Endpoints

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."
    ]
  }
}