API

Everything the UI does goes through a small HTTP API, built for shell scripts and AI agents. No OAuth, no SDK: a site's edit id and its edit password are enough, and an account can issue a single API token that covers every site it owns.

On the hosted instance at app.sitebin.io, the API is an account feature: a site created anonymously (a Drop) has no API access at all — manage it from its edit page instead, or sign in and create the site there to script it. Self-hosted community instances have no accounts and no gate — every example below works anonymously there.

Authentication

There are two ways to authenticate, and which one you want depends on whether you are managing one site or many.

Edit password — one site

Every request identifies the site by its edit id (in the URL path) and proves ownership with the edit password — sent as an X-Edit-Password header, or via HTTP Basic auth. Both come from the site's claim ticket. This is the only method a self-hosted community instance has, and it needs no account at all.

Account API token — every site you own (Enterprise)

An account can issue API tokens in the dashboard at /account, optionally named so you can tell them apart. Send one as a bearer token:

curl -H "Authorization: Bearer $TOKEN" \
     -F "files=@dist.zip" https://app.sitebin.io/api/sites

A token does two things an edit password cannot. It creates sites owned by your account without a browser session — the reason it exists, since publishing a build artifact from CI or an AI agent has no browser to sign in with. And it replaces the edit password on every site that account already owns, so a pipeline that manages twenty sites carries one secret instead of twenty.

A token is shown once, at creation. Sitebin stores only its hash, so a lost token is replaced rather than recovered — revoke it in the dashboard and issue another.

What a token cannot do. It acts on sites, never on the account that owns them: the dashboard refuses it, so it cannot change your plan, reset passwords or delete your account. It reaches no other account's sites, and no anonymous site — those belong to nobody. A token that has been revoked, or one that never existed, is refused outright rather than falling back to something weaker.

The examples below use https://app.sitebin.io as the host (swap in your own base domain if you self-host) and assume $EDIT_ID and $PW hold a site's edit id and edit password. Anywhere you see -H "X-Edit-Password: $PW" you can substitute -H "Authorization: Bearer $TOKEN", as long as the token's account owns the site.

Create a site

POST multipart form data. Repeat the files field freely; create folders by putting a path in the part's filename.

curl -F "files=@index.html" -F "files=@app.js;filename=js/app.js" \
     https://app.sitebin.io/api/sites

Create a viewer site with settings

Settings can be supplied at creation time as ordinary form fields — here the mode, a view password, an expiry, WebDAV, and a custom domain.

curl -F "mode=viewer" -F "view_password=sesame" \
     -F "expires_at=2026-12-31T23:59:59Z" -F "webdav=true" \
     -F "domain=docs.client.com" \
     -F "files=@report.pdf" \
     https://app.sitebin.io/api/sites

Upload a zip

A zip field is unpacked server-side into the new site.

curl -F "zip=@site.zip" https://app.sitebin.io/api/sites

Read site settings

A GET on the site returns its settings, file list, and usage.

curl -H "X-Edit-Password: $PW" https://app.sitebin.io/api/sites/$EDIT_ID

Update settings

PUT a JSON object with any subset of settings; "expires_at": null clears the expiry.

curl -X PUT -H "X-Edit-Password: $PW" -H "Content-Type: application/json" \
     -d '{"mode":"viewer","entry_file":"report.pdf","webdav_enabled":true}' \
     https://app.sitebin.io/api/sites/$EDIT_ID

Manage files

Add files

curl -X POST -H "X-Edit-Password: $PW" -F "files=@new.html;filename=new.html" \
     https://app.sitebin.io/api/sites/$EDIT_ID/files

Replace all files

?replace=true swaps out the site's entire content — here with a zip, in one request.

curl -X POST -H "X-Edit-Password: $PW" -F "zip=@all.zip" \
     "https://app.sitebin.io/api/sites/$EDIT_ID/files?replace=true"

Delete a file

curl -X DELETE -H "X-Edit-Password: $PW" \
     https://app.sitebin.io/api/sites/$EDIT_ID/files/js/app.js

Custom domains

Custom domains are an Enterprise feature — in the community edition these endpoints return 403.

Add a domain

curl -X POST -H "X-Edit-Password: $PW" -H "Content-Type: application/json" \
     -d '{"domain":"docs.client.com"}' \
     https://app.sitebin.io/api/sites/$EDIT_ID/domains

Remove a domain

curl -X DELETE -H "X-Edit-Password: $PW" \
     https://app.sitebin.io/api/sites/$EDIT_ID/domains/docs.client.com

Read one file's content

Returns the raw content of a single file — this is what the in-browser editor uses.

curl -H "X-Edit-Password: $PW" https://app.sitebin.io/api/sites/$EDIT_ID/content/index.html

Download the site as a zip

curl -H "X-Edit-Password: $PW" -o site.zip https://app.sitebin.io/api/sites/$EDIT_ID/download

Delete the site

curl -X DELETE -H "X-Edit-Password: $PW" https://app.sitebin.io/api/sites/$EDIT_ID

Report abuse

Public endpoint, no auth required.

curl -X POST -H "Content-Type: application/json" \
     -d '{"target":"https://abc.app.sitebin.io","reason":"phishing"}' \
     https://app.sitebin.io/api/report

Rate limits

Anonymous site creation is rate limited per IP, and password attempts (edit, view, and WebDAV auth) are rate limited per IP and per site. Self-hosted instances can tune both limits at startup.