Appbricx
Docs
FeaturesPricingStart free

Get started

OverviewWhat Appbricx isQuickstart with a coding agentQuickstart with the builderCore concepts

Guides

Data and tablesAccess and rolesBusiness rulesSign-inCustom screensRealtime and topicsWorkflows, schedules and webhooksServer functionsAI in your appPaymentsFilesMessagesIntegrationsVerifyPublishing, domains and rollbackOperating your appExport and self-hostSelf-host install

Tutorials

Build a booking app with Claude CodeMulti-user todo listClient portalSlack on new sign-upTemplates

Reference

Reference homeFrontend SDKHTTP APIMCP toolsCLIIntegrations catalogContract formatAI key resolutionRun Appbricx locally

Developer API

The HTTP door the CLI, the MCP server and CI use: tokens, projects, the contract loop (check, apply, patch, verify, deploy) and operating the running app (SQL, rows, schema, snapshots, deploys, runs, tail, secrets).

38 endpointsHTTP API referenceGuide: Automate with the HTTP API

On this page
  1. Authentication
  2. Endpoints
  3. POST /tokens
  4. GET /tokens
  5. DELETE /tokens/:tokenId
  6. GET /me
  7. GET /docs
  8. POST /components/check
  9. GET /projects
  10. POST /projects
  11. GET /projects/:id
  12. GET /projects/:id/contract
  13. POST /projects/:id/check
  14. POST /projects/:id/apply
  15. POST /projects/:id/patch
  16. POST /projects/:id/screenshot
  17. POST /projects/:id/verify
  18. POST /projects/:id/data/query
  19. GET /projects/:id/logs
  20. POST /projects/:id/deploy
  21. GET /projects/:id/demo-reset
  22. POST /projects/:id/demo-reset
  23. GET /projects/:id/sign-in
  24. POST /projects/:id/sign-in
  25. POST /projects/:id/sql
  26. POST /projects/:id/rows
  27. GET /projects/:id/schema
  28. GET /projects/:id/snapshots
  29. POST /projects/:id/snapshots
  30. POST /projects/:id/snapshots/:snapshotId/restore
  31. GET /projects/:id/deploys
  32. POST /projects/:id/deploys/:deploymentId/rollback
  33. POST /projects/:id/workflows/:workflowId/run
  34. GET /projects/:id/runs/:runId
  35. GET /projects/:id/dead-letters
  36. POST /projects/:id/dead-letters/replay
  37. GET /projects/:id/tail
  38. GET /projects/:id/secrets
  39. PUT /projects/:id/secrets/:name
  40. DELETE /projects/:id/secrets/:name

Base URL: https://appbricx.com/api/dev/v1 (self-hosted: <your API>/dev/v1). Errors answer { error, code? } with the HTTP status. The MCP tools and the CLI call the same operations and get the same answers.

Authentication

Builder session only
The signed-in builder session. A personal access token can't mint another token. Authorization: Bearer $SESSION_JWT
Developer token
A personal access token (apx_pat_…, one workspace, scopes read / apply / deploy), the CLI's browser sign-in token, or the builder session. A project outside the token's reach answers 404, never 403. Authorization: Bearer $APPBRICX_TOKEN

Endpoints

Mint a token

POST/api/dev/v1/tokens

Create a personal access token for one workspace. The token is shown once.

Auth
Builder session only: Authorization: Bearer $SESSION_JWT
Scope: builder session

Body

NameTypeDescription
namerequiredstring1 to 80 characters.
workspaceIdrequireduuidThe workspace it reaches.
scopesoptionalArray<"read" | "apply" | "deploy">Default ["read", "apply"].
expiresInDaysoptionalnumber1 to 366; omitted, it doesn't expire.

Response

201 Created.

