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

> Copiez, déplacez ou renommez un fichier dans Blob Storage avec POST /v1/objects/copy, côté serveur et sans le télécharger.

<ParamField header="Authorization" type="string" placeholder="API Key" required>
  La clé d'API de votre compte. Vous pouvez la trouver dans les [paramètres de votre compte](https://squarecloud.app/fr/account/security).
</ParamField>

Object Copy duplique un fichier sous un nouveau nom, préfixe ou visibilité, entièrement sur le serveur : aucun octet ne transite par votre application. Avec `move: true`, la source est ensuite supprimée, ce qui permet de **renommer** ou de **déplacer** un fichier. Nécessite le scope `blob:write` et un plan payant.

* La copie conserve l'extension, le type de contenu, le cache, la disposition et les métadonnées de la source.
* Une copie compte dans votre quota de stockage ; un déplacement non.
* La destination utilise toujours le stockage actuel, donc le déplacement est aussi le moyen de faire passer un fichier hérité, stocké avant la mise à jour de septembre 2026, au nouveau format (voir [Mise à jour d'objet](/fr/blob-reference/endpoint/update#fichiers-hérités)).

<ParamField body="source" type="string" required>
  L'id du fichier à copier.
</ParamField>

<ParamField body="destination" type="object" required>
  L'emplacement de la copie.

  <Expandable title="propriétés">
    <ParamField body="name" type="string" required>
      Le nouveau nom, sans extension. Même motif que dans [Object Post](/fr/blob-reference/endpoint/post).
    </ParamField>

    <ParamField body="prefix" type="string">
      Le nouveau préfixe. Omettez-le pour stocker la copie à la racine.
    </ParamField>

    <ParamField body="private" type="boolean">
      La visibilité de la copie. Par défaut, celle de la source.
    </ParamField>

    <ParamField body="expire" type="string | null">
      Une nouvelle expiration comptée à partir de maintenant (`30d`, `6h`). `null` la supprime. Omettez-le pour conserver la date d'expiration de la source.
    </ParamField>

    <ParamField body="security_hash" type="boolean" default="false">
      Ajoute un suffixe aléatoire au nouveau nom. Les copies privées le reçoivent toujours.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="move" type="boolean" default="false">
  `true` supprime la source une fois la copie réussie.
</ParamField>

<ParamField body="overwrite" type="boolean" default="false">
  `true` remplace un fichier existant à la destination. Sinon, la requête répond `409 OBJECT_ALREADY_EXISTS`.
</ParamField>

### Limites de débit

<Note>10 requêtes par 10 secondes (`RATE_LIMITED`, 429).</Note>

### Réponse

<ResponseField name="status" type="string">
  "success" en cas de succès, "error" sinon.
</ResponseField>

<ResponseField name="response" type="object">
  <Expandable title="Afficher l'objet">
    <ResponseField name="id" type="string">
      L'id du nouveau fichier.
    </ResponseField>

    <ResponseField name="private" type="boolean">
      Indique si le nouveau fichier est privé.
    </ResponseField>

    <ResponseField name="url" type="string | null">
      L'URL publique du nouveau fichier, ou `null` s'il est privé.
    </ResponseField>

    <ResponseField name="expires_at" type="ISO 8601">
      Date à laquelle le nouveau fichier sera supprimé. Présent uniquement lorsqu'il expire.
    </ResponseField>

    <ResponseField name="size" type="number">
      La taille du fichier, en octets.
    </ResponseField>

    <ResponseField name="source" type="string">
      L'id de la source.
    </ResponseField>

    <ResponseField name="moved" type="boolean">
      Indique si la source a été supprimée.
    </ResponseField>

    <ResponseField name="replaced" type="boolean">
      Indique si un fichier existant à la destination a été remplacé.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash Renommer 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>

### Erreurs

| Code                                                         | HTTP | Quand                                                                 |
| ------------------------------------------------------------ | ---- | --------------------------------------------------------------------- |
| `INVALID_OBJECT`                                             | 400  | `source` est absent, mal formé ou ne vous appartient pas.             |
| `INVALID_OBJECT_NAME` / `INVALID_OBJECT_PREFIX`              | 400  | Le nom ou le préfixe de destination ne correspond pas au motif.       |
| `INVALID_DESTINATION`                                        | 400  | `private` ou `security_hash` n'est pas un booléen.                    |
| `INVALID_OBJECT_EXPIRE`                                      | 400  | `expire` n'est pas une durée comprise entre 1 heure et 1825 jours.    |
| `INVALID_OBJECT_SECURITY_HASH`                               | 400  | `security_hash: false` sur une copie privée.                          |
| `SAME_OBJECT`                                                | 400  | La destination est la source.                                         |
| `PERMISSION_DENIED`                                          | 401  | Le compte n'a pas de plan payant actif.                               |
| `UPGRADE_REQUIRED`                                           | 403  | L'expiration nécessite un plan supérieur.                             |
| `STORAGE_QUOTA_EXCEEDED`                                     | 403  | La copie dépasserait le stockage inclus.                              |
| `OBJECT_NOT_FOUND`                                           | 404  | La source n'existe pas.                                               |
| `OBJECT_ALREADY_EXISTS`                                      | 409  | Un fichier existe à la destination et `overwrite` ne vaut pas `true`. |
| `RATE_LIMITED`                                               | 429  | Plus de 10 requêtes en 10 secondes.                                   |
| `COPY_FAILED`                                                | 500  | La copie a échoué. Réessayez.                                         |
| `PRIVATE_STORAGE_UNAVAILABLE` / `PUBLIC_STORAGE_UNAVAILABLE` | 503  | Le stockage est temporairement indisponible. Réessayez.               |
