Skip to main content

Developers

Use user API keys to call the Hostless HTTP API from scripts, CI pipelines, or other services. Each key belongs to your account, carries explicit scopes, and acts on behalf of you across every project you can access.

Base URL

https://api.hostless.dev

All paths below are prefixed with /v1.

Authentication

API keys (automation)

Send the full token as the Authorization header. Do not add a Bearer prefix.

curl -sS \
-H "Authorization: hlk_a1b2c3d4_your_secret_here" \
"https://api.hostless.dev/v1/apps"
HeaderValue
Authorizationhlk_<prefix>_<secret>

Some HTTP clients always send Bearer. This is also accepted when the token starts with hlk_:

Authorization: Bearer hlk_a1b2c3d4_your_secret_here

User sessions (dashboard / key management)

Browser login and creating or revoking API keys require a normal JWT session:

Authorization: Bearer <access_token>

API keys cannot call key-management routes or account-level billing routes (payment methods, currency).

Quick start

  1. In the dashboard, open Account → Settings → API Keys.
  2. Create a key, select scopes, set optional expiry, and copy the token immediately (shown once).
  3. Call any allowed platform endpoint with Authorization: hlk_....
export HOSTLESS_API="https://api.hostless.dev"
export HOSTLESS_TOKEN="hlk_xxxxxxxx_your_secret"

# List apps across all projects you can access
curl -sS -H "Authorization: $HOSTLESS_TOKEN" "$HOSTLESS_API/v1/apps"

List endpoints return resources from all projects you belong to. Optional ?projectId= filters to one project. When creating resources with an API key, include projectId in the request body.

Model Context Protocol (MCP)

Hostless exposes a remote HTTP MCP server at https://mcp.hostless.app with two endpoints:

EndpointAuthPurpose
POST /mcp/docsNoneRead Hostless documentation (docs_search, docs_get_page, docs_list)
POST /mcpAPI key, JWT, or OAuthCall platform APIs as typed tools (apps_*, projects_*, etc.)

The MCP service is separate from the REST API. Platform tool calls are proxied to https://api.hostless.dev/v1/* using your credentials. API key scopes and project roles apply the same way as direct HTTP calls.

Use /mcp/docs when you only need documentation (onboarding agents, open-source examples, or users without a Hostless account). Use /mcp when the agent should manage apps, sites, databases, and other resources.

MCP base URL

https://mcp.hostless.app

Use the URL of your deployed MCP service if self-hosting.

RouteMethodPurpose
/healthGETLiveness check (no auth)
/.well-known/oauth-protected-resourceGETOAuth resource metadata for /mcp
/mcp/docsPOSTPublic documentation MCP (no auth)
/mcpPOSTPlatform API MCP (auth required)
/mcp, /mcp/docsGETNot supported (returns 405)

Health check

curl -sS "https://mcp.hostless.app/health"
{
"ok": true,
"service": "hostless-mcp",
"baseUrl": "https://api.hostless.dev",
"docsMcpPath": "/mcp/docs"
}

Public documentation MCP (no auth)

Read-only access to Hostless guides, API reference, and framework tutorials. No API key, no JWT, no Authorization header.

Docs MCP URL

https://mcp.hostless.app/mcp/docs
ToolPurpose
searchOpenAI-compatible search; returns document ids, titles, and URLs
fetchOpenAI-compatible fetch; loads full document text and citation metadata by id
docs_searchSearch documentation by keyword; returns titles, paths, snippets, and public URLs
docs_get_pageLoad a full page by path (e.g. app/deployments, developers) — omit .md / .mdx
docs_listList every documentation page

Tips for agents

  • Prefer search then fetch for ChatGPT/OpenAI clients and deep-research-style retrieval.
  • docs_search, docs_get_page, and docs_list remain available for existing MCP clients.
  • Paths match the public docs site (https://web.hostless.cloud/...) without the file extension.
  • For deploys, billing, or resource changes, connect to the platform API MCP instead.

Connect from Cursor (no auth)

Prefer a native HTTP MCP entry — no mcp-remote bridge and no env vars:

{
"mcpServers": {
"hostless-docs": {
"url": "https://mcp.hostless.app/mcp/docs"
}
}
}

Alternatively, use mcp-remote:

{
"mcpServers": {
"hostless-docs": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.hostless.app/mcp/docs"]
}
}
}

