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

Functions, workflows and webhooks

Call server functions, queue workflow runs, read runs and dead letters, read notifications, and receive inbound webhooks.

9 endpointsHTTP API referenceGuide: Run work in the background

On this page
  1. Authentication
  2. Endpoints
  3. POST /functions/:name
  4. POST /runtime/workflows/:id/run
  5. GET /runtime/runs/:runId
  6. GET /runtime/runs
  7. GET /notifications
  8. GET /runtime/dlq
  9. POST /runtime/dlq/replay
  10. GET /runtime/webhooks/:name/secret
  11. POST /hooks/:projectId/:name

Base URL: your app's origin ($APP_ORIGIN): the published host, a custom domain, or the platform origin for the builder preview. Errors answer { ok: false, error: { code, message } } unless noted. Add x-appbricx-env: dev or prod to pick the database explicitly; otherwise the host decides (preview means dev, a published host means prod).

Authentication

App key + data marker
A project API key (dpk_c_… in browsers, bound to the app's origins; dpk_s_… on servers) or the builder preview token, plus the data-API marker header. With an app session (the header, or the appbricx_app_session cookie) the call acts as that user under row-level security; without one it acts as a guest. A server key may assert x-appbricx-app-user, x-appbricx-app-role and x-appbricx-app-org. Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)
Server key
A server-tier project API key (dpk_s_…, created in the editor under Backend, API). Browser keys and end-user sessions are refused. Authorization: Bearer $SERVER_KEYx-appbricx-data-api: 1
Webhook signature
No bearer token. When the webhook has a secret, sign the raw body with HMAC-SHA256 and send the hex digest. Hooks with a caller-provisioned secret also accept the secret itself in x-appbricx-webhook-secret. x-appbricx-signature: <hex HMAC-SHA256 of the raw body>

Endpoints

Call a server function

POST/__appbricx/functions/:name

Run the workflow name (declared with on: { call: true }) now, for the signed-in caller, and wait for its return value (at most about 35 seconds).

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Path parameters

NameTypeDescription
:namerequiredstringThe workflow id.

Body

NameTypeDescription
inputoptionalobjectThe function's input (64 KB max).

Response

Response
{
  "ok": true,
  "result": {
    "total": 7.9,
    "currency": "EUR"
  },
  "runId": "4f0a…"
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
400BAD_FUNCTION_NAMEInvalid name.
400BAD_JSONBody isn't JSON.
400BAD_INPUTinput isn't an object.
413INPUT_TOO_LARGEOver 64 KB.
404FUNCTION_NOT_FOUNDNo such workflow.
403NOT_A_FUNCTIONNot a ui-triggered workflow.
401SIGN_IN_REQUIREDSigned out and the function isn't public.
403ROLE_FORBIDDENThe caller's role isn't in the function's roles.
429FUNCTION_BUSY4 calls already in flight for this app.
429QUOTA_EXCEEDEDDaily workflow runs used up.
422FUNCTION_FAILEDThe function threw; message is its error (credentials masked).
504FUNCTION_TIMEOUTDidn't finish in time.
curl
curl -X POST "$APP_ORIGIN/__appbricx/functions/shipping-quote" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION" \
  -H "content-type: application/json" \
  -d '{"input":{"country":"DE","weightKg":2.5}}'
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/functions/shipping-quote`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "input": {
      "country": "DE",
      "weightKg": 2.5
    }
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Relatedapp.call

Source: services/api/src/app-runtime/http/workflow-routes.ts:121

Queue a workflow run

POST/__appbricx/runtime/workflows/:id/run

Queue a ui-triggered workflow (other triggers need a server key). The run's identity comes from the session, never from the payload.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Path parameters

NameTypeDescription
:idrequiredstringThe workflow id.

Body

NameTypeDescription
payloadoptionalobjectThe event payload.
dryRunoptionalbooleanTrace without side effects.

Response

Response
{
  "ok": true,
  "runId": "4f0a…"
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
403WORKFLOW_NOT_UI_TRIGGEREDNot ui-triggered and not a server key.
401SIGN_IN_REQUIREDA callable function needs a signed-in caller here.
403ROLE_FORBIDDENRole not allowed.
404PROJECT_NOT_FOUNDProject gone.
curl
curl -X POST "$APP_ORIGIN/__appbricx/runtime/workflows/send-invoice/run" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION" \
  -H "content-type: application/json" \
  -d '{"payload":{"order":"8c1d…"}}'
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/workflows/send-invoice/run`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "payload": {
      "order": "8c1d…"
    }
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedGET /__appbricx/runtime/runs/:runId

Source: services/api/src/app-runtime/http/workflow-routes.ts:200

Get a run

GET/__appbricx/runtime/runs/:runId

One workflow run with its status, error and log lines.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Path parameters

NameTypeDescription
:runIdrequiredstringFrom a queue or function call.

Response

Response
{
  "ok": true,
  "run": {
    "id": "4f0a…",
    "workflow_id": "send-invoice",
    "status": "succeeded",
    "error": null,
    "started_at": "2026-10-12T09:14:03Z",
    "finished_at": "2026-10-12T09:14:04Z",
    "logs": [
      {
        "ts": "…",
        "level": "info",
        "message": "invoice sent"
      }
    ]
  }
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
404RUN_NOT_FOUNDUnknown run.
curl
curl "$APP_ORIGIN/__appbricx/runtime/runs/4f0a1c2d-…" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION"
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/runs/4f0a1c2d-…`, {
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/app-runtime/http/workflow-routes.ts:264

List runs

GET/__appbricx/runtime/runs

Recent workflow runs of the project.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Query parameters

NameTypeDescription
limitoptionalnumber1 to 200 (default 50).
statusoptionalstringqueued, running, succeeded, failed…

Response

Response
{
  "ok": true,
  "runs": [
    {
      "id": "4f0a…",
      "workflow_id": "send-invoice",
      "trigger_type": "manual",
      "status": "failed",
      "error": "SMTP timeout",
      "attempt": 3,
      "call_depth": 0,
      "created_at": "…"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
curl
curl "$APP_ORIGIN/__appbricx/runtime/runs?limit=20&status=failed" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION"
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/runs?limit=20&status=failed`, {
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/app-runtime/http/workflow-routes.ts:278

Notifications

GET/__appbricx/notifications

The last notifications for the caller: person-targeted ones for them, role-targeted ones for their role, and untargeted ones.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Query parameters

NameTypeDescription
limitoptionalnumber1 to 200 (default 50).

Response

Response
{
  "ok": true,
  "notifications": [
    {
      "id": "n_1",
      "kind": null,
      "title": "New order",
      "body": "Order 1042 needs packing",
      "meta": {
        "role": "staff",
        "user": null
      },
      "created_at": "…"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
curl
curl "$APP_ORIGIN/__appbricx/notifications?limit=20" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION"
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/notifications?limit=20`, {
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Relatedctx.notify

Source: services/api/src/app-runtime/http/workflow-routes.ts:315

Dead letters

GET/__appbricx/runtime/dlq

Jobs that used up their retries.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Query parameters

NameTypeDescription
limitoptionalnumber1 to 1000 (default 100).

Response

Response
{
  "ok": true,
  "jobs": [
    {
      "id": "j_9",
      "run_id": "4f0a…",
      "attempt": 3,
      "max_attempts": 3,
      "last_error": "SMTP timeout",
      "workflow_id": "send-invoice",
      "trigger_type": "cdc"
    }
  ]
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
curl
curl "$APP_ORIGIN/__appbricx/runtime/dlq?limit=50" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION"
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/dlq?limit=50`, {
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedMCP run

Source: services/api/src/app-runtime/http/workflow-routes.ts:353

Replay a dead letter

POST/__appbricx/runtime/dlq/replay

Queue a dead job again.

Auth
App key + data marker: Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)

Body

NameTypeDescription
jobIdrequiredstringFrom the dead-letter list.

Response

Response
{
  "ok": true,
  "replayed": true
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
400MISSING_JOB_IDNo jobId.
404JOB_NOT_FOUNDUnknown job.
403CROSS_PROJECTAnother project's job.
400JOB_NOT_DEADNot in the dead state.
curl
curl -X POST "$APP_ORIGIN/__appbricx/runtime/dlq/replay" \
  -H "Authorization: Bearer $APP_KEY" \
  -H "x-appbricx-data-api: 1" \
  -H "x-appbricx-app-session: $APP_SESSION" \
  -H "content-type: application/json" \
  -d '{"jobId":"j_9"}'
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/dlq/replay`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${APP_KEY}`,
    "x-appbricx-data-api": "1",
    "x-appbricx-app-session": APP_SESSION,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "jobId": "j_9"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

Source: services/api/src/app-runtime/http/workflow-routes.ts:377

Webhook secret

GET/__appbricx/runtime/webhooks/:name/secret

The derived signing secret of a webhook, to paste into the sending provider's HMAC settings.

Auth
Server key: Authorization: Bearer $SERVER_KEYx-appbricx-data-api: 1

Path parameters

NameTypeDescription
:namerequiredstringThe webhook name.

Response

Response
{
  "ok": true,
  "secret": "5f2c…e91a"
}

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key").
400PARAMS_INVALIDThe x-appbricx-data-api: 1 header is missing.
403ORIGIN_NOT_ALLOWEDA browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all).
429RATE_LIMITEDThe project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default).
403TIER_FORBIDDENNot a server key.
400INVALID_NAMEBad name.
404WEBHOOK_NOT_FOUNDNo such webhook.
400NOT_DERIVEDThe webhook uses your own env-var secret.
curl
curl "$APP_ORIGIN/__appbricx/runtime/webhooks/stripe-events/secret" \
  -H "Authorization: Bearer $SERVER_KEY" \
  -H "x-appbricx-data-api: 1"
fetch
const res = await fetch(`${APP_ORIGIN}/__appbricx/runtime/webhooks/stripe-events/secret`, {
  headers: {
    Authorization: `Bearer ${SERVER_KEY}`,
    "x-appbricx-data-api": "1",
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedPOST /hooks/:projectId/:name

Source: services/api/src/app-runtime/http/workflow-routes.ts:415

Inbound webhook

POST/hooks/:projectId/:name

Receive an event from another service and queue the bound workflow with { webhook, body, headers }. The environment (dev or prod) is the one bound when the webhook was registered.

Auth
Webhook signature: x-appbricx-signature: <hex HMAC-SHA256 of the raw body>

Path parameters

NameTypeDescription
:projectIdrequiredstringThe project id.
:namerequiredstringThe webhook name.

Body

NameTypeDescription
(any JSON)optionalobjectThe provider's payload (1 MB max).

Response

A repeated x-appbricx-idempotency-key within 24 hours answers { ok: true, idempotent: true } without a second run.

Response
{
  "ok": true,
  "runId": "4f0a…"
}

Errors

StatusCodeWhen
400INVALID_WEBHOOK_NAMEBad name.
429RATE_LIMITEDToo many deliveries.
413BODY_TOO_LARGEOver 1 MB.
404WEBHOOK_NOT_FOUNDUnknown or disabled.
400INVALID_JSONBody isn't JSON.
401UNAUTHORIZEDSignature (or secret) missing or wrong.
curl
curl -X POST "$APP_ORIGIN/hooks/3b7e…/stripe-events" \
  -H "x-appbricx-signature: $SIGNATURE" \
  -H "content-type: application/json" \
  -d '{"type":"checkout.session.completed","data":{"object":{"id":"cs_…"}}}'
fetch
const res = await fetch(`${APP_ORIGIN}/hooks/3b7e…/stripe-events`, {
  method: "POST",
  headers: {
    "x-appbricx-signature": signature,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "type": "checkout.session.completed",
    "data": {
      "object": {
        "id": "cs_…"
      }
    }
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);

RelatedGuides workflows

Source: services/api/src/app-runtime/http/hooks-routes.ts:184

On this page

  1. Authentication
  2. Endpoints
  3. POST /functions/:name
  4. POST /runtime/workflows/:id/run
  5. GET /runtime/runs/:runId
  6. GET /runtime/runs
  7. GET /notifications
  8. GET /runtime/dlq
  9. POST /runtime/dlq/replay
  10. GET /runtime/webhooks/:name/secret
  11. POST /hooks/:projectId/: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