Response
{
  "token": "apx_pat_…",
  "id": "t_1",
  "name": "ci",
  "workspaceId": "6a1f…",
  "scopes": [
    "read",
    "apply",
    "deploy"
  ],
  "expiresAt": "2027-01-10T00:00:00Z",
  "createdAt": "…",
  "note": "Shown once — store it now. Revoke with DELETE /dev/v1/tokens/:id."
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
403SESSION_REQUIREDCalled with a token, not a session.
400BAD_REQUEST"Validation failed" with details per field.
400INVALID_SCOPEUnknown scope, or a viewer asking for more than read.
404none"Workspace not found".
curl
curl -X POST "https://appbricx.com/api/dev/v1/tokens" \
  -H "Authorization: Bearer $SESSION_JWT" \
  -H "content-type: application/json" \
  -d '{"name":"ci","workspaceId":"6a1f…","scopes":["read","apply","deploy"],"expiresInDays":90}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/tokens", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${SESSION_JWT}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "name": "ci",
    "workspaceId": "6a1f…",
    "scopes": [
      "read",
      "apply",
      "deploy"
    ],
    "expiresInDays": 90
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:61

List my tokens

GET/api/dev/v1/tokens

Your unrevoked personal access tokens (prefix only, never the token).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Response

Response
{
  "tokens": [
    {
      "id": "t_1",
      "name": "ci",
      "workspace_id": "6a1f…",
      "token_prefix": "apx_pat_Ab12Cd",
      "scopes": [
        "read",
        "apply"
      ],
      "expires_at": null,
      "last_used_at": "…",
      "created_at": "…"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
curl
curl "https://appbricx.com/api/dev/v1/tokens" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/tokens", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:62

Revoke a token

DELETE/api/dev/v1/tokens/:tokenId

Revoke one of your tokens. It stops working at once.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any (own tokens)

Path parameters

NameTypeDescription
:tokenIdrequiredstringThe token id.

Response

Response
{
  "revoked": "0b6e…"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Token not found".
curl
curl -X DELETE "https://appbricx.com/api/dev/v1/tokens/0b6e…" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/tokens/0b6e…", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:63

Who am I

GET/api/dev/v1/me

The signed-in user, the credential kind, its scopes and workspaces.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Response

Response
{
  "userId": "u_1",
  "email": "dev@example.com",
  "auth": "pat",
  "scopes": [
    "read",
    "apply"
  ],
  "workspaces": [
    {
      "id": "6a1f…",
      "name": "Acme",
      "role": "owner"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
curl
curl "https://appbricx.com/api/dev/v1/me" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/me", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP whoamiappbricx whoami

Source: services/api/src/routes/dev-api/index.ts:65

Agent guide

GET/api/dev/v1/docs

The contract guide for authors, as markdown.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Response

text/markdown.

Response
# appbricx contract guide

Loop: get_contract → edit → check_contract …

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
curl
curl "https://appbricx.com/api/dev/v1/docs" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/docs", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const text = await res.text();

RelatedMCP get_guideappbricx docs

Source: services/api/src/routes/dev-api/index.ts:66

Check a custom component

POST/api/dev/v1/components/check

Run one custom code component through every gate (import allowlist, strict TypeScript against the kit, compile, sandboxed server render with the sample props and with empty props). No project needed, nothing saved.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Body

NameTypeDescription
namerequiredstringPascalCase; the default export must use it.
sourcerequiredstringThe whole TSX file (200,000 chars max).
sampleoptionalobjectProps for the render gate.

Response

A failing gate: { ok: false, stage, errors }.

Response
{
  "ok": true,
  "passed": [
    "static",
    "types",
    "compile",
    "render"
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
400BAD_REQUEST"Validation failed" with details per field.
curl
curl -X POST "https://appbricx.com/api/dev/v1/components/check" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"name":"WeekHeatmap","source":"import type { AppHandle } from \"@app/kit/primitives\";\nexport default function WeekHeatmap({ app }: { app?: AppHandle }) { return null; }","sample":{}}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/components/check", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "name": "WeekHeatmap",
    "source": "import type { AppHandle } from \"@app/kit/primitives\";\nexport default function WeekHeatmap({ app }: { app?: AppHandle }) { return null; }",
    "sample": {}
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP check_component

Source: services/api/src/routes/dev-api/index.ts:68

List projects

GET/api/dev/v1/projects

Projects this credential can reach, newest first (200 max).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Response

Response
{
  "projects": [
    {
      "id": "3b7e…",
      "name": "Tablefor",
      "slug": "tablefor",
      "workspace_id": "6a1f…",
      "updated_at": "…"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
curl
curl "https://appbricx.com/api/dev/v1/projects" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP list_projectsappbricx projects

Source: services/api/src/routes/dev-api/index.ts:69

Create a project

POST/api/dev/v1/projects

Create an empty project. Then apply a contract to build it.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply

Body

NameTypeDescription
namerequiredstring1 to 100 characters.
workspaceIdoptionaluuidRequired for a session; a token is pinned to its workspace.
descriptionoptionalstringUp to 2000 characters.

Response

201 Created.

Response
{
  "project": {
    "id": "3b7e…",
    "name": "Tablefor",
    "slug": "tablefor",
    "workspaceId": "6a1f…"
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
400BAD_REQUEST"Validation failed" with details per field.
404none"Workspace not found".
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"name":"Tablefor"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "name": "Tablefor"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP create_projectappbricx create

Source: services/api/src/routes/dev-api/index.ts:70

Project state

GET/api/dev/v1/projects/:id

Whether the project has been built, the last build failure if any, and its preview path.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "project": {
    "id": "3b7e…",
    "name": "Tablefor",
    "workspaceId": "6a1f…",
    "role": "owner"
  },
  "state": {
    "built": true,
    "lastError": null
  },
  "previewPath": "/preview/3b7e…/"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP get_projectappbricx link

Source: services/api/src/routes/dev-api/index.ts:71

Get the contract

GET/api/dev/v1/projects/:id/contract

The project's current contract (null before the first apply). Seeds come back as "UNCHANGED": rows live in the database.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "contract": {
    "app": {
      "name": "Tablefor"
    },
    "personas": [
      {
        "id": "staff",
        "kind": "staff"
      }
    ],
    "entities": [
      {
        "name": "bookings",
        "fields": [
          {
            "name": "date",
            "type": "date"
          }
        ]
      }
    ],
    "seeds": "UNCHANGED"
  },
  "built": true
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/contract" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/contract", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP get_contractappbricx pull

Source: services/api/src/routes/dev-api/index.ts:72

Check a contract

POST/api/dev/v1/projects/:id/check

Normalize a contract and report errors (must be empty to apply), fixes and warnings. No side effects.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
contractrequiredobjectThe full contract.

Response

Response
{
  "report": {
    "ok": true,
    "errors": [],
    "fixes": [
      "entities.tickets.fields.status: enum_values filled from seeds"
    ],
    "warnings": []
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
400none"contract is required".
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/check" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"contract":{"app":{"name":"Tablefor"},"personas":[],"entities":[]}}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/check", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "contract": {
      "app": {
        "name": "Tablefor"
      },
      "personas": [],
      "entities": []
    }
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP check_contractappbricx check

Source: services/api/src/routes/dev-api/index.ts:73

Apply a contract

POST/api/dev/v1/projects/:id/apply

Build the dev environment from a full contract: database created or evolved additively (rows kept), pages compiled, workflows armed.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
contractrequiredobjectThe full contract.
forceoptionalbooleanOverwrite hand-edited compiled files (backed up first).

Response

Response
{
  "report": {
    "ok": true,
    "errors": [],
    "fixes": [
      "entities.tickets.fields.status: enum_values filled from seeds"
    ],
    "warnings": []
  },
  "summary": "Built 4 tables, 9 pages, 2 workflows. Demo sign-ins: staff@demo.app / customer@demo.app",
  "warnings": []
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
400none"contract is required".
422CONTRACT_INVALIDThe report has errors.
409PROJECT_BUSYAnother build is running (retry).
409HAND_EDITED_FILESCompiled files were edited by hand; re-run with force.
500BUILD_FAILEDThe build failed at stage.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/apply" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"contract":{"app":{"name":"Tablefor"}},"force":false}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/apply", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "contract": {
      "app": {
        "name": "Tablefor"
      }
    },
    "force": false
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP apply_contractappbricx apply

Source: services/api/src/routes/dev-api/index.ts:74

Patch the contract

POST/api/dev/v1/projects/:id/patch

Apply typed edit ops (add_entity, adopt_table, add_field, update_field, remove_field, set_workflow, add_page, set_component, edit_component, set_app…) to the current contract, then rebuild. adopt_table turns a table you made by hand with SQL into a contract entity: columns are read from the dev database and its rows are kept.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
editsrequiredobject[]1 to 50 ops, each { op, ... }.
dryRunoptionalbooleanReport only.
forceoptionalbooleanOverwrite hand-edited files.

Response

Response
{
  "report": {
    "ok": true,
    "errors": [],
    "fixes": [
      "entities.tickets.fields.status: enum_values filled from seeds"
    ],
    "warnings": []
  },
  "summary": "Would add bookings.party_size"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
422CONTRACT_INVALIDThe result is invalid.
409PROJECT_BUSYBusy.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/patch" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"edits":[{"op":"add_field","entity":"bookings","field":{"name":"party_size","type":"number"}}],"dryRun":true}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/patch", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "edits": [
      {
        "op": "add_field",
        "entity": "bookings",
        "field": {
          "name": "party_size",
          "type": "number"
        }
      }
    ],
    "dryRun": true
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP patch_contractappbricx patch

Source: services/api/src/routes/dev-api/index.ts:78

Screenshot the app

POST/api/dev/v1/projects/:id/screenshot

Open the dev preview in a real browser (390×844 by default), signed in as a demo role or as a guest, and return the PNG plus page errors, horizontal overflow and the visible text. ?format=png answers the image itself.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
formatoptional"png"Answer image/png instead of JSON.

Body

NameTypeDescription
routeoptionalstringApp route like /people.
asoptionalstringPersona id, demo login email, or "guest".
widthoptionalnumber320 to 1600.
heightoptionalnumber480 to 1200.
fullPageoptionalbooleanThe whole scrollable page.

Response

Response
{
  "png": "iVBORw0KGgo…",
  "route": "/bookings",
  "as": "staff",
  "errors": [],
  "overflowX": 0,
  "text": "Bookings · Today · 3 tables free"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
400BAD_REQUESTInvalid route, size or persona.
409NOT_BUILTApply a contract first.
422SCREENSHOT_FAILEDThe browser couldn't capture the page.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/screenshot" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"route":"/bookings","as":"staff","width":390}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/screenshot", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "route": "/bookings",
    "as": "staff",
    "width": 390
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP screenshot

Source: services/api/src/routes/dev-api/index.ts:82

Verify

POST/api/dev/v1/projects/:id/verify

Run verify on the dev environment: static checks, data checks (demo sign-ins, role by table permission matrix with rolled-back writes, signed-out access, workflows armed) and a browser pass. Takes a few minutes.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "report": {
    "status": "pass",
    "stages": [
      {
        "name": "static",
        "status": "pass",
        "checks": []
      },
      {
        "name": "data",
        "status": "pass",
        "checks": []
      },
      {
        "name": "browser",
        "status": "pass",
        "checks": []
      }
    ]
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/verify" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/verify", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP verifyappbricx verify

Source: services/api/src/routes/dev-api/index.ts:88

Query dev rows

POST/api/dev/v1/projects/:id/data/query

Read rows from a table in the dev database (read-only, 200 max). Filters are equality.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
tablerequiredstringThe table (entity also accepted).
whereoptionalobjectColumn → value equality.
orderByoptionalstringDefault created_at.
descoptionalbooleanDefault true.
limitoptionalnumber1 to 200 (default 50).

Response

Response
{
  "table": "bookings",
  "rows": [
    {
      "id": "b_1",
      "status": "confirmed",
      "date": "2026-10-12"
    }
  ],
  "rowCount": 1
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
400BAD_REQUEST"Validation failed" with details per field.
409noneNo app yet: apply a contract first.
400BAD_QUERYUnknown table or column.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/data/query" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"table":"bookings","where":{"status":"confirmed"},"limit":10}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/data/query", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "table": "bookings",
    "where": {
      "status": "confirmed"
    },
    "limit": 10
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP query_dataappbricx query

Source: services/api/src/routes/dev-api/index.ts:89

Workflow logs

GET/api/dev/v1/projects/:id/logs

Recent workflow runs (status, error and their last 8 log lines) and in-app notifications.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: any

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
limitoptionalnumber1 to 200 (default 30).
workflowoptionalstringOnly this workflow's runs.

Response

Response
{
  "runs": [
    {
      "id": "4f0a…",
      "workflow_id": "send-invoice",
      "status": "failed",
      "error": "SMTP timeout",
      "log": [
        {
          "ts": "…",
          "level": "error",
          "message": "timeout"
        }
      ]
    }
  ],
  "notifications": []
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/logs?limit=10" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/logs?limit=10", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP logsappbricx logs

Source: services/api/src/routes/dev-api/index.ts:90

Deploy

POST/api/dev/v1/projects/:id/deploy

Publish to https://<subdomain>.<publish domain>. Runs verify first and refuses on red unless skipVerify. Takes a few minutes.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: deploy

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
environmentoptional"production" | "preview"Default production.
allowDestructiveoptionalbooleanConfirm destructive schema changes on promote.
skipVerifyoptionalbooleanPublish even when verify is red.
subdomainoptionalstringOne DNS label (up to 48 chars). Omitted, the project keeps its own.
demoResetoptionalbooleantrue resets published data to the preview's every night; false stops it.

Response

Response
{
  "deploymentId": "d_9",
  "url": "https://tablefor.apps.appbricx.com",
  "status": "live",
  "durationMs": 142000,
  "report": {
    "status": "pass"
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "deploy" scope.
400BAD_REQUEST"Validation failed" with details per field.
400INVALID_SUBDOMAINNot a valid label.
409SUBDOMAIN_TAKENAnother project has it.
422VERIFY_FAILEDVerify is red (report attached).
409none"A deployment is already in progress" (deploymentId attached).
500DEPLOY_FAILEDThe pipeline failed (buildLog tail attached).
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/deploy" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"subdomain":"tablefor"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/deploy", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "subdomain": "tablefor"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP deployappbricx deploy

Source: services/api/src/routes/dev-api/index.ts:92

Demo mode state

GET/api/dev/v1/projects/:id/demo-reset

Whether the published data is reset to the preview's every night.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: deploy

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "demoReset": {
    "enabled": true,
    "lastRunAt": "2026-10-12T03:00:00Z"
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "deploy" scope.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/demo-reset" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/demo-reset", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:93

Change demo mode

POST/api/dev/v1/projects/:id/demo-reset

Turn nightly demo resets on or off, or reset now.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: deploy

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
enabledoptionalbooleanTurn on or off.
runNowoptionalbooleanReset the published data now.

Response

500 when runNow failed.

Response
{
  "demoReset": {
    "enabled": true
  },
  "run": {
    "ok": true
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "deploy" scope.
400BAD_REQUEST"Validation failed" with details per field.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/demo-reset" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"enabled":true,"runNow":true}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/demo-reset", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "enabled": true,
    "runNow": true
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:94

Sign-in providers

GET/api/dev/v1/projects/:id/sign-in

Google and GitHub sign-in for the app and whether each is on.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "providers": [
    {
      "provider": "google",
      "enabled": true,
      "client": "platform"
    },
    {
      "provider": "github",
      "enabled": false
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/sign-in" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/sign-in", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP sign_in_providers

Source: services/api/src/routes/dev-api/index.ts:95

Change a sign-in provider

POST/api/dev/v1/projects/:id/sign-in

Turn a provider on or off. client "platform" uses Appbricx's own Google client (no Google Cloud setup); "own" takes your client id and secret (register https://<app host>/__appbricx/auth/oauth/<provider>/callback).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
providerrequired"google" | "github"The provider.
enabledrequiredbooleanOn or off.
clientoptional"platform" | "own"Whose OAuth client.
clientIdoptionalstringOwn client id.
clientSecretoptionalstringOwn client secret.

Response

Response
{
  "providers": [
    {
      "provider": "google",
      "enabled": true,
      "client": "platform"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
400BAD_REQUEST"Validation failed" with details per field.
400noneThe configuration isn't valid (e.g. own client without a secret).
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/sign-in" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"provider":"google","enabled":true,"client":"platform"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/sign-in", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "provider": "google",
    "enabled": true,
    "client": "platform"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP sign_in_providers

Source: services/api/src/routes/dev-api/index.ts:96

Run SQL

POST/api/dev/v1/projects/:id/sql

Run SQL like the builder's SQL editor: several statements in one transaction, DDL and DML, as the tenant admin (past row-level security). Read-only scripts run in a rolled-back transaction. A prod write takes a snapshot first.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read for read-only scripts; apply on dev, deploy on prod for writes

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
sqlrequiredstringOne or more statements (64 KB max).
envoptional"dev" | "prod"Which database: dev (the preview, default) or prod (the published app).

Response

Rows are the last statement that returned any (1000 max). Prod writes add snapshotId.

Response
{
  "rows": [
    {
      "count": "128"
    }
  ],
  "rowCount": 1,
  "truncated": false,
  "statements": [
    {
      "sql": "create index if not exists bookings_date on bookings(date)",
      "command": "CREATE",
      "rowCount": 0
    },
    {
      "sql": "select count(*) from bookings",
      "command": "SELECT",
      "rowCount": 1
    }
  ],
  "env": "dev",
  "readOnly": false,
  "durationMs": 41
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply / deploy" scope.
400BAD_REQUESTValidation failed or no statement.
400STMT_FORBIDDENReferences pg_catalog or information_schema (use schema).
400(SQL code)A statement failed; the whole script rolled back (rolledBack: true).
503SNAPSHOT_FAILEDCouldn't snapshot prod before the write; nothing changed.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/sql" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"sql":"create index if not exists bookings_date on bookings(date); select count(*) from bookings;","env":"dev"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/sql", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "sql": "create index if not exists bookings_date on bookings(date); select count(*) from bookings;",
    "env": "dev"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP sqlappbricx sql

Source: services/api/src/routes/dev-api/index.ts:100

Edit rows

POST/api/dev/v1/projects/:id/rows

Insert, update or delete rows through the app's own data API: access rules, before-write rules, lifecycle guards, row-level security and change events behave as in the app. as "admin" (default) writes elevated; as { role } acts as an app user with that role.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply on dev, deploy on prod

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
tablerequiredstringThe table.
envoptional"dev" | "prod"Which database: dev (the preview, default) or prod (the published app).
oprequired"insert" | "update" | "delete"What to do.
rowsoptionalobject[]insert: 1 to 100 rows.
idoptionalstring | numberupdate / delete: one id.
idsoptionalArray<string | number>update / delete: 1 to 100 ids.
patchoptionalobjectupdate: columns to set.
asoptional"admin" | { role, user_id? }Who acts (default admin).

Response

422 when every row failed. Per-row codes: RULE_REFUSED, E_LIFECYCLE_DIRECT_WRITE, NOT_FOUND, the stamp code.

Response
{
  "table": "bookings",
  "env": "dev",
  "op": "update",
  "as": {
    "role": "staff",
    "userId": "u_7"
  },
  "succeeded": 2,
  "failed": 0,
  "results": [
    {
      "ok": true,
      "id": "b_1",
      "row": {
        "id": "b_1",
        "status": "cancelled"
      }
    },
    {
      "ok": true,
      "id": "b_2",
      "row": {
        "id": "b_2",
        "status": "cancelled"
      }
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply / deploy" scope.
400BAD_REQUESTValidation failed.
409NO_PERSONANo app user holds that role in this env.
403TABLE_FORBIDDENThe role may not do this, or it's an internal table.
503SNAPSHOT_FAILEDProd snapshot failed; nothing changed.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/rows" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"table":"bookings","op":"update","ids":["b_1","b_2"],"patch":{"status":"cancelled"},"as":{"role":"staff"}}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/rows", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "table": "bookings",
    "op": "update",
    "ids": [
      "b_1",
      "b_2"
    ],
    "patch": {
      "status": "cancelled"
    },
    "as": {
      "role": "staff"
    }
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP edit_rowsappbricx rows

Source: services/api/src/routes/dev-api/index.ts:101

Describe the schema

GET/api/dev/v1/projects/:id/schema

The real schema: tables with columns, keys, constraints, indexes, triggers and policies; views, functions and enums. Each table's origin says whether the contract manages it, the platform made it, it's internal, or it was made by hand.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
envoptional"dev" | "prod"Which database: dev (the preview, default) or prod (the published app).

Response

Response
{
  "env": "prod",
  "tables": [
    {
      "name": "bookings",
      "origin": "contract",
      "columns": [
        {
          "name": "date",
          "type": "date",
          "nullable": false,
          "managedByContract": true
        }
      ],
      "indexes": [
        "bookings_date"
      ]
    }
  ],
  "views": [],
  "functions": [],
  "enums": []
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
409noneThe env's database doesn't exist yet (prod before the first publish).
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/schema?env=prod" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/schema?env=prod", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP describe_schemaappbricx schema

Source: services/api/src/routes/dev-api/index.ts:102

List snapshots

GET/api/dev/v1/projects/:id/snapshots

Database snapshots (pg_dump) of dev and prod. Every publish and every agent write on prod takes one.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
envoptional"dev" | "prod"Only this environment.

Response

Response
{
  "snapshots": [
    {
      "id": "prod-2026-10-12T09-00-00Z-a1b2",
      "env": "prod",
      "reason": "publish",
      "createdAt": "…",
      "bytes": 482113
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
503SNAPSHOTS_UNAVAILABLESnapshots aren't configured on this install.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots?env=prod" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots?env=prod", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP snapshotsappbricx snapshots

Source: services/api/src/routes/dev-api/index.ts:103

Take a snapshot

POST/api/dev/v1/projects/:id/snapshots

Take a snapshot now (default env prod).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
envoptional"dev" | "prod"Default prod.

Response

201 Created.

Response
{
  "snapshot": {
    "id": "prod-2026-10-12T09-30-00Z-c3d4",
    "env": "prod",
    "reason": "manual",
    "createdAt": "…",
    "bytes": 482990
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
500SNAPSHOT_FAILEDpg_dump failed.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"env":"prod"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "env": "prod"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:105

Restore a snapshot

POST/api/dev/v1/projects/:id/snapshots/:snapshotId/restore

Replace the whole database with a snapshot. The current state is snapshotted first (undoSnapshotId), so a restore can be undone.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: deploy

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:snapshotIdrequiredstringFrom the list, e.g. prod-…

Response

Response
{
  "restored": "prod-2026-10-12T09-00-00Z-a1b2",
  "env": "prod",
  "undoSnapshotId": "prod-2026-10-12T09-31-12Z-e5f6"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "deploy" scope.
404SNAPSHOT_NOT_FOUNDNo such snapshot.
500RESTORE_FAILEDThe restore failed.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots/prod-2026-10-12T09-00-00Z-a1b2/restore" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/snapshots/prod-2026-10-12T09-00-00Z-a1b2/restore", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:107

Deploy history

GET/api/dev/v1/projects/:id/deploys

The project's deployments: status, url, git sha and timing.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
environmentoptional"production" | "preview"Filter.
limitoptionalnumber1 to 100 (default 20).

Response

Response
{
  "deployments": [
    {
      "id": "d_9",
      "environment": "production",
      "status": "live",
      "url": "https://tablefor.apps.appbricx.com",
      "version_number": 12,
      "git_sha": "a1b2c3d",
      "build_time_ms": 81000,
      "created_at": "…"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/deploys?limit=5" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/deploys?limit=5", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP deploysappbricx deploys

Source: services/api/src/routes/dev-api/index.ts:109

Roll back

POST/api/dev/v1/projects/:id/deploys/:deploymentId/rollback

Switch what's live back to an earlier successful deployment (its stored build, else a rebuild of its git sha). Files only: roll the database back with snapshots.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: deploy

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:deploymentIdrequiredstringThe deployment to go back to.

Response

Response
{
  "data": {
    "url": "https://tablefor.apps.appbricx.com",
    "mode": "stored-build"
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "deploy" scope.
404noneNo such successful deployment.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/deploys/5c1d…/rollback" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/deploys/5c1d…/rollback", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:111

Run a workflow

POST/api/dev/v1/projects/:id/workflows/:workflowId/run

Run a workflow now with input. Server functions run inline (as the persona in as, or signed out); other workflows are queued. Waits up to 30 seconds for the result.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply on dev, deploy on prod

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:workflowIdrequiredstringThe workflow id.

Body

NameTypeDescription
inputoptionalobjectIts trigger payload.
envoptional"dev" | "prod"Which database: dev (the preview, default) or prod (the published app).
asoptional{ role, user_id? }Act as an app user holding this role.

Response

202 with finished: false when still running; read it with GET …/runs/:runId.

Response
{
  "runId": "4f0a…",
  "status": "succeeded",
  "finished": true,
  "result": {
    "sent": true
  },
  "error": null
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply / deploy" scope.
404WORKFLOW_NOT_FOUNDNo compiled workflow of that id.
409NO_PERSONANo app user holds that role.
422WORKFLOW_FAILEDThe run failed.
429QUOTA_EXCEEDEDDaily runs used up.
422ENQUEUE_FAILEDCouldn't start it.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/workflows/send-invoice/run" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"input":{"order":"b_1"},"env":"dev"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/workflows/send-invoice/run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "input": {
      "order": "b_1"
    },
    "env": "dev"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP runappbricx run

Source: services/api/src/routes/dev-api/index.ts:113

Get a run

GET/api/dev/v1/projects/:id/runs/:runId

One run with its log.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:runIdrequiredstringThe run id.

Response

Response
{
  "run": {
    "id": "4f0a…",
    "workflow_id": "send-invoice",
    "status": "succeeded",
    "error": null,
    "logs": [
      {
        "ts": "…",
        "level": "info",
        "message": "invoice sent"
      }
    ]
  }
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
404RUN_NOT_FOUNDNo such run.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/runs/4f0a1c2d-…" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/runs/4f0a1c2d-…", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:117

Dead letters

GET/api/dev/v1/projects/:id/dead-letters

Jobs that used up their retries.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
limitoptionalnumber1 to 200.

Response

Response
{
  "deadLetters": [
    {
      "id": "j_9",
      "workflow_id": "send-invoice",
      "env": "prod",
      "last_error": "SMTP timeout"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/dead-letters" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/dead-letters", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:119

Replay dead letters

POST/api/dev/v1/projects/:id/dead-letters/replay

Queue dead letters again (all when ids is omitted).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply (deploy when a job ran on prod)

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Body

NameTypeDescription
idsoptionaluuid[]1 to 100 job ids.

Response

Response
{
  "replayed": [
    "9a0b…"
  ],
  "skipped": []
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply / deploy" scope.
curl
curl -X POST "https://appbricx.com/api/dev/v1/projects/3b7e…/dead-letters/replay" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"ids":["9a0b…"]}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/dead-letters/replay", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "ids": [
      "9a0b…"
    ]
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:121

Tail events and requests

GET/api/dev/v1/projects/:id/tail

Recent activity: events (row writes and topic messages), requests (every error and about 10% of the rest, 7 days) or errors (4xx and 5xx only). Paths only, never bodies, query strings or tokens.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Query parameters

NameTypeDescription
kindrequired"events" | "requests" | "errors"What to show.
envoptional"dev" | "prod"Which database: dev (the preview, default) or prod (the published app).
sinceoptionalstring15m, 2h, 1d or an ISO time.
limitoptionalnumber1 to 500 (default 100).

Response

Response
{
  "kind": "errors",
  "env": "prod",
  "requests": [
    {
      "at": "…",
      "method": "POST",
      "path": "/__appbricx/api/v1/bookings",
      "status": 422,
      "ms": 38,
      "error": "RULE_REFUSED",
      "app_user_id": "u_7"
    }
  ],
  "note": "…"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
400BAD_REQUESTsince isn't a duration or ISO time.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/tail?kind=errors&env=prod&since=2h" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/tail?kind=errors&env=prod&since=2h", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP tailappbricx tail

Source: services/api/src/routes/dev-api/index.ts:123

List secrets

GET/api/dev/v1/projects/:id/secrets

The app's secrets: names, env and updated-at, never values. Also which names the app declares and which are missing.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: read

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).

Response

Response
{
  "secrets": [
    {
      "name": "STRIPE_KEY",
      "scope": "project",
      "env": "prod",
      "secret": true,
      "updatedAt": "…"
    }
  ],
  "declaredByApp": [
    "STRIPE_KEY",
    "SHIPPO_KEY"
  ],
  "missing": [
    "SHIPPO_KEY"
  ],
  "note": "Values are never returned."
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "read" scope.
curl
curl "https://appbricx.com/api/dev/v1/projects/3b7e…/secrets" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/secrets", {
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP secretsappbricx secretsctx.secrets.get

Source: services/api/src/routes/dev-api/index.ts:125

Set a secret

PUT/api/dev/v1/projects/:id/secrets/:name

Create or update a project secret. ctx.secrets reads env prod or all.

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply, and a workspace owner or admin

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:namerequiredstringAn env var name (letters, digits, _).

Body

NameTypeDescription
valuerequiredstringUp to 10,000 characters.
envoptional"dev" | "prod" | "all"Default all.

Response

201 when created, 200 when updated.

Response
{
  "name": "SHIPPO_KEY",
  "env": "all",
  "created": true,
  "updatedAt": "…"
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
403FORBIDDEN_ROLEOnly workspace owners and admins write secrets.
400BAD_REQUESTBad name or missing value.
curl
curl -X PUT "https://appbricx.com/api/dev/v1/projects/3b7e…/secrets/SHIPPO_KEY" \
  -H "Authorization: Bearer $APPBRICX_TOKEN" \
  -H "content-type: application/json" \
  -d '{"value":"shippo_live_…","env":"all"}'
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/secrets/SHIPPO_KEY", {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "value": "shippo_live_…",
    "env": "all"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:126

Delete a secret

DELETE/api/dev/v1/projects/:id/secrets/:name

Delete a project secret (env limits it to one environment).

Auth
Developer token: Authorization: Bearer $APPBRICX_TOKEN
Scope: apply, and a workspace owner or admin

Path parameters

NameTypeDescription
:idrequiredstringThe project id (uuid).
:namerequiredstringThe secret name.

Query parameters

NameTypeDescription
envoptional"dev" | "prod" | "all"Only this environment.

Response

Response
{
  "deleted": "SHIPPO_KEY",
  "envs": [
    "dev"
  ]
}

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing, invalid, expired or revoked token.
404none"Project not found": the id is wrong or outside the token's reach.
403FORBIDDEN_SCOPEThe token lacks the "apply" scope.
403FORBIDDEN_ROLEOwners and admins only.
404SECRET_NOT_FOUNDNo such secret.
curl
curl -X DELETE "https://appbricx.com/api/dev/v1/projects/3b7e…/secrets/SHIPPO_KEY?env=dev" \
  -H "Authorization: Bearer $APPBRICX_TOKEN"
fetch
const res = await fetch("https://appbricx.com/api/dev/v1/projects/3b7e…/secrets/SHIPPO_KEY?env=dev", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${APPBRICX_TOKEN}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/routes/dev-api/index.ts:130

On this page

  1. Authentication
  2. Endpoints
  3. POST /tokens
  4. GET /tokens
  5. DELETE /tokens/:tokenId
  6. GET /me
  7. GET /docs
  8. POST /components/check
  9. GET /projects
  10. POST /projects
  11. GET /projects/:id
  12. GET /projects/:id/contract
  13. POST /projects/:id/check
  14. POST /projects/:id/apply
  15. POST /projects/:id/patch
  16. POST /projects/:id/screenshot
  17. POST /projects/:id/verify
  18. POST /projects/:id/data/query
  19. GET /projects/:id/logs
  20. POST /projects/:id/deploy
  21. GET /projects/:id/demo-reset
  22. POST /projects/:id/demo-reset
  23. GET /projects/:id/sign-in
  24. POST /projects/:id/sign-in
  25. POST /projects/:id/sql
  26. POST /projects/:id/rows
  27. GET /projects/:id/schema
  28. GET /projects/:id/snapshots
  29. POST /projects/:id/snapshots
  30. POST /projects/:id/snapshots/:snapshotId/restore
  31. GET /projects/:id/deploys
  32. POST /projects/:id/deploys/:deploymentId/rollback
  33. POST /projects/:id/workflows/:workflowId/run
  34. GET /projects/:id/runs/:runId
  35. GET /projects/:id/dead-letters
  36. POST /projects/:id/dead-letters/replay
  37. GET /projects/:id/tail
  38. GET /projects/:id/secrets
  39. PUT /projects/:id/secrets/:name
  40. DELETE /projects/:id/secrets/:name
Appbricx

The backend, runtime and hosting for apps your coding agent builds. On our cloud, in yours, or on your own servers.

Features

Coding agents and MCPVerify testingBuilder consolePostgres databaseData APIRealtimeRow-level securitySign-in and authPaymentsWorkflows and jobsAI in your appIntegrationsBackups and rollbackHosting and domainsSelf-host and exportAll features

Product

ShowcasePricingFor coding agentsTemplatesPrivate cloudBring your own AI keyFAQ

Compare

Appbricx vs SupabaseLovable alternativeBolt alternativeFor freelancersFor agencies

Resources

DocumentationReferenceBlogSupportContact

© 2026 Appbricx. All rights reserved.

TermsPrivacyCookiesAcceptable Use