Restart Cursor after saving ~/.cursor/mcp.json (or your project MCP config).

Connect from Claude Desktop (no auth)

Add a streamable HTTP MCP server (Settings → Developer → MCP):

FieldValue
URLhttps://mcp.hostless.app/mcp/docs
Authorization headerOmit — not required

Local development (no auth)

Run the MCP HTTP server from the monorepo:

cd hostless-api
npm run build
npm run start:mcp:http # default http://localhost:3333

Docs are loaded automatically from hostless-docs/docs/ when the repo is checked out side by side. Set API_BASE_URL in hostless-api/.env if startup fails (required to boot the process even when you only use /mcp/docs).

Point Cursor at the local docs endpoint:

{
"mcpServers": {
"hostless-docs-local": {
"url": "http://localhost:3333/mcp/docs"
}
}
}

Verify locally:

curl -sS http://localhost:3333/health

Docs + platform API together

Use two MCP servers in the same config — docs without credentials, platform with your API key:

{
"mcpServers": {
"hostless-docs": {
"url": "https://mcp.hostless.app/mcp/docs"
},
"hostless": {
"url": "https://mcp.hostless.app/mcp",
"headers": {
"Authorization": "hlk_a1b2c3d4_your_secret_here"
}
}
}
}

For local platform API calls, swap hostless to http://localhost:3333/mcp and use your dev API key.

Platform API MCP (auth required)

Every POST /mcp request must include an Authorization header. Use the same tokens as the REST API:

Token typeHeader
API keyAuthorization: hlk_<prefix>_<secret>
API key (some clients)Authorization: Bearer hlk_<prefix>_<secret>
User JWTAuthorization: Bearer <access_token>
OAuth access tokenAuthorization: Bearer <oauth_access_token>

Create an API key in the dashboard (Account → Settings → API Keys) with the scopes you need (for example apps:read, projects:read). The MCP server does not accept a server-wide token — each client sends its own credential on every request.

OAuth for ChatGPT and Claude connectors

AI clients can connect to Hostless MCP using OAuth 2.0 authorization code + PKCE instead of pasting an API key. When a client has no token, POST /mcp returns 401 with a WWW-Authenticate header pointing at the protected-resource metadata URL.

Discovery

DocumentURL
Authorization server (API host)https://api.hostless.dev/.well-known/oauth-authorization-server
JWKS (API host)https://api.hostless.dev/.well-known/jwks.json
Protected resource (MCP host)https://mcp.hostless.app/.well-known/oauth-protected-resource

Flow (summary)

  1. Client discovers metadata from the URLs above.
  2. Client opens GET /v1/oauth/authorize on the API with PKCE (code_challenge / S256), resource=https://mcp.hostless.app, and a registered redirect_uri.
  3. Hostless redirects to the web app consent screen (/oauth/authorize). Sign in if needed, then Allow or Deny.
  4. Client exchanges the authorization code at POST /v1/oauth/token for a short-lived RS256 access token and refresh token.
  5. Client calls POST https://mcp.hostless.app/mcp with Authorization: Bearer <oauth_access_token>.

Scopes (v1): OAuth connectors receive read-only scopes (for example projects:read, apps:read, logs:read). Write and delete scopes are not granted to ChatGPT/Claude connectors in this release.

Revoke access: In the dashboard go to Account → Settings → Connected AI apps and revoke the connector. Access stops on the next MCP or API request.

Claude custom connector credentials

Claude requires a Client ID and Client secret in Advanced settings. Generate your own credentials in the dashboard (Account → Settings → Connected AI apps → Generate Claude credentials). Each credential pair is tied to your account — you do not need a shared platform secret.

  1. Generate credentials and copy the Client ID (hloc_…) and Client secret (shown once).
  2. In Claude: add a custom connector with MCP URL https://mcp.hostless.app/mcp.
  3. Open Advanced settings and paste the Client ID and Client secret.
  4. Complete OAuth consent when Claude connects.

