CLI Guide
Upload and manage pages from your terminal. Works for both humans and AI agents.
Installation
Install globally via npm:
npm install -g @sharedrop/cli
Or run without installing using npx:
npx @sharedrop/cli upload report.html
Authentication
The CLI resolves credentials in this order (first match wins):
--tokenflag: Highest priority. Overrides everything for a single command.SHAREDROP_TOKENenvironment variable: Best for CI/CD..envfile in the current directory: Project-level config.- Stored credentials from
sharedrop login: Interactive browser-based auth.
By default the CLI targets https://sharedrop.cloud. Point it at another instance with the --url flag or the SHAREDROP_URL environment variable (same precedence: flag over env over .env).
Interactive Login
sharedrop login
Opens your browser to authenticate with sharedrop, using the same one-command flow as gh or glab. A CLI-specific key is created and stored in your OS config directory, so every later command just works from any directory. No copy-paste, no env var.
Stored credential location by platform:
| OS | Path |
|---|---|
| macOS | ~/Library/Preferences/sharedrop-nodejs/config.json |
| Linux | ~/.config/sharedrop-nodejs/config.json |
| Windows | %APPDATA%\sharedrop-nodejs\Config\config.json |
CI/CD Setup
Set SHAREDROP_TOKEN in your CI environment:
export SHAREDROP_TOKEN=sd_your_api_key_here
sharedrop upload report.html --json
Output Modes
The CLI auto-detects your terminal:
- TTY (interactive terminal): Human-friendly output with tables, colors, and spinners
- Non-TTY (piped/CI): JSON output, no colors, no spinners
Force JSON output in any context with the --json flag:
sharedrop list --json
JSON output follows the same structure as the REST API: { "data": ... } for success, { "error": { "code": "...", "message": "..." } } for errors.
When an upload changes or blocks content, human output prints the warning messages to stderr. JSON output keeps stdout machine-readable: data.warnings is always present on upload and update (an empty array for a clean upload), and each warning has a code to branch on. See Upload JSON.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Authentication required (no token found locally) |
| 3 | Authentication failed: the server rejected the token (invalid, revoked or expired, a 401) or refused the action (a 403) |
| 4 | Rate limited (429 from API) |
| 5 | Not found (404 from API) |
| 6 | Validation error (bad input) |
| 7 | Payment required (402 from API) |
Exit 1 also covers two cases worth knowing:
TOKEN_EXPIRED: the short-lived upload token for this one upload expired before it finished. Your API token is fine; run the same command again.sharedrop checkfound something the upload would change or block (see sharedrop check).
Exit code 7: the account is read only
A failed subscription payment that is still unpaid after 21 days puts the account into read only. Any command that writes then fails like this:
$ sharedrop upload report.html
Error: Your account is read only because a payment failed. Update your card at sharedrop.cloud/dashboard/settings/billing to start uploading again.
$ echo $?
7
The message is printed in red on stderr and nothing is uploaded. With --json you
get the same thing machine readable, with no pricing block:
{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Your account is read only because a payment failed. Update your card at sharedrop.cloud/dashboard/settings/billing to start uploading again."
}
}
This takes the CLI's plain error path, the same one every non-billing error takes, so
a request_id field may also appear in the JSON, with a matching Request ID: line
in the human output. Quote it if you contact support. Today's 402 body carries no
request id, so in practice you see just the message, but do not write a parser that
assumes the object has exactly two keys.
Update the card at the address in the message. The lock lifts on its own at the next successful payment, and the same command works again with nothing else to do.
Reading keeps working: list, get, whoami and delete work while the account
is locked, and so do fetch and download for documents. The lock drops the plan to
Free, so 14 days later fetch and download fail with not found for images, video and
archives until the plan is restored. See Failed payments for the full
timeline.
Commands
sharedrop upload
Upload a file to create a new page. Accepts HTML, PDF, MHTML, Markdown, JSON, JSONL, source code, plain text, Word documents, spreadsheets, images, and video (or a folder for an HTML bundle). Documents upload on every tier; images and video require Pro. The bytes stream directly to storage, never base64.
If an HTML upload contains tags or attributes that Sharedrop removes for safety, the command reports each removal after the upload succeeds. To see this before publishing, run sharedrop check first.
Size limits: each file can be up to your plan's per-file limit (Free 10 MB, Pro and Team 100 MB). HTML and other text files (Markdown, source code, plain text, JSON, JSONL, MHTML, skills, Word documents, spreadsheets) and SVG images are capped at 10 MB on every plan. A folder bundle is capped at the plan's per-file limit across all its files together. An oversized upload fails with FILE_SIZE_EXCEEDED before any bytes are sent. For larger content, split it, or upload it as a zip with sharedrop archive: it is stored as a download-only archive (Pro plan or higher).
sharedrop upload <file> [options]
Arguments:
| Argument | Description |
|---|---|
file | Path to a file (HTML, PDF, Markdown, JSON, image, and more), a folder for an HTML bundle, or - to read from stdin |
Options:
| Flag | Description |
|---|---|
--title <string> | Page title. Default: a new single file takes its file name without the extension (report.html becomes report); stdin (-) and folders take the HTML <title> (for a folder, the entry file's); --page-id keeps the page's current title |
--visibility <string> | public, private, or shared (default: private) |
--mode <string> | static or interactive, HTML only. Default: a new page takes your account's default upload mode (interactive unless you changed it in settings); a re-upload with --page-id keeps the page's current mode |
--entry <file> | Entry HTML for a folder/bundle upload, relative to the folder (default: index.html) |
--workspace <id> | Upload to a specific workspace |
--folder <id|path> | File the new page into a folder in your Sharedrop tree (Pro plan or higher), for single files and folder bundles. Accepts a folder id or a slash path like reports/q3, auto-creating missing segments. Ignored on re-upload |
--page-id <id> | Re-upload over an existing page: keeps the same URL and records a new version |
--to <slug|id> | Claim a reserved address created with sharedrop reserve. Single file only; mutually exclusive with --page-id, --folder, and folder bundles. See sharedrop reserve |
--json | Force JSON output |
Workspaces are part of the Team plan and are created in the dashboard. Anyone invited
to one can upload to it with --workspace, whatever their own plan. See
Workspaces and seats.
Examples:
Upload a file:
sharedrop upload report.html --title "Q1 Report" --visibility public
Upload from stdin (for agents piping HTML):
cat report.html | sharedrop upload - --title "Generated Report"
Generate and upload in one pipeline:
echo "<h1>Hello from CI</h1>" | sharedrop upload - --title "CI Build Output" --json
Upload an HTML slide deck:
# deck.html contains <meta name="sharedrop:kind" content="slides" />
sharedrop upload deck.html --title "Q3 review" --visibility public
There is no --slides flag and none is needed. An HTML file carrying the in-file marker uploads as a deck, gains a fullscreen Present mode, and can be opened on a TV by adding ?present=1 to its URL. See the slide decks guide.
Upload JSON
With --json (or when piped), upload and update <id> <file|folder> print:
{
"data": {
"id": "3f0c2b4e-8f7a-4c1d-9e2b-1a2b3c4d5e6f",
"title": "Q3 report",
"url": "/scottoau/ab12cd34ef",
"full_url": "https://sharedrop.cloud/scottoau/ab12cd34ef",
"kind": "html",
"mode": "interactive",
"visibility": "private",
"was_reupload": false,
"version": 1,
"scripts_will_run": false,
"external_resource_hosts": ["cdn.jsdelivr.net"],
"warnings": [
{ "code": "images_extracted", "detail": "img", "count": 2, "message": "2 inline images were moved to hosted storage." },
{ "code": "external_refs_block_scripts", "detail": "cdn.jsdelivr.net", "count": 1, "message": "Scripts will not run because the page loads resources from 1 external host. Turn on external network for this page or vendor the files." }
],
"same_title_pages": [
{ "id": "7d1e0a9c-2b3f-4e5d-8c7b-6a5f4e3d2c1b", "full_url": "https://sharedrop.cloud/scottoau/zz98yy76xx", "updated_at": "2026-10-06T22:14:03.000Z" }
]
}
}
| Field | Meaning |
|---|---|
mode | The mode the page actually got, after the account default or the page's existing mode was applied |
was_reupload | true when this replaced an existing page (--page-id or update) |
version | The page's version number. It starts at 1 and goes up by one on every re-upload, so a revision that updated in place shows the same id and url with a higher version |
scripts_will_run | Whether the page's scripts run right now: interactive mode, an HTML or slides page, scripts not blocked, and either external network on or no external hosts. Changing the page's settings later can change it |
external_resource_hosts | Hosts the stored HTML loads resources from. With external network off, these stop an interactive page's scripts |
warnings | Always present (possibly empty). Codes: removed_tag, removed_attribute, images_extracted (count inline images moved to hosted storage) and external_refs_block_scripts (detail lists the hosts) |
same_title_pages | Only on a new page: up to 5 of your existing pages with exactly the same title (ignoring case), newest first. A hint, not an error: use --page-id if you meant to revise one |
skipped | Folder bundles only, always present: files left out, each with path and reason (hidden file or unsupported file type) |
Human output prints the title, URL, ID, the effective mode and the version, with any warnings on stderr.
Uploading a large file (over 30 MB) or storing something download-only (a database dump, a build tarball, a big
.zip)? Usesharedrop archiveinstead.uploadis for files Sharedrop renders;archiveis for bytes you want to store and hand back.
sharedrop check
Run the real upload checks on a file or folder without publishing. check streams the bytes to quarantine exactly like upload, runs the server's sanitiser, image extraction, slides detection, size limit and external-host check, then deletes the copy. No page is created or changed, and no page slot is used.
Because check signs like an upload, it needs a free page slot and storage headroom for the file (a check with --page-id needs no free slot). At your page or storage cap it fails with the same limit error upload would give, and exits 7. It still never uses a page slot or publishes anything.
sharedrop check <file|folder> [options]
| Flag | Description |
|---|---|
--mode <string> | Check as static or interactive (default: the mode upload would use) |
--page-id <id> | Check as a re-upload of this page (its mode applies unless --mode is set) |
--slides | Check a single HTML file as a slide deck |
--entry <file> | Entry HTML for a folder (default: index.html) |
--workspace <id> | Check as an upload to this workspace (the same option as upload --workspace) |
--json | Force JSON output |
Exit code: 1 when the upload would change or block something (would_change is true), 0 when it would publish as-is. Other errors use the normal exit codes.
would_change is true when the file is too large, or when any warning is removed_tag, removed_attribute or external_refs_block_scripts. Moving inline images to hosted storage (images_extracted) alone does not count as a change.
JSON output:
{
"data": {
"kind": "html",
"mode_effective": "interactive",
"detected_slides": false,
"size_ok": true,
"size_bytes": 48211,
"size_limit_bytes": 26214400,
"title": "Q3 report",
"warnings": [ { "code": "removed_tag", "detail": "iframe", "count": 1, "message": "Removed 1 <iframe> element." } ],
"images_extracted": 2,
"external_resource_hosts": [],
"scripts_would_run": true,
"same_title_pages": [],
"would_change": true
}
}
A folder adds "files" (the number of files in the bundle). If the size is refused before the checks can run, data is { "size_ok": false, "size_bytes", "size_limit_bytes" (or null), "would_change": true, "warnings": [], "message" } and the exit code is 1.
sharedrop check report.html --json && sharedrop upload report.html --json
sharedrop archive
Upload a large file as a download-only archive (Pro plan or higher). The bytes stream straight to storage, files over 30 MB upload in resumable parts, and the archive is always private. Full walkthrough in the Archives guide.
sharedrop archive <file> [options]
Options:
| Flag | Description |
|---|---|
--title <string> | Page title (default: derived from the file name) |
--folder <id|path> | File the archive into a folder (id or slash path; missing segments are created) |
--workspace <id> | Upload to a specific workspace |
--store-as-file | Store any file as a download-only archive, bypassing the archive-extension check (for a large non-archive file) |
--json | Force JSON output |
Examples:
sharedrop archive backup.sql.gz --title "Nightly DB backup"
sharedrop archive huge-export.csv --store-as-file # any file, stored download-only
Download it back with the archive-aware sharedrop download <id>. Use
sharedrop delete <id> to move it to charged trash for 7 days. Run
sharedrop trash empty only when you intend permanent deletion. Archives cannot
be re-uploaded over: delete and upload a new one to replace.
sharedrop list
List your pages. The table includes each page's ID. Copy it into get, update, delete, or share.
sharedrop list [options]
Options:
| Flag | Description |
|---|---|
--limit <number> | Results per page (default: 50, max 100) |
--cursor <string> | Pagination cursor |
--workspace <id> | Filter to a specific workspace |
--folder <id|path> | List the pages inside a folder (id or existing slash path) |
--json | Force JSON output |
Example:
sharedrop list --limit 10
sharedrop list --folder reports/q3 # pages filed under a folder
sharedrop search
Find pages with a single query matched across title, slug, id, and file type at once, so jpeg finds your image uploads and report finds them by name. Scoped to your own pages.
sharedrop search <query> [options]
Options:
| Flag | Description |
|---|---|
--limit <number> | Results per page (default: 50, max 100) |
--cursor <string> | Pagination cursor |
--workspace <id> | Search within a specific workspace |
--json | Force JSON output |
Examples:
sharedrop search jpeg # every JPEG you've uploaded
sharedrop search "q3 report" # match by title
sharedrop search ubbsrh8rwx # match by slug or id
sharedrop get
Get details for a specific page.
sharedrop get <ref> [options]
<ref> can be the page id, its slug, or a full page URL, whichever is easiest to paste. The same applies to update, delete, and share.
Options:
| Flag | Description |
|---|---|
--json | Force JSON output |
Example:
sharedrop get 550e8400-e29b-41d4-a716-446655440000
sharedrop get ubbsrh8rwx
sharedrop get https://sharedrop.cloud/you/ubbsrh8rwx
sharedrop fetch
Pull a page's raw content: the original file bytes, not the sandboxed viewer page. Built for an agent reading a page (its own, a public one, or one shared to it) into its context. get returns metadata; fetch returns the content itself. Available on every tier.
sharedrop fetch <id> [options]
By default the raw bytes stream to stdout (no log line), so you can pipe them straight into another tool. Use --output to write a file.
Options:
| Flag | Description |
|---|---|
-o, --output <path> | Write the bytes to a file (- for stdout, the default) |
--json | Force JSON output |
Examples:
sharedrop fetch ubbsrh8rwx # raw content to stdout
sharedrop fetch ubbsrh8rwx -o report.html # write to a file
sharedrop fetch ubbsrh8rwx | grep -i title # pipe into another tool
Distinct from
download(which writes a zip of the full artefact for a human).fetchreturns the raw root document with its real content type and is the agent-native read path.
Archives can't be fetched: sharedrop fetch on an archive fails with ARCHIVE_DOWNLOAD_REQUIRED. Use sharedrop download <id> for archives. An unknown id or slug fails with a not-found error (exit code 5).
An image or video page that is still in its safety check can only be fetched or downloaded by its owner. An image, video or archive page whose paying plan lapsed more than 14 days ago cannot be fetched or downloaded by anyone until the plan is restored. Both fail with the same not-found error.
sharedrop download
Download a page's complete artefact as a zip: the root document plus every asset (images, CSS, JS) beneath it, with their original relative paths preserved. Use download when you want the whole bundle on disk; use fetch when you only need the raw root document.
sharedrop download <id> [options]
By default the zip is written to <ref>.zip in the current directory. Use --output to choose the path, or -o - to stream the zip to stdout.
Options:
| Flag | Description |
|---|---|
-o, --output <path> | Output file path. Defaults to <ref>.zip (- streams to stdout) |
--json | Force JSON output (errors only) |
Examples:
sharedrop download ubbsrh8rwx # writes ubbsrh8rwx.zip
sharedrop download ubbsrh8rwx -o report.zip # write to a specific path
sharedrop download ubbsrh8rwx -o - > out.zip # stream to stdout
You can download a page you own, or one shared to you with download enabled: the sharer ticks "allow zip download" on your access grant, matched against your account's verified email. A page you can't download returns the same not-found error as a page that doesn't exist, so existence is never leaked.
The default filename uses the ref you pass (
<ref>.zip), not the page's slug, because the slug isn't known client-side without an extra lookup. Pass-oto set the name.
sharedrop update
Update a page's content, title, or visibility. Pass a file to replace the page's content, or a folder to replace a folder (bundle) page's files. The URL stays the same and the page's version goes up by one. Omit the file to change metadata only.
When you pass a file or folder, the output is the same as upload (see Upload JSON): was_reupload is true, version shows the new number, and warnings lists anything the sanitiser removed.
sharedrop update <id> [file] [options]
Options:
| Flag | Description |
|---|---|
--title <string> | New page title |
--visibility <string> | public, private, or shared |
--mode <string> | static or interactive when replacing content (default: keep the page's current mode) |
--slug <address> | Rename a public page to a custom address (Pro plan or higher) |
--json | Force JSON output |
Examples:
# Replace content -- same URL, new version recorded
sharedrop update 550e8400-... report.html
# Replace a folder page's files in place
sharedrop update 550e8400-... ./site
# Change metadata only
sharedrop update 550e8400-... --title "Updated Report" --visibility public
# Rename a public page to a custom address
sharedrop update 550e8400-... --slug quarterly-report
sharedrop delete
Move a page to recoverable, charged trash. Archives stay there for 7 days.
Other pages stay for 30 days. Use sharedrop trash empty to permanently remove
the authenticated caller's trash.
sharedrop delete <id> [options]
Options:
| Flag | Description |
|---|---|
--json | Force JSON output |
Example:
sharedrop delete 550e8400-e29b-41d4-a716-446655440000
sharedrop trash empty
Permanently remove the authenticated caller's trash and release its charged storage. This operation is irreversible. The command itself is the destructive confirmation, so it works without a prompt in terminals, agents, and CI.
sharedrop trash empty [options]
Options:
| Flag | Description |
|---|---|
--json | Return structured output with numeric purged and freedBytes fields |
Examples:
sharedrop trash empty
sharedrop trash empty --json
Human output reports how many rows were purged and formats the released byte count. JSON output preserves the server response:
{
"success": true,
"purged": 3,
"freedBytes": 1048576
}
Deleting an item does not immediately release storage. New uploads and archives compare live usage plus recoverable trash plus uploads still in progress plus the candidate bytes against the cap. Restore checks live usage plus only the selected trashed subtree. Archives stay in trash for 7 days. Other items, including folders, stay for 30 days.
Workspace storage meters and new-write gates charge all trash in the workspace. Empty trash removes only rows owned by the authenticated caller, even when that caller is a workspace member or owner. A workspace-bound key narrows the caller-owned operation to its bound workspace. Workspace-owner-wide Empty trash is tracked separately and is not implemented.
sharedrop move
Move an existing page into a folder, or back to your top level. Only the page's place in your tree changes: its URL, contents, and shares stay the same. Requires a Pro plan or higher (folders are Pro-gated); a free key prints the server reason plus an upgrade link.
sharedrop move <id> (--folder <id|path> | --root)
Pass exactly one destination. --folder accepts a folder id or a slash path like reports/2026/q3, auto-creating any missing segments; --root sends the page back to your top level.
Options:
| Flag | Description |
|---|---|
--folder <id|path> | Destination folder (id or slash path; missing segments are created) |
--root | Move the page to your top level |
--json | Force JSON output |
Examples:
sharedrop move ubbsrh8rwx --folder reports/q3 # into a folder (auto-created)
sharedrop move ubbsrh8rwx --root # back to your top level
To file a page into a folder at upload time instead, use
sharedrop upload <file> --folder <id|path>. To move a whole folder, usesharedrop folder move.
sharedrop share
Share a page with someone by email.
sharedrop share <id> --email <email> [options]
Options:
| Flag | Description |
|---|---|
--email <string> | Email address to share with (required) |
--json | Force JSON output |
Example:
sharedrop share 550e8400-... --email colleague@example.com
The recipient gets an invitation email, up to a daily limit per account: 10 on Free, 500 on Pro
and 2000 on Team (this also counts link create --people emails). Over the limit the share still works, but
no email is sent and the CLI prints a yellow line naming the limit, so send the link yourself.
With --json the same message is in email_warning.
sharedrop link
Manage disappearing links (Pro and Team): separate links that stop working after a time limit or a number of views. A link never changes the page's own visibility or sharing. See the Disappearing links guide.
sharedrop link create <id> [options]
sharedrop link list <id>
sharedrop link people <id> <link-id> [--add <emails...>] [--remove <emails...>]
sharedrop link revoke <id> <link-id>
<id> is the page id, slug, or full URL.
link create options:
| Flag | Description |
|---|---|
--people <emails...> | Only these people can open the link, after signing in with one of these emails. Comma or space separated. Without it, anyone holding the link can open it |
--expires-in <duration> | Time limit, e.g. 30m, 12h, 7d (Pro up to 7 days, Team up to 30) |
--max-views <n> | Total views allowed across everyone |
--present | Slide decks only: open straight into fullscreen Present mode |
--no-email | With --people: don't email them the link. link people --add takes it too |
--json | Force JSON output |
Set --expires-in, --max-views, or both.
Examples:
# Anyone with the link, for 12 hours or 5 views
sharedrop link create q3-report --expires-in 12h --max-views 5
# Only the board, after they sign in
sharedrop link create q3-report --people board@example.com,cfo@example.com --expires-in 7d
# Add and remove people on that link
sharedrop link people q3-report <link-id> --add new@example.com --remove cfo@example.com
sharedrop link revoke q3-report <link-id>
Sharedrop emails the people on a --people link (and anyone added later) the link and its limits. Pass --no-email to send the URL the command prints yourself.
sharedrop reserve
Reserve a stable address before an agent has anything to upload. Prints the final URL plus a one-time claim token, then the agent claims it later with sharedrop upload <file> --to <slug>. See the Reserved addresses guide for the full walkthrough.
sharedrop reserve [options]
Options:
| Flag | Description |
|---|---|
--title <string> | Page title shown once the address is claimed |
--agent-name <name> | Name of the agent expected to claim this address |
--visibility <string> | public, private, or shared the claimed page inherits (default private) |
--slug <address> | Pre-claim a custom address for a public reservation (Pro plan or higher) |
--expires <timestamp> | Expiry as an ISO 8601 timestamp. Omit to keep it until claimed or revoked |
--json | Force JSON output |
The human output prints the reserved URL, status, and a Claim token with a "store this now, shown once, cannot be retrieved again" warning. Capture it immediately: the token appears only here, never in sharedrop reservations list. --json returns the reservation plus the sibling claim_token verbatim.
sharedrop reserve --title "Q3 Metrics" --agent-name "reporting-bot" --visibility public
sharedrop reserve --visibility public --slug quarterly-report
Claim it later with a single file:
sharedrop upload metrics.html --to abc123
--to accepts the reserved slug or the reservation id. The claim always creates a new page at the reserved URL, so it cannot be combined with --page-id (which replaces an existing page), --folder (the reservation keeps the folder chosen at reserve time), or a folder bundle (single file only). After the claim lands, re-upload over the live page with --page-id as normal.
sharedrop reservations
Manage your reserved addresses.
sharedrop reservations <subcommand> [options]
Subcommands:
| Command | Description |
|---|---|
reservations list | List your reserved addresses with their slug, status (reserved, claimed, expired, or revoked), intended agent, URL, and expiry. Accepts --limit and --cursor |
reservations revoke <id> | Revoke a reservation. The row is kept (status flips to revoked) and the claim token is permanently invalidated |
All subcommands accept --json for structured output.
sharedrop reservations list
sharedrop reservations revoke 550e8400-e29b-41d4-a716-446655440000
sharedrop login
Authenticate with sharedrop via your browser.
sharedrop login
Opens your default browser to the sharedrop login page. After authenticating, a CLI-specific key is created and stored in your OS config directory (see Authentication for paths). Requires a TTY (interactive terminal). For headless/CI, set SHAREDROP_TOKEN instead.
sharedrop whoami
Show your account information.
sharedrop whoami [options]
Options:
| Flag | Description |
|---|---|
--json | Force JSON output |
Displays your username, email, plan tier, and usage information.
sharedrop folder
Organise your pages into nested folders. The folder command groups the full lifecycle: create, list, rename, move, delete (to trash), and restore. Requires a Pro plan or higher; a free key prints the server reason plus Upgrade: https://sharedrop.cloud/pricing.
sharedrop folder <subcommand> [args] [options]
Subcommands:
| Command | Description |
|---|---|
folder create <path> | Create a folder. A slash path like reports/2026/q3 auto-creates each missing segment. --parent <id> nests under an existing folder. If the whole path already exists it prints an idempotent "already exists" line and exits 0 |
folder list [--parent <id>] | List your top-level folders, or a folder's direct children |
folder rename <id> <new-name> | Rename a folder |
folder move <id> (--parent <id> | --root) | Reparent a folder, or move it to your top level with --root. Exactly one flag is required |
folder delete <id> [--force] | Delete a folder. An empty folder goes straight away; a non-empty one needs --force, which moves the subtree to trash and reports the page/folder counts affected. Archive descendants stay for 7 days; every other item stays for 30 days |
folder restore <id> | Restore a trashed folder or page before its kind-specific expiry. Restore checks live usage plus the selected subtree; if the original parent is gone, the item returns to your top level |
All subcommands accept --json for structured output.
Examples:
sharedrop folder create reports/2026/q3 # nested, auto-creates segments
sharedrop folder list # top-level folders
sharedrop folder list --parent <folder-id> # a folder's children
sharedrop folder rename <folder-id> "Q3 Reports"
sharedrop folder move <folder-id> --root # back to top level
sharedrop folder delete <folder-id> --force # non-empty: sends subtree to trash
sharedrop folder restore <folder-id> # undo before kind-specific expiry
Folders are Pro-gated. On a free key, folder commands (and
--folderonupload/list/move) return aFOLDERS_RESTRICTEDerror with an upgrade link rather than silently falling back to your top level.
sharedrop about
Print what sharedrop is, why to use it, and the key links (docs, llms.txt, pricing). No authentication required.
sharedrop about [options]
Options:
| Flag | Description |
|---|---|
--json | Structured output ({ "data": { "tagline", "why", "links" } }) for agents |
Custom domains
If your account has a live custom domain, the CLI prints the branded
address for any page that is eligible for it. upload, list, get and reservations all show
https://share.yourcompany.com/yourhandle/abc123 instead of the sharedrop.cloud address, and
--json carries the same value in full_url. A page in a Team workspace uses the workspace's
custom domain, which the workspace owner manages.
Nothing about how you authenticate changes. The CLI still talks to sharedrop.cloud; only the URL
it hands you for a recipient is branded. Pages that are not eligible, private pages and archives,
keep their sharedrop.cloud address.
Custom domains cover public pages on subdomains only, and need exactly two records: one CNAME for
share and one CNAME for view. See Custom domains for the full v1 scope.
CI/CD Usage
For CI/CD pipelines, use environment variables and JSON output:
export SHAREDROP_TOKEN=sd_your_api_key_here
# Upload a build artifact
sharedrop upload dist/report.html --title "Build #${BUILD_NUMBER}" --json
# Check exit code
if [ $? -eq 0 ]; then
echo "Upload successful"
else
echo "Upload failed"
fi
Key considerations for CI:
- Set
SHAREDROP_TOKENas a secret in your CI provider - Use
--jsonfor machine-parseable output - Check exit codes for error handling (see Exit Codes)
- No interactive prompts in non-TTY environments
Agent Usage
AI agents that shell out to CLIs can use sharedrop directly:
# Agent generates HTML and pipes it
cat file.html | sharedrop upload - --title "Agent Report" --json
# Parse the JSON response
URL=$(cat file.html | sharedrop upload - --json | jq -r '.data.full_url')
Agents should:
- Always use
--jsonfor structured output - Use stdin (
-) for piping generated HTML - Run
sharedrop checkfirst when it matters what the sanitiser removes or whether scripts will run - Read
data.warnings,data.modeanddata.scripts_will_runfrom the upload result instead of a second call - Revise a page with
sharedrop update <id> <file>so the link stays the same;data.versiongoes up by one - Check exit codes for error handling
- Use
SHAREDROP_TOKENenvironment variable for authentication