> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Subir vídeo

> Sube vídeos MP4, MOV o WebM y obtén una URL pública para las API de generación. Límite predeterminado: 50MB por archivo.

> [!NOTE]
>
> Sube material de referencia y recibe directamente una URL pública al completarse, sin consultas periódicas. La subida es gratuita, pero el saldo de la cuenta debe ser positivo. Los tres endpoints comparten una cuota por usuario: 2000 archivos en 72 horas de forma predeterminada.

> [!NOTE]
>
> El Playground de la documentación no admite subidas de archivos. Usa los ejemplos cURL, Python o JavaScript. El ejemplo JavaScript requiere un `<input type="file">` con un archivo seleccionado.

```bash cURL theme={null}
curl --request POST \
  --url https://api.apimart.ai/v1/uploads/videos \
  --header 'Authorization: Bearer <token>' \
  --form 'file=@/path/to/reference.mp4'
```

```python Python theme={null}
import requests

with open("reference.mp4", "rb") as file:
    response = requests.post(
        "https://api.apimart.ai/v1/uploads/videos",
        headers={"Authorization": "Bearer <token>"},
        files={"file": file}
    )

response.raise_for_status()
result = response.json()
print(result["url"])
```

```javascript JavaScript theme={null}
const input = document.querySelector('input[type="file"]');
const file = input?.files?.[0];
if (!file) throw new Error("Select a file first");

const formData = new FormData();
formData.append("file", file, file.name);

const response = await fetch("https://api.apimart.ai/v1/uploads/videos", {
  method: "POST",
  headers: { Authorization: "Bearer <token>" },
  body: formData
});
const result = await response.json();
if (!response.ok) {
  throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
console.log(result.url);
```

```json 200 theme={null}
{
  "url": "https://cdn.example/uploads/reference.mp4",
  "filename": "reference.mp4",
  "content_type": "video/mp4",
  "file_type": "video",
  "bytes": 235680,
  "created_at": 1793836800,
  "quota": {
    "limit": 2000,
    "used": 124,
    "remaining": 1876,
    "window_hours": 72,
    "reset_at": 1794063600
  }
}
```

```json 402 theme={null}
{
  "error": {
    "message": "insufficient balance: uploading files requires a positive account balance, please top up",
    "type": "insufficient_user_quota"
  }
}
```

```json 413 theme={null}
{
  "error": {
    "message": "video file exceeds maximum 52428800 bytes (50MB)",
    "type": "invalid_request_error"
  }
}
```

```json 429 theme={null}
{
  "error": {
    "message": "upload limit reached: each account can upload at most 2000 files per 72 hours",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded",
    "param": ""
  },
  "quota": {
    "limit": 2000,
    "used": 2000,
    "remaining": 0,
    "window_hours": 72,
    "reset_at": 1794063600
  }
}
```

## Autenticación

**Authorization** `string` *required*