ChatGPT

ChatGPT uses the public openai-chatgpt OAuth client. Per-connector redirect URLs (https://chatgpt.com/connector/oauth/{id}) are allowed via redirect URI prefix matching — no manual env configuration per connector.

Legacy shared Claude client

The seeded claude-custom-connector client remains for backward compatibility when OAUTH_CLAUDE_CLIENT_SECRET is set in server config. New integrations should use per-user credentials from the dashboard instead.

Connect from Cursor

Native HTTP MCP (Cursor 0.4.7+):

{
"mcpServers": {
"hostless": {
"url": "https://mcp.hostless.app/mcp",
"headers": {
"Authorization": "hlk_a1b2c3d4_your_secret_here"
}
}
}
}

Or use mcp-remote:

{
"mcpServers": {
"hostless": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.hostless.app/mcp",
"--header",
"Authorization:${HOSTLESS_TOKEN}"
],
"env": {
"HOSTLESS_TOKEN": "hlk_a1b2c3d4_your_secret_here"
}
}
}
}

Replace HOSTLESS_TOKEN with your API key (hlk_...) or Bearer <jwt>. On Windows, omit spaces around the colon in --header (Authorization:${HOSTLESS_TOKEN}) if Cursor mangles spaced arguments.

Connect from Claude Desktop

Add a streamable HTTP server entry (Claude Desktop → Settings → Developer → MCP). Point the URL at https://mcp.hostless.app/mcp and set the Authorization header to your hlk_... token or Bearer JWT.

Exact UI labels vary by Claude Desktop version; the required values are the MCP URL and the same Authorization header as above.

Available tools

Tools mirror common platform operations. Names follow {resource}_{action}:

ResourceTools
Projectsprojects_list, projects_get, projects_create, projects_patch, projects_delete
Appsapps_list, apps_get, apps_create, apps_patch, apps_delete
Sitessites_list, sites_get, sites_create, sites_patch, sites_delete
Workersworkers_list, workers_get, workers_create, workers_patch, workers_delete
Cron jobscron_jobs_list, cron_jobs_get, cron_jobs_create, cron_jobs_patch, cron_jobs_delete
Databasesdatabases_list, databases_get, databases_create, databases_patch, databases_delete

Tips for agents

  • Call projects_list first, then pass projectId when listing or creating apps, sites, workers, cron jobs, or databases.
  • Apps, sites, workers, and cron jobs are identified by name, not MongoDB id.
  • Project create/update/delete requires a user JWT; API keys can only read projects (projects:read).
  • Use public documentation MCP (/mcp/docs) to look up guides without an API key.

MCP errors

StatusMeaning
401 UnauthorizedPOST /mcp only — missing or invalid Authorization header (POST /mcp/docs never returns 401)
405 Method Not AllowedGET /mcp or GET /mcp/docs — use POST for MCP requests
Tool isError: truePlatform API error (missing scope, not found, validation, etc.) — body includes the API error
Docs tool isError: truePage not found or invalid argument (e.g. empty query or path)

Key management API

These endpoints require a user JWT, not an API key. You can only create or revoke your own keys.

Create API key

POST /v1/users/me/api-keys

Request body

{
"name": "CI deploy",
"scopes": ["apps:read", "deployments:write"],
"expiresAt": "2026-12-31T23:59:59.000Z"
}
FieldTypeRequiredDescription
namestringyesLabel for the key (1–128 characters).
scopesstring[]yesOne or more scopes from the scope reference.
expiresAtstring (ISO 8601)noExpiry time. Omit or null for no expiry. Must be in the future.

Response 201

{
"token": "hlk_a1b2c3d4f8e7d6c5b4a39281726354849302ab1cd2ef3a4b5c6d7e8f9a0b1",
"apiKey": {
"id": "674a1b2c3d4e5f6789012345",
"name": "CI deploy",
"prefix": "hlk_a1b2c3d4",
"scopes": ["apps:read", "deployments:write"],
"expiresAt": "2026-12-31T23:59:59.000Z",
"lastUsedAt": null,
"createdAt": "2026-05-22T12:00:00.000Z"
}
}
FieldDescription
tokenFull secret. Returned only once. Store it securely; it cannot be retrieved later.
apiKey.prefixPublic identifier for lists (not the secret).
apiKey.idUse when revoking the key.

