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

# Blob Object Copy

> Copia, mueve o renombra un archivo dentro de Blob Storage con POST /v1/objects/copy, en el servidor y sin descargarlo.

<ParamField header="Authorization" type="string" placeholder="API Key" required>
  La clave de API de tu cuenta. Puedes encontrarla en la [configuración de tu cuenta](https://squarecloud.app/es/account/security).
</ParamField>

Object Copy duplica un archivo con un nuevo nombre, prefijo o visibilidad, completamente en el servidor: ningún byte pasa por tu aplicación. Con `move: true` el origen se elimina después, y así es como **renombras** o **mueves** un archivo. Requiere el scope `blob:write` y un plan de pago.

* La copia conserva la extensión, el tipo de contenido, la caché, la disposition y los metadatos del origen.
* Una copia cuenta para tu cuota de almacenamiento; un movimiento no.
* El destino siempre usa el almacenamiento actual, así que mover es también la forma de llevar un archivo heredado, almacenado antes de la actualización de septiembre de 2026, al nuevo formato (consulta [Object Update](/es/blob-reference/endpoint/update#archivos-heredados)).

<ParamField body="source" type="string" required>
  El id del archivo a copiar.
</ParamField>

<ParamField body="destination" type="object" required>
  Dónde va la copia.

  <Expandable title="propiedades">
    <ParamField body="name" type="string" required>
      El nuevo nombre, sin extensión. Mismo patrón que en [Object Post](/es/blob-reference/endpoint/post).
    </ParamField>

    <ParamField body="prefix" type="string">
      El nuevo prefijo. Omítelo para guardar la copia en la raíz.
    </ParamField>

    <ParamField body="private" type="boolean">
      La visibilidad de la copia. Por defecto, la del origen.
    </ParamField>

    <ParamField body="expire" type="string | null">
      Una nueva expiración contada desde ahora (`30d`, `6h`). `null` la elimina. Omítela para conservar la fecha de expiración del origen.
    </ParamField>

    <ParamField body="security_hash" type="boolean" default="false">
      Añade un sufijo aleatorio al nuevo nombre. Las copias privadas siempre lo reciben.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="move" type="boolean" default="false">
  `true` elimina el origen cuando la copia tiene éxito.
</ParamField>

<ParamField body="overwrite" type="boolean" default="false">
  `true` reemplaza un archivo existente en el destino. Si no, la solicitud responde `409 OBJECT_ALREADY_EXISTS`.
</ParamField>

### Límites de tasa

<Note>10 solicitudes cada 10 segundos (`RATE_LIMITED`, 429).</Note>

### Respuesta

<ResponseField name="status" type="string">
  "success" si tuvo éxito, "error" si no.
</ResponseField>

<ResponseField name="response" type="object">
  <Expandable title="Alternar objeto">
    <ResponseField name="id" type="string">
      El id del nuevo archivo.
    </ResponseField>

    <ResponseField name="private" type="boolean">
      Si el nuevo archivo es privado.
    </ResponseField>

    <ResponseField name="url" type="string | null">
      La URL pública del nuevo archivo, o `null` cuando es privado.
    </ResponseField>

    <ResponseField name="expires_at" type="ISO 8601">
      Cuándo se eliminará el nuevo archivo. Solo aparece cuando expira.
    </ResponseField>

    <ResponseField name="size" type="number">
      El tamaño del archivo, en bytes.
    </ResponseField>

    <ResponseField name="source" type="string">
      El id del origen.
    </ResponseField>

    <ResponseField name="moved" type="boolean">
      Si se eliminó el origen.
    </ResponseField>

    <ResponseField name="replaced" type="boolean">
      Si se reemplazó un archivo existente en el destino.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash Renombrar theme={null}
  curl --request POST \
    --url 'https://blob.squarecloud.app/v1/objects/copy' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "source": "pub/3155597145698959364/uploads/IMG_2041.png",
      "destination": { "name": "cover", "prefix": "posts/launch" },
      "move": true
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://blob.squarecloud.app/v1/objects/copy', {
    method: 'POST',
    headers: {
      Authorization: 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      source: 'pub/3155597145698959364/uploads/IMG_2041.png',
      destination: { name: 'cover', prefix: 'posts/launch' },
      move: true,
    }),
  });
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "status": "success",
    "response": {
      "id": "pub/3155597145698959364/posts/launch/cover.png",
      "private": false,
      "url": "https://blob.squarecloud.dev/pub/3155597145698959364/posts/launch/cover.png",
      "size": 416230,
      "source": "pub/3155597145698959364/uploads/IMG_2041.png",
      "moved": true,
      "replaced": false
    }
  }
  ```
</ResponseExample>

### Errores

| Código                                                       | HTTP | Cuándo                                                         |
| ------------------------------------------------------------ | ---- | -------------------------------------------------------------- |
| `INVALID_OBJECT`                                             | 400  | `source` falta, está mal formado o no es tuyo.                 |
| `INVALID_OBJECT_NAME` / `INVALID_OBJECT_PREFIX`              | 400  | El nombre o el prefijo de destino no cumplen el patrón.        |
| `INVALID_DESTINATION`                                        | 400  | `private` o `security_hash` no es un booleano.                 |
| `INVALID_OBJECT_EXPIRE`                                      | 400  | `expire` no es una duración de 1 hora a 1825 días.             |
| `INVALID_OBJECT_SECURITY_HASH`                               | 400  | `security_hash: false` en una copia privada.                   |
| `SAME_OBJECT`                                                | 400  | El destino es el origen.                                       |
| `PERMISSION_DENIED`                                          | 401  | La cuenta no tiene un plan de pago activo.                     |
| `UPGRADE_REQUIRED`                                           | 403  | La expiración requiere un plan superior.                       |
| `STORAGE_QUOTA_EXCEEDED`                                     | 403  | La copia superaría el almacenamiento incluido.                 |
| `OBJECT_NOT_FOUND`                                           | 404  | El origen no existe.                                           |
| `OBJECT_ALREADY_EXISTS`                                      | 409  | Existe un archivo en el destino y `overwrite` no es `true`.    |
| `RATE_LIMITED`                                               | 429  | Más de 10 solicitudes en 10 segundos.                          |
| `COPY_FAILED`                                                | 500  | La copia falló. Reintenta.                                     |
| `PRIVATE_STORAGE_UNAVAILABLE` / `PUBLIC_STORAGE_UNAVAILABLE` | 503  | El almacenamiento no está disponible temporalmente. Reintenta. |
