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

# Subir Archivo Grande

> Sube archivos de hasta 200 MB. El cliente envía el cuerpo del archivo directamente a Google Cloud Storage con una URL PUT firmada de corta duración, y después registra la carga en la API.

<Info>
  Use este endpoint siempre que el archivo sea mayor a 32 MB. Para archivos de hasta 32 MB, el endpoint single-shot [POST /files](/es/upload-file) es más simple y sigue siendo soportado.
</Info>

### Cómo funciona

El cuerpo del archivo se sube **directamente desde el cliente a Google Cloud Storage** usando una URL PUT firmada V4 de corta duración — los bytes nunca pasan por el servidor de la API, lo que permite que el endpoint acepte archivos de hasta 200 MB.

Una sola carga son tres llamadas desde el cliente:

1. **`POST /v2/files/sign`** — la API genera una URL PUT firmada para GCS válida por \~15 minutos y devuelve los headers que el cliente debe repetir en el PUT.
2. **`PUT`** del cuerpo del archivo directamente a la `uploadUrl` devuelta. El PUT lleva **exactamente** los headers de `requiredHeaders` — ni más, ni menos — están vinculados a la firma V4, así que un header faltante, extra o distinto hace que GCS rechace el PUT con `403`.
3. **`POST /v2/files/register`** — la API verifica el tamaño del objeto subido contra lo que declaraste en `/sign`, lo mueve server-side del área de staging temporal a su ubicación final, deduplica por hash de contenido, y devuelve el `FileDTO` estándar (mismo formato que [POST /files](/es/upload-file)).

### Paso 2 — PUT directo a Google Cloud Storage

Envíe exactamente los headers devueltos en `requiredHeaders` (actualmente `Content-Type` y `x-goog-if-generation-match`):

```http cURL theme={null}
curl --request PUT \
  --url 'PEGUE_uploadUrl_AQUI' \
  --header 'Content-Type: application/pdf' \
  --header 'x-goog-if-generation-match: 0' \
  --upload-file './report.pdf'
```

GCS devuelve `200` en caso de éxito. El header `x-goog-if-generation-match: 0` hace el PUT **create-only** — reintentos devuelven `412 Precondition Failed`.

### Paso 3 — registrar la carga

Después de que el PUT termine con éxito, finalice la carga. El tamaño declarado no necesita enviarse de nuevo — el servidor recuerda el `size` que declaraste en `/sign` (por \~16 minutos) y lo compara con el objeto realmente subido:

```http cURL theme={null}
curl --request POST \
  --url 'https://api.tess.im/v2/files/register' \
  --header 'Authorization: Bearer <TOKEN>' \
  --header 'x-workspace-id: YOUR_WORKSPACE_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "object_path": "<objectPath devuelto por /sign>",
    "filename": "report.pdf",
    "content_type": "application/pdf",
    "process": false
  }'
```

Devuelve `201` con el `FileDTO` estándar. Si un archivo con contenido idéntico ya existe en el workspace, la API devuelve `200` con el `FileDTO` del archivo existente en lugar de crear un duplicado. El campo opcional `process` funciona exactamente igual que en [POST /files](/es/upload-file).

### Archivos soportados

Los mismos que [POST /files](/es/upload-file) — Texto, Word, Hoja de cálculo, PDF, Excel, PowerPoint, Imagen, Video, Audio y más de 30 extensiones de código.

### Límites

* Tamaño máximo por carga: **200 MB**
* Un archivo por flujo (ejecute las tres etapas otra vez para archivos adicionales)
* Límite de almacenamiento: 30 archivos

### Errores

| Status | Significado                                                                                                                                            |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400`  | Validación de `/register` falló (campo faltante u `object_path` mal formado)                                                                           |
| `401`  | Token Bearer ausente o inválido                                                                                                                        |
| `403`  | El caller no tiene permiso de API para el workspace destino — o, en el `PUT` a GCS, los headers no coinciden con `requiredHeaders`                     |
| `404`  | Sesión de carga expirada (ventana de \~15 minutos) o desconocida, o el objeto nunca se subió — comience de nuevo en `/sign`                            |
| `412`  | En el `PUT` a GCS: el objeto ya existe (la URL firmada es create-only)                                                                                 |
| `415`  | `content_type` no soportado en `/register`                                                                                                             |
| `422`  | Validación de `/sign` falló (campo faltante o `size` > 200 MB) — o el objeto subido es mayor que el tamaño declarado en `/sign` (el objeto se elimina) |
| `429`  | Throttled                                                                                                                                              |

### **Encabezados**

<ParamField header="x-workspace-id" type="integer" required>
  ID del workspace. **Obligatorio a partir del 01/09/2026.** Hasta entonces, si se omite, se usa el workspace seleccionado del usuario (deprecated). Después de la fecha, ausencia → **422**.
</ParamField>


## OpenAPI

````yaml api-reference/upload-file-v2-sign.openapi.json POST /v2/files/sign
openapi: 3.1.0
info:
  title: Tess API - Upload Large File
  version: 1.0.0
servers:
  - url: https://api.tess.im
security: []
paths:
  /v2/files/sign:
    post:
      summary: 'Upload Large File - Step 1: Sign'
      description: >-
        Step 1 of the Upload Large File flow. Mints a short-lived (~15 min)
        Google Cloud Storage V4-signed PUT URL that the client uses to upload
        the file body directly to GCS. Returns the upload URL, the object path,
        and the exact headers the client must echo on the subsequent PUT (these
        headers are bound into the V4 signature - missing, extra, or different
        headers cause GCS to reject the PUT with 403). After the PUT succeeds,
        call POST /v2/files/register to finalize the upload and receive the
        standard FileDTO.
      parameters:
        - name: x-workspace-id
          in: header
          required: true
          description: >-
            Workspace ID. Required as of 2026-09-01. Until then, if omitted, the
            user's selected workspace is used (deprecated). After the cutoff, a
            missing header returns 422.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filename
                - content_type
                - size
              properties:
                filename:
                  type: string
                  description: >-
                    Original filename including extension (e.g. report.pdf).
                    Used to derive the stored extension.
                content_type:
                  type: string
                  description: >-
                    MIME type of the file. Bound into the signed URL - the
                    client MUST PUT with exactly this Content-Type header.
                size:
                  type: integer
                  description: >-
                    Declared file size in bytes. The server remembers this value
                    and /register rejects the upload if the actual uploaded
                    object is larger than declared. Hard maximum: 200 MB
                    (209715200 bytes).
      responses:
        '200':
          description: Signed PUT URL minted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  uploadUrl:
                    type: string
                    format: uri
                    description: >-
                      Pre-signed Google Cloud Storage PUT URL. Valid for ~15
                      minutes.
                  objectPath:
                    type: string
                    description: >-
                      GCS object path the file will land at. Pass this back to
                      POST /v2/files/register.
                  requiredHeaders:
                    type: object
                    additionalProperties:
                      type: string
                    description: >-
                      Headers the client MUST send on the PUT - bound into the
                      V4 signature. Contains exactly Content-Type (the value you
                      declared) and x-goog-if-generation-match: 0 (create-only).
                      Send these headers verbatim and do not add others.
                  finalUrl:
                    type: string
                    format: uri
                    description: >-
                      Short-lived signed download URL (~3 hours) for the
                      uploaded object. For a durable reference, use the url
                      field of the FileDTO returned by POST /v2/files/register.
        '401':
          description: Missing or invalid Bearer token.
        '403':
          description: Caller does not have API permission for the target workspace.
        '422':
          description: >-
            Validation failed (missing field, or size > 200 MB / 209715200
            bytes).
        '429':
          description: Throttled.
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````