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

# SDK Blob: uploads e tokens de upload

> Envie arquivos com put(): caminhos, Blob/File ou bytes, upload multipart automático acima de 90 MiB e tokens para enviar direto do navegador.

Os exemplos usam o cliente `blob` de [Criando o cliente](/pt-br/sdks/blob/client#criando-o-cliente).

## `put(file, options)`

`put()` envia um arquivo e retorna o novo objeto.

```typescript theme={"system"}
const { id, url } = await blob.put("./photo.png", {
    name: "photo",
    prefix: "avatars",
});
```

### Entradas

| Entrada | Ambiente | Observações |
| - | - | - |
| `string` (caminho de arquivo) | **Apenas Node.js** | Aberto com `fs.openAsBlob` e **transmitido do disco**, nunca lido inteiro para a memória. A extensão vem do nome base do caminho. |
| `Blob` / `File` | Node.js e navegadores | Um `File` fornece seu `name` (e sua extensão). |
| `Uint8Array` (incluindo `Buffer`) | Node.js e navegadores | Passe `filename` para definir a extensão. |
| `ArrayBuffer` | Node.js e navegadores | Passe `filename` para definir a extensão. |

A extensão do objeto vem de `filename`, depois do nome base do caminho ou do nome do `File`. Bytes e um `Blob` simples não têm nome, então **passe `filename`** (por exemplo `"data.json"`) ao enviá-los.

<Note>
  No Node.js, um caminho que não pode ser aberto lança um `Error` simples (`Cannot open file: <path>`, com o erro original em `cause`). No navegador, passar um caminho falha antes, com o erro da importação de `node:fs`. Use um `File` de um `<input type="file">` em vez disso.
</Note>

### Opções

| Opção | Tipo | Descrição |
| - | - | - |
| `name` | `string` | Nome do objeto **sem extensão**, correspondendo a `^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$`, sem `..`, sem terminar em `-ex<digits>`. Obrigatório, a menos que um token de upload o fixe. |
| `prefix` | `string` | Caminho no estilo de pasta: até 8 segmentos de `^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$`, 256 caracteres. |
| `private` | `boolean` | Padrão `false`. Objetos privados sempre recebem um hash de segurança e têm `url: null`. |
| `security_hash` | `boolean` | Acrescenta `_<hash>` ao nome. |
| `expire` | `string` | `"30"` (dias), `"30d"` ou `"168h"`; de 7 a 1825 dias (Enterprise a partir de 1 hora). A expiração passa a fazer parte do id. |
| `overwrite` | `boolean` | `false` falha com `OBJECT_ALREADY_EXISTS` quando o nome já está em uso. **Apenas uploads simples.** |
| `disposition` | `"inline"` \| `"attachment"` | `Content-Disposition` do objeto. |
| `auto_download` | `boolean` | Força um download (`application/octet-stream`). |
| `cache_control` | `string` | `immutable`, `max-age=60..31536000` ou `no-cache` (Enterprise). |
| `metadata` | `Record<string, string>` | Pro e Enterprise. Chaves `^[a-z0-9-]{1,64}$` (nunca `sq-*`), até 5 chaves e 512 bytes. |
| `checksum_sha256` | `string` | 64 caracteres hexadecimais em minúsculas. Uma divergência falha com `CHECKSUM_MISMATCH` e nada é armazenado. **Apenas uploads simples.** |
| `filename` | `string` | Nome de arquivo cuja extensão se torna a extensão do objeto. Por padrão, o nome do `File` ou o nome base do caminho. |
| `mime_type` | `string` | Usado apenas para escolher a extensão quando `filename` não tem uma. O servidor deriva o `Content-Type`. |

Veja [Envio de objeto](/pt-br/blob-reference/endpoint/post) para todas as regras do lado do servidor.

### Resultado

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | `string` | Id opaco do objeto. [Armazene-o como está](/pt-br/sdks/blob/client#ids-de-objetos). |
| `private` | `boolean` | Se o objeto é privado. |
| `url` | `string \| null` | URL pública, ou `null` para um objeto privado (use [`downloadUrl()`](/pt-br/sdks/blob/objects#links-de-download)). |
| `expires_at` | `string` | Quando o objeto expira, se tiver uma expiração. |
| `size` | `number` | Tamanho em bytes. |
| `name`, `prefix`, `sha256`, `replaced` | | Apenas uploads simples. |
| `parts` | `number` | Apenas uploads multipart: número de partes enviadas. |

## Uploads simples e multipart

`put()` escolhe o fluxo de upload a partir do tamanho do arquivo:

| Tamanho do arquivo | Fluxo | Endpoint |
| - | - | - |
| Até **90 MiB** (94.371.840 bytes), inclusive | Upload simples, uma requisição | [Envio de objeto](/pt-br/blob-reference/endpoint/post) |
| Acima de 90 MiB, até **10 GiB** | Upload multipart (em partes) | [Início de upload em partes](/pt-br/blob-reference/endpoint/chunked-init) |

Todo arquivo precisa ter **pelo menos 512 bytes**; arquivos menores falham com `FILE_TOO_SMALL`. Um `max_size` de uma regra ou de um token de upload, ou sua cota de armazenamento, pode reduzir o teto de 10 GiB.

### Como um upload multipart funciona

1. O SDK inicia o upload, e o servidor responde com seus limites de partes (`max_size`, `max_parts`).
2. O arquivo é dividido em partes de `min(max_size, max(16 MiB, ceil(size / max_parts)))` bytes. Uma parte geralmente tem 16 MiB ou mais, mas é menor quando o `max_size` do servidor é menor.
3. As partes são enviadas **6 por vez**, o limite do servidor para partes em andamento. Uma parte que falha é [tentada novamente](/pt-br/sdks/blob/errors#política-de-novas-tentativas) dentro de `maxRetries`.
4. Quando todas as partes chegam, o SDK conclui o upload.

Se uma parte falhar definitivamente, ou se a conclusão falhar, o SDK **aguarda as partes ainda em andamento** e então **cancela** o upload, para que nenhuma parte chegue depois do cancelamento. O erro original é lançado. **Não há retomada**: chame `put()` novamente.

<Warning>
  Um upload multipart **não verifica `overwrite: false` nem `checksum_sha256`**. Ele sempre substitui um objeto existente com o mesmo nome.
</Warning>

<Note>
  Uma conta pode ter no máximo **32 uploads multipart abertos** (compartilhados com o gateway S3); mais um falha com `TOO_MANY_OPEN_UPLOADS`. Como as partes vão 6 por vez por conta, execute **um upload grande por vez**.
</Note>

## Upload a partir do navegador

Nunca envie a chave de API para um navegador. Em vez disso, seu servidor gera um **token de upload** de curta duração e o navegador faz o upload com ele.

<Tabs>
  <Tab title="Servidor">
    ```typescript theme={"system"}
    import { SquareCloudBlob } from "@squarecloud/blob";

    const blob = new SquareCloudBlob(process.env.SQUARECLOUD_API_KEY);

    // e.g. inside your API route
    const { token } = await blob.uploadTokens.create({
        prefix: "avatars/",
        security_hash: true,
        max_size: 5 * 1024 * 1024,
        allowed_extensions: ["png", "jpg"],
    });
    // send only `token` to the browser
    ```
  </Tab>

  <Tab title="Navegador">
    ```typescript theme={"system"}
    import { SquareCloudBlob } from "@squarecloud/blob";

    const upload = new SquareCloudBlob(token);
    const { url } = await upload.put(input.files[0], { name: "avatar" });
    ```
  </Tab>
</Tabs>

Um cliente criado com um token **só pode chamar `put()`**, incluindo uploads multipart. Qualquer outro método falha com `403 UPLOAD_TOKEN_NOT_ALLOWED`.

### `uploadTokens.create(options)`

O token fixa todas as opções com que foi gerado.

| Opção | Tipo | Descrição |
| - | - | - |
| `name` | `string` | Fixa o nome do objeto. Sem ele, o hash de segurança é sempre aplicado. |
| `prefix` | `string` | Fixa o prefixo. |
| `private` | `boolean` | Fixa a visibilidade. |
| `security_hash` | `boolean` | Acrescenta `_<hash>` ao nome. |
| `expire` | `string` | Expiração do objeto, como em `put()`. |
| `max_size` | `number` | Tamanho máximo do arquivo em bytes. |
| `allowed_extensions` | `string[]` | De 1 a 20 extensões. |
| `metadata` | `Record<string, string>` | Metadados aplicados ao objeto enviado. |
| `expires_in` | `number` | Duração do token em segundos, de 60 a 3600 (padrão 900). |
| `max_uses` | `number` | Uploads permitidos, de 1 a 100 (padrão 1). Depois disso, o token falha com `UPLOAD_TOKEN_USED`. |

Retorna `{ token, expires_at, max_uses }`. Veja [Tokens de upload](/pt-br/blob-reference/endpoint/upload-tokens) para as regras do lado do servidor.

<Note>
  `uploadTokens.create()` é uma escrita e tem uma **única tentativa**: nunca é repetido.
</Note>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Objetos" icon="folder-open" href="/pt-br/sdks/blob/objects">
    Liste, atualize, copie, mova e exclua objetos.
  </Card>

  <Card title="Referência da API de upload" icon="code" href="/pt-br/blob-reference/endpoint/post">
    Os endpoints REST por trás do put().
  </Card>
</CardGroup>


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