Archives
Archives let you store a large file as a download-only artefact: a database dump, a .zip of generated assets, a build tarball, a big model export. The bytes stream directly to dedicated storage, you get a stable page URL, and anyone you authorise downloads it back byte for byte.
Archives are deliberately narrow:
- Download-only. An archive is never rendered, never viewed in the sandbox, and has no in-browser preview. It exists to be downloaded.
- Private-only. An archive is always
private. It cannot be madepublicorshared, and it cannot be put behind a public or disappearing link. Any attempt to change its visibility is refused. - Pro and Team only. Archive uploads require a Pro plan or higher. They count against your storage quota.
If you want a file that renders in the browser (HTML, PDF, an image, Markdown), use a normal upload instead. Archives are for bytes you want to store and hand back, not display.
Limits
| Free | Pro | Team | |
|---|---|---|---|
| Archive uploads | Not available | Yes | Yes |
| Max size per file | Not available | 10 GB | 10 GB |
archives:create per day | Not available | 50 | 100 |
| Counts against storage quota | Not available | Yes | Yes |
A file is refused before any bytes move when live storage plus recoverable trash
plus other uploads still in progress plus the declared archive bytes would exceed
the cap. The STORAGE_LIMIT billing response includes combined current usage, the
trash-only amount, pricing, and an upgrade URL. Storage add-on space counts toward
the cap only while the subscription is paid (see
Trash and storage accounting).
If your plan lapses
Archives follow the same clock as images and video. When the plan that pays for an archive drops to Free (cancelled, or unpaid after a failed payment), the archive stays downloadable for 14 days. From day 14 it is locked: every download route, including the CLI, the API, MCP and a custom domain, answers not found, and the dashboard shows it as locked. After 28 days it is permanently deleted. Restoring the plan before then brings it straight back. A workspace archive follows the workspace's Team plan, not the plan of the person who uploaded it.
Deleting an archive moves it to charged trash for 7 days. Other items, including folders and non-archive pages, stay in trash for 30 days. The archive object is removed only when it expires or Empty trash permanently purges it.
Archive vs a normal upload
Two things are decided independently:
- Kind (archive or a rendered page) is something you declare, never something inferred from size. By default a file is treated as an archive when its extension is one of
.zip,.tar,.gz,.tgz,.sql, or.sql.gz. To store any other file as a download-only blob (a 500 MB.csv, a large.htmlyou do not want rendered), opt in explicitly with the "store as file" option (--store-as-fileon the CLI,as_archiveon the API). - Transport is decided by size alone. Files 30 MB or smaller upload in a single streamed PUT. Files larger than 30 MB upload in parts (multipart), so a 10 GB file never has to fit in one request or in memory.
You rarely have to think about transport: the CLI, the MCP tools, and the dashboard all pick the right lane for you. It matters only if you call the REST API directly.
Dashboard
Drag a large file onto the dashboard drop zone and Sharedrop routes it for you:
-
A recognised archive (
.zip,.tar, and friends) uploads as an archive. -
A renderable file that is over your plan's render ceiling is not silently dropped. You get a prompt offering to store it as a downloadable file instead.
-
A file larger than 30 MB cannot be uploaded from the browser. The drop zone shows a ready-to-copy command instead:
sharedrop archive '/path/to/your-file.zip'Copy it, run it in your terminal, and the archive lands in the same account.
An archive's page in the dashboard is a download card: the file name, its size, and a Download button. There is no preview, no share tab, and no visibility control, because none of those apply to a private download-only file. You can rename it, move it into a folder, and delete it.
CLI
Requires @sharedrop/cli 1.8.0 or newer. See the CLI guide for installation and authentication.
sharedrop archive
Upload a large file as a download-only archive.
sharedrop archive <file> [options]The CLI streams the file straight to storage and automatically uses the multipart lane for files over 30 MB, resuming part by part. A 10 GB file is streamed from disk, never buffered in memory. Press Ctrl-C mid-upload and the CLI aborts the multipart cleanly so it does not hold your quota.
Options:
| Flag | Description |
|---|---|
--title <string> | Page title (default: derived from the file name) |
--folder <id|path> | File the archive into a folder in your Sharedrop tree. Accepts a folder id or a slash path like backups/2026, auto-creating missing segments |
--workspace <id> | Upload to a specific workspace |
--store-as-file | Store any file as a download-only archive, bypassing the archive-extension check. Use it for a large non-archive file (a big .csv, .html, or .log) |
--json | Force JSON output |
Examples:
# A database dump
sharedrop archive backup.sql.gz --title "Nightly DB backup"
# A 4 GB build tarball into a folder
sharedrop archive dist.tar.gz --folder builds/2026
# A large non-archive file, stored download-only
sharedrop archive huge-export.csv --store-as-fileHuman output prints the page ID, the size, and the exact download command. --json returns { "data": { "id", "size_bytes", "download_url" } }.
Downloading and deleting
Download an archive with the standard download command, which is archive-aware:
sharedrop download <id> -o backup.sql.gzFor an archive, download streams the raw stored bytes to disk (not a zip
wrapper). You can download an archive you own. Move it to recoverable trash
like any other page:
sharedrop delete <id>The archive remains charged while it is recoverable. Permanently clear the authenticated caller's trash only when that deletion is intended:
sharedrop trash emptyThe command is irreversible and releases the retained bytes after the guarded row deletion. Archives expire automatically after 7 days. Other items expire after 30 days.
Archives cannot be re-uploaded over. To replace one, delete it and upload a new archive.
MCP
The archive tools appear only when the connected account is on a plan that allows archives (Pro or Team). A free-tier agent never sees them. See Connector (MCP) for connecting an agent.
An agent uploads a large file like this:
create_archive_uploadwithfilenameandsize_bytes(optionallyfolder_id/folder_path,workspace, or areservation_idto claim a reserved address). The response is a transport plan plus aninstructionsstring telling the agent exactly what to do next.- For a file 30 MB or smaller the plan is the single lane: PUT the bytes to
upload_urlwith theupload_token, then callfinalize_upload(the same finalize used for normal uploads). - For a larger file the plan is multipart: it returns
page_id, the part size, and the part count (but no part URLs yet).
- For a file 30 MB or smaller the plan is the single lane: PUT the bytes to
sign_archive_parts(multipart only) with thepage_id. Returns fresh presignedpartsURLs for the parts still outstanding, plus theuploadedparts already received (so a resumed upload skips them). PUT each part's byte range directly to its URL with only aContent-Lengthheader, and capture the returnedETag.complete_archivewith thepage_idand the{ part_number, etag }list. Returns the finishedpageand adownload_url. This step is idempotent: a retried complete returns the same result without double-charging quota.abort_archivewith thepage_idif anything goes wrong. Releases the reserved quota. Also used to clear aMULTIPART_IN_PROGRESSerror (one in-flight archive per account): the error returns the stuckpage_idto abort.
sign_archive_parts and abort_archive exist as tools because the underlying routes need a credential the hosted agent does not hold, so the MCP server proxies them on the agent's behalf.
The download_url returned by complete_archive (and by the single-lane finalize) is a short-lived link the agent can hand back to the user.
Use delete_page to move a finished archive into charged trash. Use the
empty_trash tool only with clear intent to permanently remove the trash
(pass workspace for a workspace's trash). Archives stay recoverable for 7 days; other items
stay recoverable for 30 days.
REST API
Archive routes live under https://sharedrop.cloud/api/archives. Authenticate with a Bearer API key (sd_...), the same as the rest of the API. Write steps need a pages:write key; downloading needs only pages:read.
Zero object bytes pass through Sharedrop's servers: every step returns a presigned URL that you PUT to (or GET from) directly.
Start an upload
POST /api/archives/createThe single decision point. It runs the tier, size, and quota gates and returns the transport plan.
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | File name including extension |
size_bytes | number | Yes | Exact byte size of the file |
workspace | string | No | Upload to a specific workspace |
folder_id | string | No | Folder to file the archive into |
reservation_id | string | No | Claim a reserved address |
as_archive | boolean | No | Store any file as an archive, skipping the archive-extension check |
curl -X POST \
-H "Authorization: Bearer sd_..." \
-H "Content-Type: application/json" \
-d '{"filename": "backup.sql.gz", "size_bytes": 48219033}' \
https://sharedrop.cloud/api/archives/createResponse for a file 30 MB or smaller (single lane):
{
"transport": "single",
"upload_url": "https://uploads.sharedrop.cloud/...",
"upload_token": "...",
"finalize_url": "https://sharedrop.cloud/api/upload/finalize",
"object_key": "..."
}PUT the bytes to upload_url (Bearer upload_token), then finalize with the same /api/upload/finalize call used for normal uploads. The archive kind is bound into the signed token, so the finished page is a private download-only archive.
Response for a larger file (multipart):
{
"transport": "multipart",
"page_id": "550e8400-...",
"upload_id": "...",
"part_size_bytes": 67108864,
"part_count": 3,
"sign_parts_url": "https://sharedrop.cloud/api/archives/550e8400-.../sign-parts",
"complete_url": "https://sharedrop.cloud/api/archives/550e8400-.../complete",
"abort_url": "https://sharedrop.cloud/api/archives/550e8400-.../abort",
"effective_cap_bytes": 10737418240
}Error Cases:
400 VALIDATION_ERROR: Invalid body, or a file type that is not an allowed archive (passas_archive: trueto store it anyway)402 TIER_LIMIT: Archives require a Pro plan or higher402 FILE_SIZE_EXCEEDED: File exceeds your plan's per-file archive ceiling402 STORAGE_LIMIT: File exceeds your remaining storage quota409 MULTIPART_IN_PROGRESS: You already have an archive upload in flight. The response carries itspage_idandabort_url
Sign parts (multipart)
POST /api/archives/:id/sign-partsMint fresh presigned URLs for the parts still outstanding. Optional body { "part_numbers": [1, 2] } limits it to specific parts; omit it to sign every remaining part. Safe to call repeatedly, which is how a resumed upload works.
{
"parts": [{ "part_number": 1, "url": "https://..." }],
"uploaded": [{ "part_number": 2, "etag": "\"abc...\"" }],
"part_size_bytes": 67108864
}PUT each part's byte range directly to its url with a Content-Length header (no auth header), and keep the ETag from each response.
Complete or abort (multipart)
POST /api/archives/:id/completeBody { "parts": [{ "part_number": 1, "etag": "..." }] } with every uploaded part. Sharedrop verifies the real object size against what you declared, reconciles it against your quota, and flips the archive live.
{
"page": { "id": "550e8400-...", "slug": "abc123", "kind": "archive", "status": "active", "file_size": 48219033 },
"download_url": "https://..."
}Complete is idempotent: retrying after success returns the same result without completing twice or double-charging quota.
POST /api/archives/:id/abortNo body. Cancels the multipart upload and releases the reserved quota. Idempotent. Aborting an already-completed upload returns 409.
Download
GET /api/archives/:id/downloadReturns a 302 redirect to a short-lived presigned link that streams the raw bytes as an attachment. Needs only a pages:read key. You can download an archive you own; anything else returns 404 so existence is never leaked. An archive whose paying plan lapsed more than 14 days ago also returns 404, for the owner too, until the plan is restored (see If your plan lapses).
curl -L -H "Authorization: Bearer sd_..." \
https://sharedrop.cloud/api/archives/550e8400-.../download \
-o backup.sql.gzDelete
Archives use the standard page delete, which moves the archive row and retained object to charged trash:
curl -X DELETE \
-H "Authorization: Bearer sd_..." \
https://sharedrop.cloud/api/v1/pages/550e8400-...To permanently remove the authenticated caller's trash:
curl -X DELETE \
-H "Authorization: Bearer sd_..." \
https://sharedrop.cloud/api/trashThat DELETE /api/trash response contains success, purged, and
freedBytes. It is irreversible. Archives otherwise expire from trash after
7 days; other items expire after 30 days.
Workspace storage meters and new-write gates charge all trash in the workspace.
In a workspace's trash (?workspace_id=), an owner removes every item, a member
only the items they created plus the trashed folders.
Why archives are private-only
An archive is opaque stored bytes, not a page Sharedrop has sanitised and understood. Serving it publicly would mean handing arbitrary bytes to anyone with the link, so archives are held to the safest posture: private, owner-download-only, no public or shared links. Attempting to change an archive's visibility, add an access grant, or mint a disappearing link returns:
Archives are private only. Sharing is not available for this file.
Renaming, moving into a folder, and deleting all stay available.