Example

curl -sS -X POST "$HOSTLESS_API/v1/users/me/api-keys" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "CI deploy",
"scopes": ["apps:read", "deployments:write"],
"expiresAt": null
}'

List API keys

GET /v1/users/me/api-keys

Response 200 — array of key metadata (no secrets):

[
{
"id": "674a1b2c3d4e5f6789012345",
"name": "CI deploy",
"prefix": "hlk_a1b2c3d4",
"scopes": ["apps:read", "deployments:write"],
"expiresAt": "2026-12-31T23:59:59.000Z",
"lastUsedAt": "2026-05-22T14:30:00.000Z",
"createdAt": "2026-05-22T12:00:00.000Z"
}
]

Revoke API key

DELETE /v1/users/me/api-keys/{keyId}

Response 200

{
"success": true
}

Revoked keys stop working immediately.

Using keys on platform APIs

Send Authorization: hlk_... on any endpoint below. The required scope is determined by HTTP method and path:

MethodTypical scope
GET, HEADresource:read (or deployments:read / logs:read when the path matches those segments)
POST, PUT, PATCHresource:write (or deployments:write / hostless-file:write)
DELETEresource:delete (integrations and billing use :write for DELETE)

Paths use {appName}, {siteName}, {workerName}, {cronJobName}, {databaseName}, {projectId}, {deploymentId}, and {id} as path parameters. Expand a scope to see every matching route.

With an API key, GET list routes return data from all projects you can access unless you pass ?projectId=. POST create routes require projectId in the JSON body.

API reference (by scope)

