> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shelv.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Archive Download

> Download a shelf as a portable .tar.gz snapshot.

Archive download is useful for CI pipelines, offline processing, and environments where adapters are not available.

## Fast path: `download.sh`

```bash theme={"theme":{"light":"github-light","dark":"poimandres"}}
curl -s https://api.shelv.dev/v1/helpers/download.sh | SHELV_KEY=sk_... SHELF_PUBLIC_ID=shf_a1b2c3d4e5f60718293a4b5c sh
```

Or download and run locally:

```bash theme={"theme":{"light":"github-light","dark":"poimandres"}}
curl -sO https://api.shelv.dev/v1/helpers/download.sh
sh download.sh --key sk_... --shelf-public-id shf_a1b2c3d4e5f60718293a4b5c --target ./my-shelf
```

Script options:

| Flag                | Env var           | Default                 |
| ------------------- | ----------------- | ----------------------- |
| `--key`             | `SHELV_KEY`       | required                |
| `--shelf-public-id` | `SHELF_PUBLIC_ID` | required                |
| `--target`          | `TARGET`          | `./shelf`               |
| `--api`             | `SHELV_API_URL`   | `https://api.shelv.dev` |

## Manual API flow

Request a presigned URL:

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"poimandres"}}
  curl "https://api.shelv.dev/v1/shelves/{shelfPublicId}/archive-url?ttl=600" \
    -H "Authorization: Bearer sk_your_api_key"
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"poimandres"}}
  const res = await fetch(
    `https://api.shelv.dev/v1/shelves/${shelfPublicId}/archive-url?ttl=600`,
    { headers: { Authorization: `Bearer ${process.env.SHELV_API_KEY}` } },
  );
  const archive = await res.json();
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"poimandres"}}
  import os
  import requests

  res = requests.get(
      f"https://api.shelv.dev/v1/shelves/{shelf_public_id}/archive-url",
      params={"ttl": 600},
      headers={"Authorization": f"Bearer {os.environ['SHELV_API_KEY']}"},
  )
  archive = res.json()
  ```
</CodeGroup>

Rules:

* Shelf must be `ready` or `review`
* `ttl` range is `60` to `3600` seconds
* Default `ttl` is `300`

The first request may start archive preparation, so use short polling loops in automation.

If archive is not ready yet, you get `202`:

```json theme={"theme":{"light":"github-light","dark":"poimandres"}}
{
  "status": "generating",
  "retryAfter": 5
}
```

Poll after `retryAfter` seconds until `200`, then download from returned `url`.

On `401`, refresh credentials. On `409`, wait for an eligible shelf status (`ready` or `review`) before retrying.

## Verify integrity

Use `sha256` from the `200` response:

```bash theme={"theme":{"light":"github-light","dark":"poimandres"}}
echo "$EXPECTED_SHA  archive.tar.gz" | sha256sum --check
```

`download.sh` performs verification automatically when a SHA-256 tool is available.

## Choosing retrieval mode

* Archive: CI/offline snapshots
* Sandbox adapters: provider-native runtime hydration
* JSON tree: in-memory workflows
* Single file: targeted reads

For reproducible jobs, log the returned `version` timestamp with your build metadata.
