> ## 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.

# Upload de Arquivo Grande

> Envie arquivos de até 200 MB. O cliente faz upload do corpo do arquivo diretamente para o Google Cloud Storage usando uma URL PUT assinada de curta duração, e depois registra o upload na API.

<Info>
  Use este endpoint sempre que o arquivo for maior que 32 MB. Para arquivos de até 32 MB, o endpoint single-shot [POST /files](/pt/upload-file) é mais simples e continua suportado.
</Info>

### Como funciona

O corpo do arquivo é enviado **diretamente do cliente para o Google Cloud Storage** usando uma URL PUT assinada V4 de curta duração — os bytes nunca passam pelo servidor da API, o que permite que o endpoint aceite arquivos de até 200 MB.

Um único upload são três chamadas do cliente:

1. **`POST /v2/files/sign`** — a API gera uma URL PUT assinada para o GCS válida por \~15 minutos e retorna os headers que o cliente deve repetir no PUT.
2. **`PUT`** do corpo do arquivo diretamente para a `uploadUrl` retornada. O PUT carrega **exatamente** os headers de `requiredHeaders` — nem mais, nem menos — eles estão vinculados à assinatura V4, então um header faltando, extra ou diferente faz o GCS rejeitar o PUT com `403`.
3. **`POST /v2/files/register`** — a API verifica o tamanho do objeto enviado contra o que você declarou no `/sign`, move-o server-side da área de staging temporária para o local final, faz deduplicação por hash de conteúdo, e retorna o `FileDTO` padrão (mesmo formato de [POST /files](/pt/upload-file)).

### Etapa 2 — PUT direto para o Google Cloud Storage

Envie exatamente os headers retornados em `requiredHeaders` (atualmente `Content-Type` e `x-goog-if-generation-match`):

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

O GCS retorna `200` em caso de sucesso. O header `x-goog-if-generation-match: 0` torna o PUT **create-only** — re-execuções retornam `412 Precondition Failed`.

### Etapa 3 — registrar o upload

Após o PUT ser bem-sucedido, finalize o upload. O tamanho declarado não precisa ser enviado de novo — o servidor lembra o `size` que você declarou no `/sign` (por \~16 minutos) e o compara com o objeto realmente enviado:

```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 retornado por /sign>",
    "filename": "report.pdf",
    "content_type": "application/pdf",
    "process": false
  }'
```

Retorna `201` com o `FileDTO` padrão. Se um arquivo com conteúdo idêntico já existir no workspace, a API retorna `200` com o `FileDTO` do arquivo existente em vez de criar uma duplicata. O campo opcional `process` funciona exatamente como em [POST /files](/pt/upload-file).

### Arquivos suportados

Os mesmos de [POST /files](/pt/upload-file) — Texto, Word, Planilha, PDF, Excel, PowerPoint, Imagem, Vídeo, Áudio e mais de 30 extensões de código.

### Limites

* Tamanho máximo por upload: **200 MB**
* Um arquivo por fluxo (execute as três etapas novamente para arquivos adicionais)
* Limite de armazenamento: 30 arquivos

### Erros

| Status | Significado                                                                                                                                           |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Validação do `/register` falhou (campo ausente ou `object_path` mal formado)                                                                          |
| `401`  | Token Bearer ausente ou inválido                                                                                                                      |
| `403`  | Caller não tem permissão de API para o workspace alvo — ou, no `PUT` do GCS, os headers não correspondem a `requiredHeaders`                          |
| `404`  | Sessão de upload expirada (janela de \~15 minutos) ou desconhecida, ou o objeto nunca foi enviado — recomece pelo `/sign`                             |
| `412`  | No `PUT` do GCS: o objeto já existe (a URL assinada é create-only)                                                                                    |
| `415`  | `content_type` não suportado no `/register`                                                                                                           |
| `422`  | Validação do `/sign` falhou (campo ausente ou `size` > 200 MB) — ou o objeto enviado é maior que o tamanho declarado no `/sign` (o objeto é excluído) |
| `429`  | Throttled                                                                                                                                             |

### **Cabeçalhos**

<ParamField header="x-workspace-id" type="integer" required>
  ID do workspace. **Obrigatório a partir de 01/09/2026.** Até lá, se omitido, usa o workspace selecionado do usuário (deprecated). Após a data, ausência → **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

````