apps:read — List and get apps
MethodPath
GET/apps
GET/apps/{appName}
GET/apps/{appName}/search
GET/apps/{appName}/environment-variables
GET/apps/{appName}/custom-domains
GET/apps/{appName}/commits
GET/apps/{appName}/collaborators
GET/apps/{appName}/review-apps
GET/apps/{appName}/review-apps/pull-requests
GET/apps/{appName}/worker-processes
GET/apps/{appName}/worker-processes/{workerId}
GET/apps/{appName}/metrics/request-count
GET/apps/{appName}/metrics/response-duration
GET/apps/{appName}/metrics/cpu-usage
GET/apps/{appName}/metrics/memory-usage
apps:write — Create and update apps
MethodPath
POST/apps
PATCH/apps/{appName}
POST/apps/{appName}/restart
POST/apps/{appName}/custom-domains
PATCH/apps/{appName}/upgrade
PATCH/apps/{appName}/collaborators
POST/apps/{appName}/scale/down
POST/apps/{appName}/scale/up
POST/apps/{appName}/review-apps/trigger
PATCH/apps/{appName}/review-apps/extend
PATCH/apps/{appName}/worker-processes/{workerId}
POST/apps/{appName}/worker-processes
apps:delete — Delete apps
MethodPath
DELETE/apps/{appName}
DELETE/apps/{appName}/custom-domains
DELETE/apps/{appName}/collaborators/{email}
DELETE/apps/{appName}/worker-processes/{workerId}
sites:read — List and get sites
MethodPath
GET/sites
GET/sites/{siteName}
GET/sites/{siteName}/search
GET/sites/{siteName}/environment-variables
GET/sites/{siteName}/custom-domains
GET/sites/{siteName}/commits
GET/sites/{siteName}/review-sites
GET/sites/{siteName}/review-sites/pull-requests
GET/sites/{siteName}/visual-builder/project
GET/sites/{siteName}/visual-builder/assets
GET/sites/{siteName}/metrics/request-count
GET/sites/{siteName}/metrics/request-count/total
GET/sites/{siteName}/metrics/response-duration
GET/sites/{siteName}/metrics/bandwidth
GET/sites/{siteName}/metrics/unique-visitors
GET/sites/{siteName}/metrics/top-paths
GET/sites/{siteName}/metrics/cpu-usage
GET/sites/{siteName}/metrics/memory-usage
GET/sites/{siteName}/deployments/{siteDeploymentId}/metrics/build-stats
sites:write — Create and update sites
MethodPath
POST/sites
POST/sites/from-upload
POST/sites/from-visual-builder
PATCH/sites/{siteName}
POST/sites/{siteName}/restart
POST/sites/{siteName}/upload
POST/sites/{siteName}/custom-domains
POST/sites/{siteName}/scale/down
POST/sites/{siteName}/scale/up
POST/sites/{siteName}/review-sites/trigger
PUT/sites/{siteName}/visual-builder/project
POST/sites/{siteName}/visual-builder/publish
POST/sites/{siteName}/visual-builder/assets
sites:delete — Delete sites
MethodPath
DELETE/sites/{siteName}
DELETE/sites/{siteName}/custom-domains
workers:read — List and get workers
MethodPath
GET/workers
GET/workers/{workerName}
GET/workers/{workerName}/search
GET/workers/{workerName}/environment-variables
GET/workers/{workerName}/commits
GET/workers/{workerName}/collaborators
GET/workers/{workerName}/metrics/cpu-usage
GET/workers/{workerName}/metrics/memory-usage
workers:write — Create and update workers
MethodPath
POST/workers
PATCH/workers/{workerName}
POST/workers/{workerName}/restart
POST/workers/{workerName}/scale/down
POST/workers/{workerName}/scale/up
PATCH/workers/{workerName}/collaborators
workers:delete — Delete workers
MethodPath
DELETE/workers/{workerName}
DELETE/workers/{workerName}/collaborators/{email}
cron-jobs:read — List and get cron jobs (standalone and per-app)
MethodPath
GET/cron-jobs
GET/cron-jobs/{cronJobName}
GET/cron-jobs/{cronJobName}/search
GET/cron-jobs/{cronJobName}/environment-variables
GET/cron-jobs/{cronJobName}/commits
GET/cron-jobs/{cronJobName}/runs
GET/cron-jobs/{cronJobName}/runs/{runId}
GET/cron-jobs/{cronJobName}/metrics/cpu-usage
GET/cron-jobs/{cronJobName}/metrics/memory-usage
GET/apps/{appName}/cron-jobs
GET/apps/{appName}/cron-jobs/{jobId}
GET/apps/{appName}/cron-jobs/{jobId}/runs
GET/apps/{appName}/cron-jobs/{jobId}/runs/{runId}
cron-jobs:write — Create and update cron jobs
MethodPath
POST/cron-jobs
PATCH/cron-jobs/{cronJobName}
POST/cron-jobs/{cronJobName}/pause
POST/cron-jobs/{cronJobName}/resume
POST/apps/{appName}/cron-jobs
PATCH/apps/{appName}/cron-jobs/{jobId}
POST/apps/{appName}/cron-jobs/{jobId}/run
cron-jobs:delete — Delete cron jobs
MethodPath
DELETE/cron-jobs/{cronJobName}
DELETE/apps/{appName}/cron-jobs/{jobId}
deployments:read — List deployments and get deployment details

Applies when the path contains /deployments (except mutating routes below).

MethodPath
GET/apps/{appName}/deployments
GET/apps/{appName}/deployments/{deploymentId}
GET/apps/{appName}/deployments/{deploymentId}/stats
GET/apps/{appName}/build/stats
GET/sites/{siteName}/deployments
GET/sites/{siteName}/deployments/{deploymentId}
GET/workers/{workerName}/deployments
GET/workers/{workerName}/deployments/{deploymentId}
GET/cron-jobs/{cronJobName}/deployments
GET/cron-jobs/{cronJobName}/deployments/{deploymentId}
deployments:write — Trigger, rerun, or create deployments
MethodPath
POST/apps/{appName}/deployments/new
POST/apps/{appName}/deployments/{deploymentId}/rerun
POST/sites/{siteName}/deployments/new
POST/sites/{siteName}/deployments/{deploymentId}/rerun
POST/workers/{workerName}/deployments/new
POST/workers/{workerName}/deployments/{deploymentId}/rerun
POST/cron-jobs/{cronJobName}/deployments/new
POST/cron-jobs/{cronJobName}/deployments/{deploymentId}/rerun
logs:read — Runtime, deployment, build, and run logs

