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

> Get a download link for any file with GET /v1/objects/download: a temporary link of up to 24 hours for private files, or the public URL.

<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 Download gives you a link to read a file. For a **private** file it signs a temporary link, valid from 60 seconds to 24 hours, that works without any credential. For a **public** file it returns the public URL. By default it answers with a `302` redirect, so you can point a browser or `curl -L` straight at it; `redirect=false` returns the link as JSON. Requires the `blob:read` scope.

Temporary links (`https://files.squarecloud.dev/d/...`) can't be revoked, support `Range` and conditional requests, and stop working when they expire or when the file is deleted, moved or changes visibility. For links you can revoke, cap or protect with a password, use a [share link](/en/blob-reference/endpoint/shares-create). See [Links and sharing](/en/blob-reference/links-and-sharing).

<ParamField query="object" type="string" required>
  The id of the file.
</ParamField>

<ParamField query="expires" type="number" default="3600">
  How long the temporary link lasts, from 60 to 86400 seconds (24 hours).
</ParamField>

<ParamField query="redirect" type="boolean" default="true">
  `false` returns the link as JSON instead of redirecting.
</ParamField>

<ParamField query="disposition" type="string">
  `inline` (open in the browser) or `attachment` (download). Setting it always produces a temporary link, even for public files.
</ParamField>

<ParamField query="filename" type="string" placeholder="report-september.pdf">
  The name the browser saves the file as. Implies `attachment` unless `disposition` says otherwise, and always produces a temporary link.
</ParamField>

### Rate limits

<Note>
  * 60 requests per minute to this route (`RATE_LIMITED`, 429).
  * Each temporary link accepts 60 requests per minute per IP, on top of an overall limit for all the links of your account. Past that the link answers `429` in plain text. To hand one file to many people, make it public: public files are served by the CDN, without this limit. An expired or invalid link answers `404`.
</Note>

### Response

With `redirect=true` (default): `302` with the link in `Location` and `Cache-Control: no-store`. With `redirect=false`:

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

<ResponseField name="response" type="object">
  <Expandable title="Toggle object">
    <ResponseField name="url" type="string">
      The link: a temporary link on `files.squarecloud.dev`, or the public URL.
    </ResponseField>

    <ResponseField name="expires_at" type="ISO 8601 | null">
      When the temporary link expires, or `null` for a public URL.
    </ResponseField>

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

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

    <ResponseField name="content_type" type="string">
      The `Content-Type` the file is served with.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://blob.squarecloud.app/v1/objects/download?object=prv/3155597145698959364/invoices/2026-09_mugws5c0-1b4f0e9851971998e732078544c96b36.pdf&expires=600&redirect=false' \
    --header 'Authorization: YOUR_API_KEY'
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    object: 'prv/3155597145698959364/invoices/2026-09_mugws5c0-1b4f0e9851971998e732078544c96b36.pdf',
    expires: '600',
    filename: 'invoice-september.pdf',
    redirect: 'false',
  });

  const res = await fetch(`https://blob.squarecloud.app/v1/objects/download?${params}`, {
    headers: { Authorization: 'YOUR_API_KEY' },
  });
  const { response } = await res.json();
  // hand response.url to the user; it works without credentials for 10 minutes
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "status": "success",
    "response": {
      "url": "https://files.squarecloud.dev/d/Rb7nKq2WvX9sLp4TzYc1Hm8JdF0gUe6AoNiQ3tVwBk5Sy.Pj3Lx9Qe2Rw7Ty4Uo",
      "expires_at": "2026-09-25T12:10:00.000Z",
      "private": true,
      "size": 88412,
      "content_type": "application/pdf"
    }
  }
  ```
</ResponseExample>

### Errors

| Code                         | HTTP | When                                                   |
| ---------------------------- | ---- | ------------------------------------------------------ |
| `INVALID_OBJECT`             | 400  | `object` is missing, malformed or not yours.           |
| `INVALID_DOWNLOAD_EXPIRES`   | 400  | `expires` is not an integer from 60 to 86400.          |
| `INVALID_OBJECT_DISPOSITION` | 400  | `disposition` is not `inline` or `attachment`.         |
| `INVALID_FILENAME`           | 400  | `filename` is empty after removing invalid characters. |
| `OBJECT_NOT_FOUND`           | 404  | The file doesn't exist.                                |
| `RATE_LIMITED`               | 429  | More than 60 requests in a minute.                     |
