Skip to main content

AppBlocks Cloud HTTP API

The AppBlocks Cloud backend exposes a REST-style HTTP API. It is the same API the AppBlocks web application uses, so anything you can do in the UI can also be automated.

Base URL

EnvironmentBase URL
Productionhttps://api.appblocks.io
Self-hostedvalue of the server's API_URL environment variable

All paths in this reference are relative to the base URL.

Route prefixes

The API is split across a few prefixes that reflect the subsystem behind them:

PrefixContents
/api/workspacesWorkspaces, members, invites, variables, tenants, audit logs
/cgg/devicesDevices, variables, tables, commands, firmware, logs, metrics
/cgg/public/devicesRead-only access to devices with a public dashboard
/cgg/groupsDevice groups

Authentication

Programmatic access uses API keys. A key is a personal credential: it authenticates as the user who created it, so every workspace, tenant and device permission that applies to that user applies to the key as well.

Creating a key

In the web app, go to Settings → API Keys (/settings/api-keys), give the key a name, choose its scopes and an optional expiry. The secret is shown once, at creation time — only its SHA-256 hash is stored, so it cannot be retrieved again. The same thing can be done over HTTP with POST /api/account/api-keys.

Keys look like abk_ followed by 32 random bytes:

abk_1a2B3c4D5e6F7g8H9i0JkLmNoPqRsTuVwXyZ...

Using a key

Send it in the x-api-key header, or as a bearer token:

curl -H 'x-api-key: abk_…' https://api.appblocks.io/cgg/devices?count=20

# equivalent
curl -H 'Authorization: Bearer abk_…' https://api.appblocks.io/cgg/devices?count=20
const res = await fetch('https://api.appblocks.io/cgg/devices?count=20', {
headers: { 'x-api-key': process.env.APPBLOCKS_API_KEY },
});
const { count, data } = await res.json();

GET /api/me is the cheapest way to check that a key works and see what it is allowed to do:

{
"id": "8a3f1c2d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"email": "me@example.com",
"auth": "apiKey",
"apiKey": { "id": "664e…", "name": "CI deploy", "scopes": ["read", "write"] }
}

Scopes

ScopeAllows
readGET, HEAD and OPTIONS requests. Always present.
writeEverything else — POST, PUT, PATCH, DELETE

A key without the write scope that attempts a modifying request is rejected with 403 {"message":"This API key does not have the write scope"}.

Limits and revocation

  • A key may be given an expiry of 1–365 days, or no expiry at all.
  • Each user may hold up to 25 active keys.
  • Revoking a key takes effect immediately; a revoked or expired key returns 401 {"message":"Invalid or expired API key"}.
  • lastUsedAt is refreshed at most once a minute, so it shows recent use rather than the exact time of the last request.
Account endpoints are session-only

Everything under /api/account — profile, password and API key management itself — rejects key authentication with 403 {"message":"This endpoint requires a signed-in session, not an API key"}. A key can therefore never change the account's credentials or mint further keys.

const res = await fetch('https://api.appblocks.io/cgg/devices?count=20', {
credentials: 'include',
});

CORS reflects the requesting origin and allows credentials, so a browser client on any origin can talk to the API once a session exists. Every endpoint accepts either authentication method, except the account routes noted above.

Endpoints that require no authentication

A handful of routes are intentionally public:

  • GET /api/projects/examples, /examples/categories, /examples/:id
  • POST /api/projects/code, /download, /save, /blockgen, /build
  • GET /api/projects/:id/versions/:versionCode/firmware/:filename (device OTA download)
  • GET /cgg/public/devices/... (devices with publicDashboard: true)
  • ALL /cgg/webhooks/:id (workflow webhook triggers)
  • GET /api/invites/:token, POST /api/invites/:token/accept
  • POST /api/chatwoot/webhook, GET /api/chatwoot/status, GET /api/copilotkit/status
  • GET /api/tibbits/docs/:model

Everything else returns 401 unauthorized (plain text) when neither an API key nor a valid session cookie is present.

Devices do not use this API

Deployed devices talk to the cloud over MQTT, authenticating with their deviceId and device key. The only HTTP endpoint devices use is the OTA firmware download URL stored on a project version.

Common conventions

Pagination

List endpoints accept start (offset, default 0) and count (page size). The default page size is 10 for most collections, 20 for logs, metrics and extensions. Results are sorted by updatedAt descending unless noted.

The response envelope is:

{
"count": 137,
"data": [ /* … */ ]
}

count is the total number of matching documents, not the number returned.

caution

Audit logs use limit/skip instead of count/start, and return { logs, total, deviceNames }. Workflow runs clamp count to a maximum of 100.

Where supported, search=<text> filters by name using a case-insensitive regular expression. Device and workspace log endpoints apply search to the log message instead.

Field filters

Collection endpoints for devices, projects, device logs and metrics accept ad-hoc filters encoded in the query string as <field>___<operator>=<value>:

Operator suffixMeaning
___eqequals
___nenot equal
___gtgreater than
___ltless than
___gtegreater than or equal
___lteless than or equal

For example, only connected devices:

GET /cgg/devices?state.connected___eq=true&count=50

An empty value is treated as null, which is useful for "field is not set" queries.

Time ranges

Log and metric endpoints accept startTime and endTime as any Date-parseable string (ISO 8601 is recommended). When omitted, endTime defaults to now and startTime to 24 hours earlier.

Workspace and tenant scoping

Most collections exist either in a user's personal space or inside a workspace:

  • Without workspace, the endpoint returns the caller's personal items — documents with no workspace.
  • With workspace=<workspaceId>, it returns that workspace's items, after verifying the caller has access.
  • Adding tenant=<tenantId> narrows the result to a tenant. For devices, groups, logs and metrics, passing workspace without tenant returns only the items that are not assigned to a tenant.

Error responses

StatusMeaning
400Missing/invalid input, or the referenced object is not visible to the caller
401No valid credentials (unauthorized as plain text, {"error":"Unauthorized"}, or {"message":"Invalid or expired API key"})
403Authenticated but the role or the key's scope is insufficient ({"message":"…"})
404Object does not exist
500Server error (error as plain text, or {"message":"…"})
503An optional integration (AI, Chatwoot) is not configured

Error bodies are not fully consistent: newer routes return { "message": "…" } or { "error": "…" }, while older ones send an empty body with the status code. Treat any non-2xx status as a failure and do not depend on a body being present.

Roles and permissions

Two independent membership models control access to workspace content.

Workspace roles

RoleCapabilities
ownerEverything, including deleting the workspace. Set at creation time.
adminManage members, invites, variables and all workspace content
operatorRead-only on devices and groups; may edit projects
memberRead and edit workspace content (devices, dashboards, workflows, projects)

Attempting a write as an operator returns 403 {"message":"Operators have read-only access"}.

Tenant roles

Tenants are sub-organizations inside a workspace, used to segment devices and users for end customers.

RoleCapabilities
adminManage tenant users, invites and variables; add devices/groups to the tenant
memberRead the tenant's devices and dashboards

A user who belongs only to a tenant (a tenant-only member) sees the workspace in a reduced form: member list, workspace variables and tenant variable templates are stripped, and isTenantOnlyMember: true is returned. Tenant-only members without the tenant admin role cannot write device state variables or tables, and cannot edit dashboards, SCADA screens, workflows or projects.

Workspace owner and operator roles have implicit access to every tenant in the workspace.

Reference sections

  • Devices — devices, variables, tables, commands, firmware, logs, metrics
  • Device Groups — grouping devices and pushing shared configuration
  • Workspaces & Tenants — workspaces, members, invites, variables, tenants, audit logs