Skip to the article
Solta

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"

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.