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

# Subidas

> Sube archivos con put(): rutas de archivo, Blob/File o bytes, subidas multipart automáticas por encima de 90 MiB y tokens de subida para subir directamente desde el navegador.

## `put(file, options)`

`put()` sube un archivo y devuelve el nuevo objeto.

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

### Entradas

| Entrada                          | Entorno               | Notas                                                                                                                                             |
| -------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `string` (ruta de archivo)       | **Solo Node.js**      | Se abre con `fs.openAsBlob` y se **transmite desde el disco**, nunca se carga entero en memoria. La extensión se toma del nombre base de la ruta. |
| `Blob` / `File`                  | Node.js y navegadores | Un `File` aporta su `name` (y su extensión).                                                                                                      |
| `Uint8Array` (incluido `Buffer`) | Node.js y navegadores | Pasa `filename` para definir la extensión.                                                                                                        |
| `ArrayBuffer`                    | Node.js y navegadores | Pasa `filename` para definir la extensión.                                                                                                        |

La extensión del objeto se toma de `filename` y, si no, del nombre base de la ruta o del nombre del `File`. Los bytes y un `Blob` simple no tienen nombre, así que **pasa `filename`** (por ejemplo `"data.json"`) al subirlos.

<Note>
  En Node.js, una ruta que no se puede abrir lanza un `Error` simple (`Cannot open file: <path>`, con el error original en `cause`). En un navegador, pasar una ruta falla antes, con el error de importar `node:fs`. Usa en su lugar un `File` de un `<input type="file">`.
</Note>

### Opciones

