API Reference
Read recent project activity.
Base URL
https://staticx.site/api/v1
Every route requires Accept: application/json and a bearer token with the ability and scope needed for that route.
Authorization: Bearer STATICX_API_TOKEN
Accept: application/json
CLI authentication
The npm CLI is a thin client over the same API.
staticx login stores the base URL and bearer token locally, then verifies access with GET /user. Every later command keeps using the same token scope and route contract shown on this page.
npm install -g staticx
staticx login --base-url "https://staticx.site/api/v1" --token "STATICX_API_TOKEN"
staticx guide
staticx whoami
Token scopes
Match the token to the job.
Global
Account-wide access for internal tools, dashboards, or broad admin automation.
Common access levels in the UI: Full access and Read only.
Site-scoped
Limited to one site. Best for CI jobs, deploy bots, and one-off agent runs.
Common access levels in the UI: Full access and Read only.
Workspace-scoped
Limited to one workspace. Best when one runner needs several sites but should stay inside one team or client boundary.
Common access levels in the UI: Full access and Read only.
The API still returns internal preset ids in current_token.preset for debugging. The dashboard shows the user-facing labels Full access and Read only.
Route index
Current versioned API contract.
Account and access
| GET | /user |
Return the authenticated user for the current token. |
| GET | /workspaces |
List workspaces visible to the token owner. |
| POST | /workspaces |
Create a workspace. Body: name. |
| GET | /workspaces/{workspace} |
Read a workspace with members and project count. |
| DELETE | /workspaces/{workspace} |
Delete a workspace. Body: site_action=move/delete, target_workspace_id when moving. |
| GET | /domains |
List visible custom domains and generated subdomains. |
Projects
| GET | /projects |
List projects visible to the token owner. Optional query: workspace_id. |
| POST | /projects |
Create a project. Body: workspace_id, name, description, archive, or source_url. |
| GET | /projects/{project} |
Read one project, including workspace, host, status, and public URL. |
| PATCH | /projects/{project} |
Update project metadata. Body: name, description. |
| DELETE | /projects/{project} |
Delete a project the token owner can write to. |
Files and imports
| GET | /projects/{project}/files |
List workspace files. Optional query: path. |
| POST | /projects/{project}/files |
Upload files, upload a ZIP, or queue URL import. Body depends on mode. |
Deployments
| GET | /projects/{project}/deployments |
List published deployment versions for the project. |
| POST | /projects/{project}/deployments |
Publish the current project state as an immutable deployment. Requires a root index.html or index.htm and 404.html. |
| GET | /projects/{project}/deployments/{deployment} |
Read one published deployment version. |
| POST | /projects/{project}/deployments/{deployment}/rollback |
Activate a previous successful immutable deployment. |
| DELETE | /projects/{project}/deployments/{deployment} |
Delete one inactive deployment record. Active deployments are protected. |
| DELETE | /projects/{project}/deployments/delete-selected |
Delete multiple inactive deployments. Body: deployment_ids[]. |
Environment and logs
| GET | /projects/{project}/environment-variables |
List project variables. |
| POST | /projects/{project}/environment-variables |
Create one variable. Body: key, value, is_secret. |
| PUT | /projects/{project}/environment-variables |
Replace/sync variables. Body: variables[]. |
| DELETE | /projects/{project}/environment-variables/{environmentVariable} |
Delete one variable. |
| GET | /projects/{project}/logs |
Read recent project activity. |
Current token
Read the active token context with /user.
{
"data": {
"id": 18,
"name": "Amina Hart",
"email": "[email protected]",
"current_token": {
"id": 44,
"name": "Morning Peak deploy bot",
"kind": "project",
"preset": "project_editor",
"preset_label": "Full access",
"scope_type": "project",
"scope_id": 81,
"scope_label": "Site ยท Morning Peak",
"abilities": [
"user.read",
"projects.read",
"projects.write",
"files.read",
"files.write",
"deploy.read",
"deploy.run",
"logs.read"
],
"expires_at": "2026-05-22T10:00:00+00:00"
}
}
}
Command mapping
What the public CLI is expected to call.
| CLI command | API routes | Notes |
|---|---|---|
staticx login |
GET /user |
Stores the token client-side and confirms the current token metadata. |
staticx workspaces |
GET /workspaces |
Best with a Global token because it may cross workspace boundaries. |
staticx sites --workspace-id WORKSPACE_ID |
GET /projects?workspace_id=... |
Best with a Workspace token when the job should stay inside one workspace. |
staticx create --workspace-id ... --name "Site" |
POST /projects |
Creates a site inside the given workspace. |
staticx deploy --site-id SITE_ID --dir dist |
POST /projects/{project}/files, POST /projects/{project}/deployments |
Upload, then publish a new version. Best with a Site token. |
staticx logs --site-id SITE_ID |
GET /projects/{project}/logs |
Use after uploads, builds, and deployments. |
Project creation
Create an empty site, a ZIP-backed site, or a URL import.
Empty project
Create a blank site first, then upload files or deploy content later.
curl -X POST "https://staticx.site/api/v1/projects" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"Marketing Site"}'
Create from ZIP
Start the site with a ready-built archive when the project already exists locally.
curl -X POST "https://staticx.site/api/v1/projects" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-F "name=Marketing Site" \
-F "[email protected]"
Create from URL
Queue a remote import when STATICX should mirror a public site for you.
curl -X POST "https://staticx.site/api/v1/projects" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-F "source_url=https://example.com"
File upload modes
Use one endpoint for files, ZIP archives, and URL imports.
| Mode | Required fields | Use case |
|---|---|---|
files |
files[], optional path, optional overwrite_confirmed |
Upload one or more files into a project path. |
zip |
archive, optional path, optional overwrite_confirmed |
Upload a built static site. The ZIP root should contain index.html or index.htm plus 404.html. |
url |
source_url, optional path |
Queue an import from a public URL. |
curl -X POST "https://staticx.site/api/v1/projects/{project}/files" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-F "mode=zip" \
-F "overwrite_confirmed=1" \
-F "[email protected]"
Deploy
Upload first, publish second.
# The uploaded ZIP must include index.html or index.htm plus 404.html at the root.
curl -X POST "https://staticx.site/api/v1/projects/{project}/deployments" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
If the deployment fails, stop and return the API message plus project logs. Do not report success unless the deployment response has status=succeeded.
Deployment versioning
Rollback changes the active release pointer.
Successful deployments created by the current publisher include a readable release name, versioning state, active state, file count, and size. Rollback never copies files; it activates an existing deployment.
Rollback
curl -X POST "https://staticx.site/api/v1/projects/{project}/deployments/{deployment}/rollback" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
Delete one inactive deployment
curl -X DELETE "https://staticx.site/api/v1/projects/{project}/deployments/{deployment}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
Delete selected deployments
curl -X DELETE "https://staticx.site/api/v1/projects/{project}/deployments/delete-selected" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"deployment_ids":[101,102]}'
The API rejects deletion of the active deployment. Publish another release or roll back first, then delete inactive versions.
Environment variables
Store per-project settings for automation.
Create one variable
curl -X POST "https://staticx.site/api/v1/projects/{project}/environment-variables" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"key":"PUBLIC_API_URL","value":"https://api.example.com","is_secret":false}'
Sync variables
curl -X PUT "https://staticx.site/api/v1/projects/{project}/environment-variables" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"variables":[{"key":"TOKEN","value":"secret","is_secret":true}]}'
Responses
Predictable JSON shapes.
Project response
{
"data": {
"id": 18,
"name": "Marketing Site",
"description": "Production landing pages",
"host": "marketing.example.test",
"public_url": "https://marketing.example.test",
"status": "active",
"workspace": {
"id": 3,
"name": "Personal Workspace",
"role": "owner"
},
"subdomain": "marketing",
"custom_domain": null,
"created_at": "2026-05-11T12:10:44+00:00",
"updated_at": "2026-05-11T12:10:45+00:00"
}
}
Deployment response
{
"data": {
"id": 245,
"version_name": "Release #245",
"version_summary": "Versioned release - live now",
"kind": "deploy",
"status": "succeeded",
"message": "Deployment published.",
"is_active": true,
"is_versioned": true,
"file_count": 128,
"size_bytes": 934122,
"created_at": "2026-06-02T10:00:00+00:00",
"activated_at": "2026-06-02T10:00:01+00:00"
}
}
Validation error
{
"message": "Validation failed",
"errors": {
"source_url": [
"The source url field must be a valid URL."
]
}
}