Usa una APIMart API Key válida, habilitada y no caducada como `Bearer <token>`. La cuenta no debe estar suspendida y debe tener saldo positivo. Agotar la cuota propia de la Key no impide subir archivos. Consigue una Key en [Gestión de API Keys](https://apimart.ai/keys).

## Parámetros de solicitud

**file** `file` *required*

Envía un archivo con su nombre en el campo `file` de una solicitud `multipart/form-data`. No sustituyas la parte de archivo por JSON, una cadena base64 o una URL. Otros campos se ignoran; si envías varias partes `file`, solo se procesa la primera.

**Formatos admitidos:** MP4 (.mp4), MOV (.mov), WebM (.webm)

**Tamaño máximo predeterminado:** 50MB. Los límites son configurables. Se aplica la configuración activa y el límite indicado en el mensaje de error.

Con cURL `--form`, Python `files` o JavaScript `FormData`, deja que el cliente genere `Content-Type` con su boundary. No establezcas esa cabecera manualmente.

## Validación de archivos

El tipo se identifica por el contenido, no por la extensión ni el MIME declarado. El contenido debe coincidir con el endpoint. Cambiar el nombre no convierte el formato; un tipo incorrecto devuelve HTTP `400`.

Se valida la estructura del contenedor. Se rechazan cabeceras falsas y contenedores dañados. Solo se admiten los formatos siguientes; renombrar AVI, MKV u otros no los hace compatibles.

| Formato | Tipo MIME detectado |
| - | - |
| MP4 (.mp4) | `video/mp4` |
| MOV (.mov) | `video/quicktime` |
| WebM (.webm) | `video/webm` |

## Respuesta correcta

HTTP `200` devuelve los datos del archivo. `url` está en la raíz JSON, sin envoltorio `data` ni ID de tarea de generación.

**url** `string`

URL pública para el parámetro de referencia correspondiente de la API de generación. Cada modelo conserva sus límites de formato, tamaño, cantidad y duración. Una subida correcta no garantiza compatibilidad con el modelo.

**filename** `string`

Nombre original del archivo.

**content\_type** `string`

Tipo MIME detectado por el servidor a partir del contenido, no el valor declarado por el cliente.

**file\_type** `string`

Categoría del archivo. Este endpoint devuelve `video`.

**bytes** `integer`

Tamaño real en bytes.

**created\_at** `integer`

Fecha de subida como marca de tiempo Unix en segundos.

**quota** `object`

Información opcional de cuota. Los campos de usuarios con límite se enumeran abajo. La estructura puede variar si el acceso es ilimitado o las estadísticas no están disponibles.

| Campo | Descripción |
| - | - |
| `quota.limit` | Máximo de subidas correctas para este usuario en la ventana; puede diferir de 2000. |
| `quota.used` | Cantidad usada en la ventana, incluida esta subida correcta. |
| `quota.remaining` | Número de archivos que aún se pueden subir actualmente. |
| `quota.window_hours` | Duración de la ventana en horas; 72 de forma predeterminada. |
| `quota.reset_at` | Momento en que el grupo más antiguo sale de la ventana, en segundos Unix. Se liberan algunas plazas; no implica un reinicio completo de la cuota. |

## Cuota compartida y límites de solicitudes

Imágenes, vídeos y audios comparten una cuota por usuario. Varias Keys del mismo usuario no suman cuota. La ventana avanza a cada hora en punto y cuenta por defecto las subidas correctas de las últimas 71–72 horas aproximadamente. Los archivos inválidos, demasiado grandes o no guardados no consumen cuota de archivos.

Las respuestas limitadas normales incluyen `X-Upload-Quota-Limit`, `X-Upload-Quota-Remaining` y `X-Upload-Quota-Reset`, correspondientes a `limit`, `remaining` y `reset_at`. Reset usa segundos Unix.

Los usuarios sin límite reciben `quota: {"unlimited": true}` sin esas tres cabeceras. Si las estadísticas no están disponibles, una respuesta correcta puede omitir `quota`. No interpretes esa ausencia como cero o ilimitado, ni vuelvas a subir el archivo solo por ello.

Al agotar la cuota de archivos se devuelve HTTP `429`, `error.type: rate_limit_exceeded`, `quota` con `remaining: 0` y `Retry-After`. Espera los segundos indicados. Existe otro límite independiente de 1000 solicitudes por Key cada 60 segundos, identificado por `rate_limit_error`.

## Gestión de errores

Los errores aparecen en el objeto `error` de la raíz JSON. Consulta el estado HTTP, `error.type` / `error.code` y `error.message`.

| HTTP | `error.type` | Causa y acción |
| - | - | - |
| 400 | `invalid_request_error` | Falta el archivo, la solicitud no es multipart, el archivo está vacío, el tipo no coincide, el formato no se admite o el contenido está dañado. Corrige el archivo o endpoint. |
| 401 / 403 | `—` | Key no válida o deshabilitada, o cuenta suspendida. Revisa la autenticación y la cuenta. |
| 402 | `insufficient_user_quota` | Saldo no positivo o Key caducada. Añade saldo o usa una Key válida. Las subidas gratuitas también requieren estas condiciones. |
| 413 | `invalid_request_error` | El archivo supera el límite de su tipo. Comprímelo o redúcelo; consulta el límite actual en el error. |
| 429 | `rate_limit_exceeded` | Cuota compartida agotada. Lee `quota` y `Retry-After` y espera a que se liberen plazas. |
| 429 | `rate_limit_error` | Demasiadas solicitudes de la Key. Reduce la frecuencia y espacia los reintentos. |
| 503 | `server_error` | Demasiadas subidas simultáneas de vídeo/audio o almacenamiento temporalmente no disponible. Reintenta más tarde. |
| 500 | `server_error` | No se pudo guardar el archivo. Reintenta más tarde. |

## Uso de URL y conservación

72 horas es la ventana de cuota predeterminada, no una garantía de conservación. La duración depende de la política de almacenamiento. Conserva los originales y usa las URL pronto para generar; no asumas que son permanentes.

## Otros endpoints de subida

* [Subir imagen](https://docs.apimart.ai/es/api-reference/uploads/images.md)
* [Subir audio](https://docs.apimart.ai/es/api-reference/uploads/audios.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.