#FAQ & Troubleshooting
#Authentication
How do I authenticate? HTTP Basic with a Personal Access Token:
Authorization: Basic base64(client_id:client_secret), or a Bearer JWT you
exchange the token for at POST /auth/token. The token scopes the request to
your tenant.
I get 401 unauthorized. The Authorization header is missing or malformed
— check the base64 encoding is client_id:client_secret (colon-separated) — or
the Bearer JWT is invalid or expired; exchange the token again. See
Auth & API Gateway.
I get 403 forbidden. Read the message. Invalid API token,
API token has been revoked and API token has expired mean the credentials
themselves were refused — a wrong secret, or a revoked or expired token.
Otherwise you're authenticated but not authorized for that resource/action.
You need a grant (intra-tenant) or, for cross-tenant data, both a share
— which exists only once you accept the owner's manifest — and a grant. See
Shares & Grants.
Token exchange answers 429. Ten failed exchanges from your IP within 60
seconds lock the exchange for that IP — valid credentials included — until the
window passes. Fix the credentials, wait a minute, and retry.
#Errors & responses
What shape are errors? Always
{ "error": { "status", "code", "message", "details" } }, with details
present when the code carries extra data. Rely on the HTTP status code; status
just mirrors it. See Auth & API Gateway.
What does 422 mean? A validation error — usually the request body didn't
match the schema (a malformed filter, a missing field), or entity attributes
don't match the entity type's JSON schema. details.errors pinpoints each
field: filter.operator: … for the request, /state: … inside attributes.
What does 409 conflict mean? Something with the same unique key already
exists — a schema with that name, a job with that name and version, an active
app token on the integration — and details names it. A write that carried an
expected_updated_at also answers 409 (details.code
CONCURRENT_MODIFICATION) when the row changed since you read it: re-read and
retry. Reusing an Idempotency-Key with a different body is a 409 too.
#Querying
Offset or keyset pagination? Use page/limit for simple offset paging, or
cursor (from a prior response's next_cursor) for stable keyset iteration
over large sets. They are mutually exclusive — send one or the other, never
both.
My filter on an attribute returns nothing. Filtering is not gated on indexing — any attribute in the type's schema can be filtered, via a JSONB fallback when it is not indexed — so an empty result usually means the value really does not match. Check the spelling of the path first: a path that doesn't exist matches nothing rather than erroring.
Can I sort on any attribute? In POST /entity/query, yes: an indexed
attribute sorts by its indexed type, and one that isn't indexed sorts by its
stored JSON value (numbers numerically), with missing and null values last. An
unindexed sort gets slower as the type grows — mark the attribute
sortable: true once a list sorts on it routinely. GraphQL orderBy and OData
$orderby are stricter: they only accept attributes indexed with
sortable: true, and anything else is a 400. See
Sorting.
REST query vs GraphQL — which should I use? They read the same data. Use
GraphQL for a typed graph view with nested edges/node; use the REST query for
composite filters, counts, and keyset pagination. See
Querying & GraphQL.
How do I turn a GraphQL query into a workflow step? Prototype it in the
playground at /graphql/, then write the same read as a
queryEntity action: typeName is the root field, each where condition
becomes a filter on ["attributes", "<name>"] (_eq → eq), and orderBy
becomes sort. The
Canonical Example
shows one translated end to end.
#Workflows & jobs
Inline action or referenced job? Inline for small, step-local logic; a referenced job when the logic is reused across workflows. See Workflows.
My workflow doesn't run. Confirm it's activated for your tenant and has
a trigger (event/cron/webhook). An unactivated definition never runs —
dispatching one answers 403 Workflow definition is not active. See
Triggers. A token that dispatches runs
directly needs read on the workflow definition and create + read on
workflow_run — see
Trigger a run.
How do I pass data between steps? Smart values — e.g.
{{ outputs.<stepId> }}, $jsonata, $literal, $if. See
Smart Values.
#Bridge apps
My app renders, but a widget shows no data. Look at the render's
notifications.
Data for "tasks" couldn't be loaded: Entity type "Task" not found means the
policy the app user acts under has no read on that type: give the spec a
policies entry that grants it and name it in defaultPolicy, or assign the
user a policy that does. Widgets can also be gated by grants and by the spec's
principal config. See Apps (Bridge).
Why do some widgets in the docs catalogue have no live preview? Data-bound
widgets (data_grid, entity_info, related_collections) are previewed with
sample data; the process widgets assemble from live sources, so they are shown
as config only, and layout widgets render only inside a page's layout. See
Widget Catalogue.
#Sharing
Activating a shared workflow answers 404, or a shared app 403. The offer
has not been accepted yet. An offer lets you read what it contains, but grants
nothing until your tenant accepts it with
PUT /access/manifests/{manifestId}/acceptance and the body
{ "status": "accepted" }. See Accept & Activate.
We accepted, but one resource is still missing. The owner did not list it in
the manifest. Activating a shared app whose policy names that resource answers
422 UNRESOLVABLE_GRANT_RESOURCE_NAME, with the resource's type and name in
details. Everything a shared workflow or app needs — its entity types, the
schemas its config names, rows of data — is a member of its own. Ask the owner
to add it; the change reaches you as soon as they save it. A job the owner
itself borrowed from a third tenant reaches you only if that job's owner offers
it to you too. See Share with Another Tenant.
#Secrets
How do I use a credential without hardcoding it? Store it as a secret
(POST /access/secrets), wire a reference such as
{{ secrets.tenant.PROVIDER_API_KEY }} into the activation's config (a
workflow's env, an app's config), and have the definition read that config
key. The value never comes back out of the API; the engine resolves it at run
time. See Secrets.
#Still stuck?
Browse the full API reference for exact request/response schemas, or read the relevant per-surface guide from the sidebar.