API
Everything the interface does, it does through this. There is no separate path — which is also why an agent connected to your account cannot reach anything you could not.
Authenticating
A key from Settings → API keys, sent as a bearer token. It is shown once and stored hashed, so a leak of our database is not a list of working keys.
curl https://solta.now/v1/me \
-H "Authorization: Bearer solta_…"Connectors use OAuth instead — see Connect Claude or ChatGPT. Both resolve to the same account with the same authority.
Publishing a file
curl -X POST https://solta.now/v1/sites \
-H "Authorization: Bearer solta_…" \
-H "Content-Type: application/json" \
-d '{"source": "export default () => <h1>hi</h1>",
"filename": "App.tsx",
"title": "Hello",
"channel": "api"}'Returns the slug, the version number and the link. Send an Idempotency-Key header and retrying the same request will not publish twice.
Publishing a folder
A separate endpoint, because the body is a file rather than JSON. Send the archive as archive, or a url we should read it from.
curl -X POST https://solta.now/v1/sites/archive \
-H "Authorization: Bearer solta_…" \
-F "archive=@dist.zip" \
-F "title=My site"Updating without breaking the link
A new version is a draft. The link keeps serving what it served until you publish it — which is two calls on purpose, so nothing goes live by accident.
POST /v1/sites/{id}/versions → { number: 2, state: "draft" }
POST /v1/sites/{id}/versions/2/publish → { number: 2, state: "live" }A folder changes by its files. POST /v1/sites/{id}/versions/files takes multipart form data: files to add (a .zip among them is opened, and a file with a name already there replaces it), a remove for each path to take out, and replace=true when the upload is the whole site. With publish=true it goes live in the same call, unless the site needs approval; then the answer has awaitsApproval: true and the version waits as a draft.
The rest
- GET /v1/library
- Your sites.
- GET /v1/sites/{slug}
- One site, its live version and its history.
- PATCH /v1/sites/{id}/visibility
- Who can open it.
- GET /v1/sites/{id}/compare?from=1&to=2
- What changed between two versions.
- DELETE /v1/sites/{id}
- Stops serving immediately. The address is held and never reissued.
Errors
A JSON body with error, and detail when there is something useful to add. A file we refuse — a planted key, an unsupported type — is a 422 with the reason in words, not a stack trace.