Applies when the path contains /logs, /post-build-logs, or /runtime-logs.

MethodPath
GET/apps/{appName}/logs
GET/apps/{appName}/deployments/{deploymentId}/logs
GET/apps/{appName}/deployments/{deploymentId}/post-build-logs
GET/sites/{siteName}/logs
GET/sites/{siteName}/deployments/{deploymentId}/logs
GET/workers/{workerName}/logs
GET/workers/{workerName}/deployments/{deploymentId}/logs
GET/cron-jobs/{cronJobName}/logs
GET/cron-jobs/{cronJobName}/deployments/{deploymentId}/logs
GET/cron-jobs/{cronJobName}/runs/{runId}/logs
GET/apps/{appName}/cron-jobs/{jobId}/runs/{runId}/logs
GET/databases/{databaseName}/import/{cloneId}/logs
databases:read — List and get databases
MethodPath
GET/databases
GET/databases/{databaseName}/search
GET/databases/{databaseName}/details
GET/databases/{databaseName}/linked-apps
GET/databases/{databaseName}/import/{cloneId}/status
databases:write — Create and update databases
MethodPath
POST/databases
PATCH/databases/{databaseName}
PATCH/databases/{databaseName}/tier
POST/databases/{databaseName}/pause
POST/databases/{databaseName}/unpause
POST/databases/{databaseName}/import
databases:delete — Delete databases
MethodPath
DELETE/databases/{databaseName}
integrations:read — Discover and list integrations
MethodPath
GET/integrations/available
GET/projects/{projectId}/integrations
integrations:write — Configure project integrations
MethodPath
POST/projects/{projectId}/integrations/slack
PUT/projects/{projectId}/integrations/slack
DELETE/projects/{projectId}/integrations/slack
POST/projects/{projectId}/integrations/slack/test
projects:read — Get project metadata

Only GET / HEAD on /projects paths (except git, integrations, and members routes).

MethodPath
GET/projects
GET/projects/{projectId}
GET/projects/{projectId}/apps
GET/projects/{projectId}/connected-accounts
git:read — Read project Git provider connections
MethodPath
GET/projects/{projectId}/github/accounts
GET/projects/{projectId}/github/accounts/{accountLogin}/repos
GET/projects/{projectId}/gitlab/repos
GET/projects/{projectId}/bitbucket/workspaces
GET/projects/{projectId}/bitbucket/workspaces/{workspace}/repos
git:write — Connect or disconnect Git accounts
MethodPath
DELETE/projects/{projectId}/github/disconnect
DELETE/projects/{projectId}/gitlab/disconnect
DELETE/projects/{projectId}/bitbucket/disconnect
traces:read — App traces
MethodPath
GET/traces/{appName}
hostless-file:read — Cost estimation from a Hostless file
MethodPath
POST/estimate-costs
hostless-file:write — Generate, update, or commit Hostless file config
MethodPath
POST/apps/{appName}/hostless-file/generate
POST/apps/{appName}/hostless-file/update
POST/apps/{appName}/hostless-file/commit
POST/apps/{appName}/hostless-file/calculate-costs
virtual-machines:read — List and get VMs
MethodPath
GET/virtual-machines
GET/virtual-machines/pricing
GET/virtual-machines/project/{projectId}
GET/virtual-machines/{id}
GET/virtual-machines/{id}/metrics
GET/virtual-machines/{id}/metrics/cpu-usage
GET/virtual-machines/{id}/metrics/memory-usage
GET/virtual-machines/{id}/metrics/network-in
GET/virtual-machines/{id}/metrics/network-out
GET/virtual-machines/{id}/metrics/disk-usage
GET/virtual-machines/{id}/firewall
virtual-machines:write — Create and manage VMs
MethodPath
POST/virtual-machines
POST/virtual-machines/{id}/start
POST/virtual-machines/{id}/stop
POST/virtual-machines/{id}/restart
PUT/virtual-machines/{id}/resources
PUT/virtual-machines/{id}/firewall
virtual-machines:delete — Delete VMs
MethodPath
DELETE/virtual-machines/{id}
billing:read — Usage, cycles, and invoices (account-wide)
MethodPath
GET/billing/breakdown
GET/billing/databases/breakdown
GET/billing/cycles
GET/billing/currencies
GET/billing/payment-config
GET/invoices
GET/invoices/{id}
GET/invoices/{id}/receipt
billing:write — Pay a project invoice
MethodPath
POST/billing/pay/{invoiceId}
metrics:read — Standalone metrics routes

