> ## 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: share links

> Create, list and revoke Blob Storage share links with @squarecloud/blob, with expiration, download limits and passwords, and compare them with downloadUrl().

A **share** is a link to one object that can **expire**, be **revoked**, cap the **number of downloads** and, on Pro and Enterprise, ask for a **password**. See [Links and sharing](/en/blob-reference/links-and-sharing) for how the links behave.

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

## Share or `downloadUrl()`?

| | [`downloadUrl()`](/en/sdks/blob/objects#download-links) | `shares.create()` |
| - | - | - |
| Public object | Permanent CDN URL (`expires_at: null`) | Redirects to the permanent public URL (see the warning below) |
| Private object | Temporary link, up to 24 hours | Share link, up to 30 days |
| Revocable | **No** | Yes, with `shares.revoke()` |
| Download limit | No | Yes, `max_downloads` |
| Password | No | Yes, Pro and Enterprise |

Use `downloadUrl()` for short-lived links you hand out yourself, and a share when you need to take the link back or control who downloads it.

## Creating a share

```typescript theme={"system"}
const share = await blob.shares.create(id, {
    expires_in: 86400,     // seconds, 60 to 2592000 (default 86400)
    max_downloads: 10,     // 1 to 10000
    password: "secret123", // 8 to 128 characters, Pro and Enterprise
});

console.log(share.url);
```

| Option | Type | Description |
| - | - | - |
| `expires_in` | `number` | Link lifetime in seconds, 60 to 2592000 (30 days). Default 86400. |
| `max_downloads` | `number` | 1 to 10000. |
| `password` | `string` | 8 to 128 characters. Pro and Enterprise; other plans get `UPGRADE_REQUIRED`. |

The result has `id`, `url`, `expires_at`, `max_downloads`, `password` (whether one is set), `object` and `object_is_public`.

<Warning>
  If `object_is_public` is `true`, the share link redirects to the object's **permanent public URL**: the password, download limit and expiration **protect nothing**, because the file stays reachable at that URL. Make the object private first, then share it:

  ```typescript theme={"system"}
  const [result] = await blob.update(id, { private: true });
  if (result.ok) {
      id = result.id; // the id changes
      const share = await blob.shares.create(id, { max_downloads: 1 });
  }
  ```
</Warning>

## Listing shares

```typescript theme={"system"}
const shares = await blob.shares.list();
```

Returns an array of shares, each with `id`, `url`, `object`, `expires_at`, `remaining_downloads`, `password` and `created_at`.

## Revoking a share

```typescript theme={"system"}
await blob.shares.revoke(share.id);
```

The link stops working. `revoke()` resolves to nothing, and revoking a share that does not exist fails with `SHARE_NOT_FOUND`.

<Tip>
  Deleting, moving or renaming the object, or changing its visibility, also breaks its share links: they point to the old id. Create new shares for the new id.
</Tip>

<Note>
  `shares.create()` and `shares.revoke()` get a **single attempt**. Only `shares.list()`, a read, is [retried](/en/sdks/blob/errors#retry-policy).
</Note>

API reference: [Create Share](/en/blob-reference/endpoint/shares-create), [List Shares](/en/blob-reference/endpoint/shares-list), [Delete Share](/en/blob-reference/endpoint/shares-delete).

## Next steps

<CardGroup cols={2}>
  <Card title="Rules and stats" icon="sliders" href="/en/sdks/blob/rules_and_stats">
    Per-prefix rules and usage stats.
  </Card>

  <Card title="Links and sharing" icon="code" href="/en/blob-reference/links-and-sharing">
    How public URLs, download links and shares behave.
  </Card>
</CardGroup>
