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

> Change the visibility, expiry, cache, disposition or metadata of up to 50 files per request with PATCH /v1/objects, without uploading them again.

<ParamField header="Authorization" type="string" placeholder="API Key" required>
  The API key for your account. You can find this in your [account settings](https://squarecloud.app/en/account/security).
</ParamField>

Object Update changes files already stored, without uploading them again: make them private or public, set or remove an expiry, and change the cache, disposition or metadata. It accepts one file or up to **50 per request**, all getting the same changes. Requires the `blob:write` scope.

Changes are applied in the order of the fields below, each on the result of the previous one. Once the body is valid the route always answers `200`, with one result per file.

<Warning>
  **Changing `private` or `expire` changes the file's id** (and its URL, for public files). Store the new `id` from each result. Share links and temporary links to the old id stop working. The other fields keep the id.
</Warning>

<ParamField body="object" type="string">
  The id of one file. Send `object` or `objects`.
</ParamField>

<ParamField body="objects" type="string[]">
  Up to 50 ids.
</ParamField>

<ParamField body="private" type="boolean">
  `true` makes the file private: the public copy is removed before the request answers, and the CDN drops it in about 60 seconds. `false` publishes it, which needs a paid plan. See [Links and sharing](/en/blob-reference/links-and-sharing#making-a-file-private-or-public).
</ParamField>

<ParamField body="expire" type="string | null">
  A new expiry counted from now (`30d`, `6h`, `30`), or `null` to keep the file forever. Needs a paid plan, and expiries under 7 days need Enterprise.
</ParamField>

<ParamField body="cache_control" type="string | null">
  `immutable`, `max-age=N` (60 to 31536000) or `no-cache` (Enterprise only). `null` removes the header and the CDN default applies.
</ParamField>

<ParamField body="disposition" type="string | null">
  `inline` or `attachment` (download with the original file name). `null` removes the header.
</ParamField>

<ParamField body="metadata" type="object | null">
  Keys to set or change. A key with a `null` value is removed, and `metadata: null` removes all of them. Up to 5 keys and 512 bytes after the change. Setting keys needs Pro or Enterprise; removing is always allowed.
</ParamField>

### Legacy files

Legacy files, uploaded before the September 2026 update (ids without `pub/` or `prv/`), can be made private and can get a new expiry: both move them to the new storage, with a new id. Their headers (`cache_control`, `disposition`, `metadata`) can't change in place and answer `OBJECT_IS_LEGACY`: move the file first with [Object Copy](/en/blob-reference/endpoint/copy) (`move: true`), then update it.

### Rate limits

<Note>50 files per 10 seconds, counted per file: one full batch of 50 uses the whole window (`RATE_LIMITED`, 429).</Note>

### Response

<ResponseField name="status" type="string">
  "success" if successful, "error" if not.
</ResponseField>

<ResponseField name="response" type="object">
  <Expandable title="Toggle object">
    <ResponseField name="results" type="array">
      One entry per file, in the order sent.

      <Expandable title="Toggle object">
        <ResponseField name="object" type="string">
          The id as sent in the request.
        </ResponseField>

        <ResponseField name="ok" type="boolean">
          Whether every change was applied to this file.
        </ResponseField>

        <ResponseField name="code" type="string">
          Only when `ok` is `false`: why this file failed.
        </ResponseField>

        <ResponseField name="changed" type="boolean">
          Whether the id changed.
        </ResponseField>

        <ResponseField name="id" type="string">
          The current id of the file. Store it.
        </ResponseField>

        <ResponseField name="private" type="boolean">
          Whether the file is private.
        </ResponseField>

        <ResponseField name="url" type="string | null">
          The public URL, or `null` for private files.
        </ResponseField>

        <ResponseField name="size" type="number">
          The size of the file, in bytes.
        </ResponseField>

        <ResponseField name="expires_at" type="ISO 8601 | null">
          When the file will be deleted, or `null` when it doesn't expire.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash Make private theme={null}
  curl --request PATCH \
    --url 'https://blob.squarecloud.app/v1/objects' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "object": "pub/3155597145698959364/reports/q3_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.pdf",
      "private": true
    }'
  ```

  ```bash Change headers theme={null}
  curl --request PATCH \
    --url 'https://blob.squarecloud.app/v1/objects' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "objects": [
        "pub/3155597145698959364/images/logo_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.png",
        "pub/3155597145698959364/images/banner_mugws5c0-1b4f0e9851971998e732078544c96b36.png"
      ],
      "cache_control": "max-age=3600",
      "metadata": { "campaign": "spring", "draft": null }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Make private theme={null}
  {
    "status": "success",
    "response": {
      "results": [
        {
          "object": "pub/3155597145698959364/reports/q3_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.pdf",
          "ok": true,
          "changed": true,
          "id": "prv/3155597145698959364/reports/q3_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.pdf",
          "private": true,
          "url": null,
          "size": 88412,
          "expires_at": null
        }
      ]
    }
  }
  ```

  ```json With a failure theme={null}
  {
    "status": "success",
    "response": {
      "results": [
        {
          "object": "pub/3155597145698959364/images/logo_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.png",
          "ok": true,
          "changed": false,
          "id": "pub/3155597145698959364/images/logo_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.png",
          "private": false,
          "url": "https://blob.squarecloud.dev/pub/3155597145698959364/images/logo_mugws5c0-9f86d081884c7d659a2feaa0c55ad015.png",
          "size": 416230,
          "expires_at": null
        },
        {
          "object": "pub/3155597145698959364/images/banner_mugws5c0-1b4f0e9851971998e732078544c96b36.png",
          "ok": false,
          "code": "OBJECT_NOT_FOUND"
        }
      ]
    }
  }
  ```
</ResponseExample>

### Errors

Errors of the whole request:

| Code                                                                                                                                           | HTTP | When                                                                        |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- |
| `INVALID_BODY` / `INVALID_OBJECT`                                                                                                              | 400  | The body is not a JSON object, or an id is missing, malformed or not yours. |
| `TOO_MANY_OBJECTS`                                                                                                                             | 400  | More than 50 ids.                                                           |
| `NOTHING_TO_UPDATE`                                                                                                                            | 400  | No field to change was sent.                                                |
| `INVALID_OBJECT_PRIVATE` / `INVALID_OBJECT_EXPIRE` / `INVALID_OBJECT_CACHE_CONTROL` / `INVALID_OBJECT_DISPOSITION` / `INVALID_OBJECT_METADATA` | 400  | A field has an invalid value.                                               |
| `UPGRADE_REQUIRED`                                                                                                                             | 403  | A value needs a higher plan. The `message` says which.                      |
| `RATE_LIMITED`                                                                                                                                 | 429  | More than 50 files in 10 seconds.                                           |

Codes of a single file, in its result:

| Code                                                         | When                                                                       |
| ------------------------------------------------------------ | -------------------------------------------------------------------------- |
| `OBJECT_NOT_FOUND`                                           | The file doesn't exist.                                                    |
| `PERMISSION_DENIED`                                          | Publishing or changing the expiry needs an active paid plan.               |
| `OBJECT_IS_LEGACY`                                           | Header change on a legacy file. Move it first.                             |
| `INVALID_OBJECT_METADATA`                                    | The file would pass 5 keys or 512 bytes of metadata.                       |
| `VISIBILITY_CHANGE_FAILED`                                   | The public copy could not be removed: the file **is still public**. Retry. |
| `PRIVATE_STORAGE_UNAVAILABLE` / `PUBLIC_STORAGE_UNAVAILABLE` | Storage is temporarily unavailable. Retry.                                 |
| `UPDATE_FAILED`                                              | The change failed. Retry.                                                  |
