[Beta] JSON API
This API is in beta. If you choose to use the API, you should know what that means. In particular, the endpoints and behavior might change at any time. Please contact support before using.
Base URL: https://builder.statichost.eu
Prerequisites
Every request needs the following headers:
Authorization: Bearer <your-api-key>
Accept: application/json
Content-Type: application/json
Create your API key in the dashboard under Account → API keys. An API key acts as the user who created it and can reach every site that user can reach. There are no per-site or read-only scopes available.
Accept and Content-Type headers need to be set exactly, as they are currently checked via direct string comparison (no parsing is done).
For the Content-Type header, use application/json for JSON request bodies
and application/zip for uploads.
Direct upload flow
Creating a live site takes two calls: create the site, then upload files to it. A newly created site exists but serves nothing until a zip is uploaded.
Step 0 — get your team ID
Site creation is scoped to a team. Contact support in order to get your team ID.
Step 1 — create the site
POST /team/{team_id}/add-site
curl -X POST https://builder.statichost.eu/team/team_01ab2cd3ef4gh5ij6kl7mn8op/add-site \
-H "Authorization: Bearer $STATICHOST_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "my-site"}'
Request fields
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | Site name. See rules below. |
primary_domain |
string | no | Custom domain to set as canonical. See Domains. |
redirect_domains |
string[] | no | Custom domains that redirect to the primary. |
Site name rules — lowercase letters, digits and hyphens only (^[a-z0-9-]+$),
at least 3 characters, and not one of the reserved names (www, api, admin
and similar). The name is globally unique across all customers and becomes the
site’s managed domain: my-site.statichost.page.
Success — 200 OK
{
"name": "my-site"
}
The response includes additional fields.
Failure — 500 with an error field:
{
"error": "You have reached the maximum number of sites allowed for your account. Please upgrade in order to add your next site."
}
Some error responses might return HTML.
Step 2 — upload your site
POST /{sitename}/drop
Send the zip as the raw request body:
curl -X POST https://builder.statichost.eu/my-site/drop \
-H "Authorization: Bearer $STATICHOST_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/zip" \
--data-binary @site.zip \
--max-time 300
Success — 201 Created, with an empty body. The upload is live at this
point: the response does not return until the files have been deployed and
published.
Failure — 500, with a JSON string (not an object) as the body:
"Could not unzip file"
Note this differs from the error shape used by create. Unifying them is one of the changes planned before this API leaves beta.
Important: Uploads are synchronous
The request stays open for the entire deploy-and-publish cycle. Two consequences:
- Set a generous client timeout. Five minutes is a reasonable starting point. Many HTTP clients default to 30 seconds or less, which will cut off legitimate uploads.
- A client-side timeout tells you nothing. The publish continues on our side regardless of whether you are still listening. If your client times out, do not blindly retry — fetch the site and check whether the upload landed, then retry only if it did not.
Uploading to a site that already has content replaces what is live. There is no partial or incremental upload.
Step 3 — set custom domains (optional)
POST /{sitename}/domains
This call replaces the site’s entire custom domain configuration. It is not additive: any domain you omit is removed. Always send the complete desired set.
curl -X POST https://builder.statichost.eu/my-site/domains \
-H "Authorization: Bearer $STATICHOST_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"primary_domain": "example.com",
"redirect_domains": ["www.example.com"]
}'
Request fields
| Field | Type | Required | Notes |
|---|---|---|---|
primary_domain |
string | no | The canonical address. At most one. |
redirect_domains |
string[] | no | Domains that 301-redirect to the primary. |
Sending neither field clears all custom domains. The site’s managed domain
(my-site.statichost.page) always works and cannot be removed.
Success — 200 OK, empty body.
Failure — 500, with a JSON string body, as with upload.
Step 4 — delete the site
DELETE /{sitename}
curl -X DELETE https://builder.statichost.eu/my-site \
-H "Authorization: Bearer $STATICHOST_API_KEY" \
-H "Accept: application/json"
This unpublishes the site, removes its files from the edge servers, and deletes the site record. It is not reversible and there is no confirmation step.
Response — always 200 OK. Check the body:
{ "deleted": true }
{ "error": "failed to delete site: cannot get site: ..." }
Known issues
- Error bodies use three different shapes across four endpoints.
500is returned for client-side mistakes that should be400/404/409.- Delete returns
200on failure. AcceptandContent-Typeare matched by exact string equality rather than proper content negotiation.- Some failures return HTML instead of JSON.
- The create endpoint’s
/team/{team}/URL prefix is being retired.
Feedback on any of these — or on what is missing — is welcome and will shape what the stable version looks like.