> ## 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 SDK: manage objects and links

> List, inspect, update, delete, copy and move Blob Storage objects with the @squarecloud/blob SDK, and get permanent or temporary download links.

Examples use the `blob` client from [Creating the client](/en/sdks/blob/client#creating-the-client).

<Note>
  Object ids are opaque (`pub/...`, `prv/...`). Store them as returned, never build or parse them, and replace your stored id whenever [`update()`](#updating-objects) returns a new one. See [Object ids](/en/sdks/blob/client#object-ids).
</Note>

## Listing

`list()` is an **async generator** that follows the cursor through every page. Order is not guaranteed.

```typescript theme={"system"}
for await (const object of blob.list({ prefix: "avatars/" })) {
    console.log(object.id, object.size, object.url);
}
```

`listPage()` fetches **one page**. Use it for manual pagination or to get `folders`:

```typescript theme={"system"}
const { objects, folders, continuationToken } = await blob.listPage({
    prefix: "avatars/",
    delimiter: "/",
});

// next page
if (continuationToken) {
    const next = await blob.listPage({ prefix: "avatars/", delimiter: "/", cursor: continuationToken });
}
```

| Option | Type | Description |
| - | - | - |
| `prefix` | `string` | Only objects under this prefix. |
| `delimiter` | `"/"` | Groups by folder: the page also returns `folders`. |
| `private` | `boolean` | Only private (`true`) or public (`false`) objects. |
| `limit` | `number` | Objects per page, 1 to 1000 (default 1000). |
| `cursor` | `string` | `listPage()` only: the previous page's `continuationToken`. |

A page has `objects`, `folders` (only with `delimiter`) and `continuationToken` (**absent on the last page**). Each listed object has `id`, `size`, `created_at`, `expires_at`, `private`, `url` and `etag`. See [Object List](/en/blob-reference/endpoint/list).

## Object details

```typescript theme={"system"}
const info = await blob.info(id);
```

Returns `id`, `size`, `content_type`, `etag`, `created_at`, `expires_at`, `private`, `url`, `cache_control`, `content_disposition`, `original_name`, `metadata` and `legacy`. See [Object Info](/en/blob-reference/endpoint/info).

<Note>
  `created_at` is the storage's last-modified time: an update that copies the object (visibility, expiration, headers) resets it.
</Note>

## Download links

```typescript theme={"system"}
const { url, expires_at } = await blob.downloadUrl(id, { expires: 3600 });
```

* A **public** object gets its **permanent CDN URL**, with `expires_at: null`.
* A **private** object, or any call with `disposition` or `filename`, gets a **temporary link** that lives `expires` seconds (up to 24 hours).

<Warning>
  A temporary link **cannot be revoked**. For revocable, password-protected or download-capped links, use a [share](/en/sdks/blob/sharing).
</Warning>

| Option | Type | Description |
| - | - | - |
| `expires` | `number` | Link lifetime in seconds, 60 to 86400 (default 3600). |
| `disposition` | `"inline"` \| `"attachment"` | Overrides `Content-Disposition` for this link. |
| `filename` | `string` | File name the browser saves the download as. |

The result has `url`, `expires_at`, `private`, `size` and `content_type`. See [Object Download](/en/blob-reference/endpoint/download).

## Updating objects

`update()` changes the visibility, expiration, cache, disposition or metadata of **one object or up to 50**. It **always returns an array**, one result per object, and each result reports its own success in `ok`.

```typescript theme={"system"}
const [result] = await blob.update(id, { private: true, expire: null });

if (result.ok) {
    id = result.id; // the id changed: store the new one
} else {
    console.error(result.code);
}
```

| Change | Type | Description |
| - | - | - |
| `private` | `boolean` | Makes the object private or public. **Changes the id.** |
| `expire` | `string \| null` | New expiration; `null` removes it. **Changes the id.** |
| `cache_control` | `string \| null` | `null` removes it. |
| `disposition` | `"inline"` \| `"attachment"` \| `null` | `null` removes it. |
| `metadata` | `Record<string, string \| null> \| null` | `{ key: null }` removes one key; `null` removes all. |

A successful result (`ok: true`) has `object` (the id you sent), `changed`, `id` (**the id after the change**), `private`, `url`, `expires_at` and `size`. A failed result (`ok: false`) has `object` and `code`. A batch does not throw for per-object failures. See [Object Update](/en/blob-reference/endpoint/update).

## Deleting

Deletion is **immediate and permanent**: there is no trash.

```typescript theme={"system"}
// Single id: resolves to nothing, throws OBJECT_NOT_FOUND when missing
await blob.delete(id);

// Batch, up to 100 ids
const { deleted, not_found, failed } = await blob.delete([id1, id2]);
```

| Call | Returns | On a missing object |
| - | - | - |
| `delete(id)` | `void` | Throws `SquareCloudBlobError` (`OBJECT_NOT_FOUND`). |
| `delete([ids])` | `{ deleted, not_found, failed }` | Reported in `not_found`. `failed` lists `{ id, code }`. |

With **a single id in an array**, the SDK still returns `{ deleted, not_found, failed }`: a missing object goes to `not_found`, and `DELETE_FAILED` or `PREFIX_NOT_ALLOWED` go to `failed` instead of throwing. Any other error (authentication, rate limit, network) still throws. See [Delete Objects](/en/blob-reference/endpoint/delete).

## Copying, moving and renaming

Both run on the server, without downloading the file.

```typescript theme={"system"}
// Copy: counts toward your storage quota
await blob.copy(id, { name: "photo_copy", prefix: "backup" });

// Move or rename: does not count toward the quota
const moved = await blob.move(id, { name: "renamed" });
id = moved.id;
```

`move(source, destination, options)` is `copy()` with `move: true`.

| Destination field | Type | Description |
| - | - | - |
| `name` | `string` | Required. Name **without extension**: the destination keeps the source's extension. |
| `prefix` | `string` | Destination prefix. |
| `private` | `boolean` | Destination visibility. |
| `security_hash` | `boolean` | Appends `_<hash>` to the name. |
| `expire` | `string \| null` | Omitted keeps the source's expiration; `null` removes it. |

| Option | Accepted by | Description |
| - | - | - |
| `overwrite` | `copy()`, `move()` | `true` replaces an existing object at the destination. |
| `move` | `copy()` | `true` removes the source once the copy succeeds (same as calling `move()`). |

The result has `id`, `private`, `url`, `expires_at`, `size`, `source`, `moved` and `replaced`. See [Object Copy](/en/blob-reference/endpoint/copy).

<Note>
  `update()`, `delete()`, `copy()` and `move()` are writes: they get a **single attempt** and are never retried. See [Retry policy](/en/sdks/blob/errors#retry-policy).
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Sharing" icon="share-nodes" href="/en/sdks/blob/sharing">
    Links that expire, count downloads or ask for a password.
  </Card>

  <Card title="Objects API reference" icon="code" href="/en/blob-reference/endpoint/list">
    The REST endpoints behind these methods.
  </Card>
</CardGroup>


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