Reference

API reference

One tenant-resolved surface for everything: GraphQL for nested, permission-aware queries; REST for scripts, webhooks and integrations. Every call is scoped to the resolved tenant and cleared by the Permission Engine.

Authentication

Sign tokens in HMAC-SHA512 (or asymmetric if ordered) with channel binding. Pass the token as a Bearer header; the token's tenant claim drives routing and scoping. Keys are never embedded client-side.

POST /auth/token
{ "email": "nan@acmetools.com", "password": "••••••••••" }

200 → { "accessToken": "…", "refreshToken": "…", "project": "…", "tenant": "…" }

Authorization: Authorization: Bearer <accessToken>. Data query requires a tenant token; auth tokens are HMAC-scoped, short-lived, and never shared across tenants.

REST

Routes live under /v1. All record paths mirror the metadata engine — list, create, batch, update, delete, restore.

MethodPathPurpose
GET/v1/tablesList tables (with fields & relations)
POST/v1/tablesCreate a table
GET/v1/tables/:slug/recordsQuery records (view-aware, paged)
POST/v1/tables/:slug/recordsCreate record(s)
PATCH/v1/tables/:slug/records/:idUpdate a record
DELETE/v1/tables/:slug/records/:idDelete a record
POST/v1/automations/:id/runTrigger an automation manually
POST/v1/functions/:slug/runRun a sandboxed function

Errors are uniform: { "error": { "code": …, "message": …, "detail": … } } with idempotency keys honored on mutations (Idempotency-Key header).

GraphQL

One endpoint, /graphql or your project subdomain. Introspection is available with an auth token for tooling (fieldMapper, Postman, Insomnia).

query TableWithRecords($slug: String!) {
  table(slug: $slug) {
    name
    slug
    recordPrefix
    fields { name type typeConfig }
    records(limit: 5, offset: 0) {
      humanId
      fieldValues
    }
  }
}

Mutations mirror the REST surface: createTable, createRecords, updateRecord, deleteRecord, runAutomation, runFunction. Queries resolve under the same permission walk as REST — you cannot view a record you could not fetch over REST.

Tenant functions

Functions run in V8 isolates inside the sandbox service. The function's ambient authority is exactly its local scope — it can reach platform data only via the SDK, broker-mediated under the caller's permission grant:

export default async function vendorScore(ctx) {
  // ctx has an HMAC-verifiable grant, no ambient authority
  const cost = await ctx.sdk.tables.records.list({ table: "Pricing", fields: ["amount"] });
  const rows = cost.filter(r => !r.deleted_at);
  return { average: rows.reduce((a, b) => a + b.amount, 0) / Math.max(rows.length, 1) };
}
  • Inputs are typed; secrets surface only via ctx.sdk.secrets.get.
  • Rate limits, memory cap and a hard execution timeout are enforced by the broker.
  • Every invocation is re-resolved against the Permission Engine — no cached grants across executions.
Versioning & cost: all routes and queries are versioned; breaking changes ship with a documented migration window. Metered calls are counted per tenant and surfaced in the billing screen.