API Overview
Authentication, scopes, conventions and errors for the Cloady REST API.
Everything you can do in the dashboard, you can do over HTTP: workspaces, applications, deploys, domains, vars, members. It is the same API the dashboard itself calls.
Base URL
https://cloady.com/apiAll requests and responses are application/json. Send Content-Type: application/json on any request with a body.
Authentication
Authenticate with a personal API token. Pass it as a bearer token:
Authorization: Bearer cldy_...A token acts as you: it reaches the workspaces you belong to, with your role in each. The secret is shown once, at creation, and cannot be retrieved afterwards — if you lose it, revoke it and create a new one.
A token can carry an expiry (never, 30d, 90d, 1y) and can be
revoked at any time. A missing, malformed, expired, or revoked token gets
401 unauthorized.
A token can also be pinned to one workspace. Requests to any other workspace
then return 403 forbidden, whatever your role there.
Your account must have a verified phone number; without one every
authenticated endpoint returns 403 phone_required. Verify it once under
Account → Security in the dashboard.
Create a token
From the dashboard: Account → API tokens (see the Dashboard
Guide). Pick a name, a scope and an expiry — the
secret is displayed once, so copy it immediately. Minting a token itself needs
full scope or a signed-in browser session.
Token scopes
Every token is minted with one scope that bounds what it can do:
read— read-only. List and inspect workspaces, applications, deploys, logs. No changes.deploy— everythingreadcan do, plus deploy, redeploy, start, stop and restart.full— unrestricted. Everythingdeploycan do, plus destructive and administrative actions: deleting an application (which permanently deletes its data), managing domains and vars, managing members and billing.
Pick the narrowest scope that covers your use case — a CI deploy key wants
deploy, not full.
Workspace roles
Scope bounds the token; your role in the workspace bounds the request. Workspace endpoints require a minimum role, ranked lowest to highest:
viewer— read the workspace and its applications.developer— deploy and operate applications: deploy, restart, logs, shell, database.admin— manage domains, vars and members.owner— everything, including billing and deleting the workspace.
A request below the endpoint's minimum role returns 403 forbidden. A workspace
you aren't a member of returns 404 not_found — membership is never disclosed.
Env + region query convention
Each application runs in one region and one environment — production,
preview or development — and its name is unique within a workspace and
environment. Dashboard URLs carry region and environment as path segments, but
API requests carry them as query params:
?env=<production|preview|development>®ion=<regionId>envdefaults toproductionwhen omitted.regionis optional and rarely needed. Pass it only when the same name exists in more than one region: those requests return400 region_required, and you retry with?region=.
GET /api/workspaces/acme/apps/my-blog?env=production®ion=hil1Region ids come from GET /api/regions. A workspace with a plan can deploy to
any of them; the region is chosen when you deploy the application.
Applications and workspaces are addressed by name in these paths, and an application's public address follows its name too — so renaming changes both the URL you call and the URL your app is served on. Update any scripts that reference the old name. Renaming is still the safe move: deleting an application permanently deletes its data.
Streaming endpoints
App status, metrics, deploy progress, deploy logs and ticket messages stream
server-sent events. Send Accept: text/event-stream for the live stream;
without that header you get the current state once, as ordinary JSON, which
is what a script wants. Service logs do the same, answering a plain request with
the last 200 lines.
Error shape
Errors carry a machine-readable code. Two shapes are in use:
{ "error": { "code": "not_found", "message": "App my-blog not found" } }{ "error": "This needs more resources than the free allowance covers. Add a payment method in workspace billing.", "code": "payment_required" }Read the code as body.code ?? body.error.code and branch on that, never on
the message or the status alone. Validation failures (bad_body) add a
details array naming the fields that were wrong.
| Status | Typical code | Meaning |
|---|---|---|
400 | bad_body, missing_input, bad_reference, bad_region | Malformed body, missing field, or a name/region that doesn't exist |
400 | region_required | The name matches applications in more than one region — retry with ?region= |
401 | unauthorized | Missing, expired or revoked token |
403 | forbidden | Role too low, token scope too low, or token pinned to another workspace |
403 | phone_required | The account has no verified phone number |
402 | payment_required | The change would take the workspace past its free allowance and there is no card on file, or the card was declined |
402 | payment_failed, no_payment_method | The card was declined, or there is no card to charge |
404 | not_found | Workspace or application not found |
503 | billing_misconfigured | Billing is unavailable |
Example
List your workspaces:
curl https://cloady.com/api/workspaces \
-H "Authorization: Bearer cldy_..."{
"workspaces": [ /* ... */ ],
"regions": [ /* ... */ ],
"tiers": [ /* ... */ ]
}For the full endpoint catalog — paths, methods, params, and bodies — see the endpoint reference.