Skip to main content

Archive Download

Download a shelf as a portable .tar.gz snapshot — ideal for CI pipelines, offline use, or environments without S3/FUSE support.

Quick Start with mount.sh

The fastest way to get a shelf onto disk. Pipe directly from the API:
curl -s https://api.shelv.dev/api/helpers/mount.sh | SHELV_KEY=sk_... SHELF_ID=a1b2c3d4-... sh
Or download and run with flags:
curl -sO https://api.shelv.dev/api/helpers/mount.sh
sh mount.sh --key sk_... --shelf a1b2c3d4-... --target ./my-shelf
Requires curl and tar. SHA-256 verification uses sha256sum or shasum if available.

Configuration

FlagEnv varDefaultDescription
--keySHELV_KEYAPI key (required)
--shelfSHELF_IDShelf UUID (required)
--targetTARGET./shelfExtraction directory
--apiSHELV_API_URLhttps://api.shelv.devBase URL override
The script handles 202 polling (up to 30 retries), SHA-256 verification, and atomic extraction automatically.

Manual API Usage

Get a Presigned URL

curl https://api.shelv.dev/api/shelves/{id}/archive-url?ttl=600 \
  -H "Authorization: Bearer sk_your_api_key"
Response (200):
{
  "url": "https://....r2.cloudflarestorage.com/...?X-Amz-Signature=...",
  "expiresAt": "2025-01-15T10:40:00.000Z",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb924...",
  "sizeBytes": 204800,
  "version": "2025-01-15T10:20:00.000Z"
}
The ttl query parameter sets URL expiration in seconds (60–3600, default 300). The version field is an ISO timestamp of when the archive was built, useful for cache invalidation.

Handle 202 — Archive Generating

If the archive hasn’t been generated yet (or the shelf was updated since the last build), the API returns 202:
{
  "status": "generating",
  "retryAfter": 5
}
Poll until you get a 200:
import time
import requests

url = f"https://api.shelv.dev/api/shelves/{shelf_id}/archive-url"
headers = {"Authorization": f"Bearer {api_key}"}

while True:
    resp = requests.get(url, headers=headers)
    if resp.status_code == 200:
        data = resp.json()
        break
    elif resp.status_code == 202:
        time.sleep(resp.json()["retryAfter"])
    else:
        resp.raise_for_status()

# Download the archive
archive = requests.get(data["url"])
The first request triggers archive generation. Subsequent requests during generation also return 202. Generation typically completes in seconds.

Integrity Verification

Verify the downloaded archive against the sha256 field from the API response:
echo "$EXPECTED_SHA  archive.tar.gz" | sha256sum --check
mount.sh does this automatically when sha256sum or shasum is available.

When to Use Archive vs. Other Methods

ApproachBest for
Archive downloadCI pipelines, offline use, environments without S3/FUSE
S3 mountingLong-running sandboxes, agents with shell tools
JSON treeServerless functions, in-memory agents, quick lookups
Single fileFetching a known file by path