| Opción            | Tipo                         | Descripción                                                                                                                                                                        |
| ----------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`            | `string`                     | Nombre del objeto **sin extensión**, que cumpla `^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$`, sin `..` y sin terminar en `-ex<digits>`. Obligatorio salvo que un token de subida lo fije. |
| `prefix`          | `string`                     | Ruta a modo de carpeta: hasta 8 segmentos de `^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$`, 256 caracteres.                                                                                 |
| `private`         | `boolean`                    | Por defecto `false`. Los objetos privados siempre reciben un hash de seguridad y tienen `url: null`.                                                                               |
| `security_hash`   | `boolean`                    | Añade `_<hash>` al nombre.                                                                                                                                                         |
| `expire`          | `string`                     | `"30"` (días), `"30d"` o `"168h"`; de 7 a 1825 días (Enterprise hasta 1 hora como mínimo). La expiración pasa a formar parte del id.                                               |
| `overwrite`       | `boolean`                    | `false` falla con `OBJECT_ALREADY_EXISTS` cuando el nombre ya está en uso. **Solo subidas simples.**                                                                               |
| `disposition`     | `"inline"` \| `"attachment"` | `Content-Disposition` del objeto.                                                                                                                                                  |
| `auto_download`   | `boolean`                    | Fuerza una descarga (`application/octet-stream`).                                                                                                                                  |
| `cache_control`   | `string`                     | `immutable`, `max-age=60..31536000` o `no-cache` (Enterprise).                                                                                                                     |
| `metadata`        | `Record<string, string>`     | Pro y Enterprise. Claves `^[a-z0-9-]{1,64}$` (nunca `sq-*`), hasta 5 claves y 512 bytes.                                                                                           |
| `checksum_sha256` | `string`                     | 64 caracteres hexadecimales en minúsculas. Si no coincide, falla con `CHECKSUM_MISMATCH` y no se guarda nada. **Solo subidas simples.**                                            |
| `filename`        | `string`                     | Nombre de archivo cuya extensión pasa a ser la extensión del objeto. Por defecto, el nombre del `File` o el nombre base de la ruta.                                                |
| `mime_type`       | `string`                     | Solo se usa para elegir la extensión cuando `filename` no tiene ninguna. El servidor deduce el `Content-Type`.                                                                     |

Consulta [Object Post](/es/blob-reference/endpoint/post) para ver todas las reglas del servidor.

### Resultado

| Campo                                  | Tipo             | Descripción                                                                                                      |
| -------------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
| `id`                                   | `string`         | Id opaco del objeto. [Guárdalo tal cual](/es/sdks/blob/client#ids-de-objeto).                                    |
| `private`                              | `boolean`        | Si el objeto es privado.                                                                                         |
| `url`                                  | `string \| null` | URL pública, o `null` para un objeto privado (usa [`downloadUrl()`](/es/sdks/blob/objects#enlaces-de-descarga)). |
| `expires_at`                           | `string`         | Cuándo caduca el objeto, si tiene expiración.                                                                    |
| `size`                                 | `number`         | Tamaño en bytes.                                                                                                 |
| `name`, `prefix`, `sha256`, `replaced` |                  | Solo subidas simples.                                                                                            |
| `parts`                                | `number`         | Solo subidas multipart: número de partes enviadas.                                                               |

## Subidas simples y multipart

`put()` elige el flujo de subida según el tamaño del archivo:

| Tamaño del archivo                            | Flujo                            | Endpoint                                                 |
| --------------------------------------------- | -------------------------------- | -------------------------------------------------------- |
| Hasta **90 MiB** (94.371.840 bytes) inclusive | Subida simple, una sola petición | [Object Post](/es/blob-reference/endpoint/post)          |
| Más de 90 MiB, hasta **10 GiB**               | Subida multipart (por partes)    | [Chunked Init](/es/blob-reference/endpoint/chunked-init) |

Todo archivo debe tener **al menos 512 bytes**; los archivos más pequeños fallan con `FILE_TOO_SMALL`. El `max_size` de una regla o de un token de subida, o tu cuota de almacenamiento, pueden reducir el límite de 10 GiB.

### Cómo se ejecuta una subida multipart

1. El SDK inicia la subida y el servidor responde con sus límites de partes (`max_size`, `max_parts`).
2. El archivo se divide en partes de `min(max_size, max(16 MiB, ceil(size / max_parts)))` bytes. Una parte suele tener 16 MiB o más, pero es más pequeña cuando el `max_size` del servidor es menor.
3. Las partes se envían **de 6 en 6**, el límite del servidor para partes en curso. Una parte fallida se [reintenta](/es/sdks/blob/errors#política-de-reintentos) dentro de `maxRetries`.
4. Cuando han llegado todas las partes, el SDK completa la subida.

Si una parte falla definitivamente, o falla la finalización, el SDK **espera a las partes que aún están en curso** y después **aborta** la subida, para que ninguna parte llegue después del aborto. Se lanza el error original. **No hay reanudación**: vuelve a llamar a `put()`.

<Warning>
  Una subida multipart **no comprueba `overwrite: false` ni `checksum_sha256`**. Siempre reemplaza un objeto existente con el mismo nombre.
</Warning>

<Note>
  Una cuenta puede tener como máximo **32 subidas multipart abiertas** (compartidas con el gateway S3); una más falla con `TOO_MANY_OPEN_UPLOADS`. Como las partes van de 6 en 6 por cuenta, ejecuta **una subida grande cada vez**.
</Note>

## Subir desde el navegador

Nunca envíes la clave de API a un navegador. En su lugar, tu servidor genera un **token de subida** de corta duración y el navegador sube con él.

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

Un cliente creado con un token **solo puede llamar a `put()`**, incluidas las subidas multipart. Cualquier otro método falla con `403 UPLOAD_TOKEN_NOT_ALLOWED`.

### `uploadTokens.create(options)`

El token fija todas las opciones con las que se generó.

| Opción               | Tipo                     | Descripción                                                                                      |
| -------------------- | ------------------------ | ------------------------------------------------------------------------------------------------ |
| `name`               | `string`                 | Fija el nombre del objeto. Sin él, siempre se aplica el hash de seguridad.                       |
| `prefix`             | `string`                 | Fija el prefijo.                                                                                 |
| `private`            | `boolean`                | Fija la visibilidad.                                                                             |
| `security_hash`      | `boolean`                | Añade `_<hash>` al nombre.                                                                       |
| `expire`             | `string`                 | Expiración del objeto, como en `put()`.                                                          |
| `max_size`           | `number`                 | Tamaño máximo del archivo en bytes.                                                              |
| `allowed_extensions` | `string[]`               | De 1 a 20 extensiones.                                                                           |
| `metadata`           | `Record<string, string>` | Metadatos aplicados al objeto subido.                                                            |
| `expires_in`         | `number`                 | Duración del token en segundos, de 60 a 3600 (por defecto 900).                                  |
| `max_uses`           | `number`                 | Subidas permitidas, de 1 a 100 (por defecto 1). Después, el token falla con `UPLOAD_TOKEN_USED`. |

Devuelve `{ token, expires_at, max_uses }`. Consulta [Upload Tokens](/es/blob-reference/endpoint/upload-tokens) para ver las reglas del servidor.

<Note>
  `uploadTokens.create()` es una escritura y tiene **un único intento**: nunca se reintenta.
</Note>