No customer routes are mounted at /metrics today. App, site, worker, and cron job metrics use each resource's :read scope (for example apps:read on GET /apps/{appName}/metrics/...). This scope is reserved for future /metrics endpoints.

Not available with API keys

These routes require a user JWT (dashboard session), not an API key:

  • Key management: /users/me/api-keys
  • Account auth and profile: /auth, /users (except your own key routes above)
  • Project members and transfers: /projects/{projectId}/members, PATCH /projects/{projectId}, DELETE /projects/{projectId}, resource transfers
  • Payment methods and currency: /billing/stripe/*, /billing/paystack/*, PATCH /billing/currency/*, GET /billing/currencies/{currencyCode}
  • Admin, SSH keys, health, campaigns, credit, and standalone /github, /gitlab, /bitbucket OAuth callbacks

Example: trigger a deployment

curl -sS -X POST \
-H "Authorization: $HOSTLESS_TOKEN" \
-H "Content-Type: application/json" \
"$HOSTLESS_API/v1/apps/my-app/deployments/new" \
-d '{}'

Requires deployments:write (and project role owner/editor if your user is a viewer).

Example: read billing breakdown

curl -sS \
-H "Authorization: $HOSTLESS_TOKEN" \
"$HOSTLESS_API/v1/billing/breakdown?startDate=2026-05-01&endDate=2026-05-31"

Requires billing:read. Returns usage across all projects you can access.

Scope reference

Scopes use the format resource:action.

ScopeDescription
Apps
apps:readList and get apps
apps:writeCreate and update apps
apps:deleteDelete apps
Sites
sites:readList and get sites
sites:writeCreate and update sites
sites:deleteDelete sites
Workers
workers:readList and get workers
workers:writeCreate and update workers
workers:deleteDelete workers
Cron jobs
cron-jobs:readList and get cron jobs
cron-jobs:writeCreate and update cron jobs
cron-jobs:deleteDelete cron jobs
Deployments
deployments:readList deployments, get deployment details
deployments:writeTrigger, rerun, or create deployments
Logs
logs:readDeployment logs, post-build logs, runtime logs
Databases
databases:readList and get databases
databases:writeCreate and update databases
databases:deleteDelete databases
Integrations
integrations:readList project integrations
integrations:writeConfigure or update integrations
Project
projects:readGet project and list project apps
git:readRead project git account connections
git:writeConnect or disconnect project git accounts
Observability
metrics:readApp/site/worker metrics endpoints
traces:readApp trace endpoints
Hostless file
hostless-file:readRead or estimate from hostless file config
hostless-file:writeUpdate hostless file config
Virtual machines
virtual-machines:readList and get VMs
virtual-machines:writeCreate and update VMs
virtual-machines:deleteDelete VMs
Billing
billing:readUsage breakdown, cycles, invoices (account-wide)
billing:writePay an invoice

Authorization rules

Access is the intersection of:

  1. Valid API key — not revoked, not expired, correct secret.
  2. Scopes — the key includes every scope required for the route.
  3. Project role — the key creator's membership role still applies. For example, a project viewer cannot perform POST/PUT/PATCH/DELETE even if the key has write scopes.
  4. App collaborators — existing app-level collaborator checks still apply.

Scopes are a ceiling, not an elevation: they cannot bypass role or collaborator rules.

Errors

StatusMeaning
401 UnauthorizedMissing/invalid token, expired key, or wrong secret.
403 ForbiddenMissing scope, viewer blocked on mutation, wrong project resource, or JWT-only route called with an API key.
404 Not FoundProject or resource not found (or not in a project you can access).

Example scope error:

{
"statusCode": 403,
"message": "Missing required scope(s): deployments:write",
"error": "Forbidden"
}