Authorize

#Workflows

A workflow is an ordered set of jobs; each job runs a sequence of actions (HTTP calls, entity reads/writes, file processing, LLM inference, …). Workflows react to triggers — an entity event, a webhook, a cron tick, or a direct dispatch. See Core Concepts for the mental model.

A workflow lives in two layers:

  • Definition — the design-time spec: the jobs, actions, and triggers. Authored under /definition/* and shareable to other tenants.
  • Activation — a tenant turning a definition on: its env, trigger secrets, bound policy, and the runs it produces. Driven under /workflows/*.

Authenticate with a Personal Access Token (HTTP Basic auth) — enter it once in the Authorize bar at the top of this page and every Try it below uses it. Each example body is pre-filled; the console targets staging by default. Full request/response schemas are in the linked API reference.

#Build a workflow

The flow is: define the workflow → activate it → trigger a run → watch it.

#1. Define the workflow

A workflow binds triggers to job steps. Author each step's logic inline — embed its actions directly in the step. Inline is the recommended default: one definition, one version, nothing else to publish or keep in sync. Each action has a stepId, a name (from the action catalog), and a config; see jobs & actions for the conditional fields (if, errorWhen, errorPolicy, onError). dependencies order steps into a DAG.

POST/definition/workflowsCreate a workflow (inline job)API docs ↗Try it

A definition is draft until the first activation flips it to active. The write is validated against the workflow JSON schema; per-action config is validated again at run time, after smart values resolve. Pass source_yaml instead of definition_json to author in YAML.

Reuse the same actions across workflows? Publish them as a named job definition (POST /definition/jobs with a (name, version)) and reference it from a step: { "stepId": "remind", "name": "notify-overdue-task", "version": "1.0.0" }. Reach for a named job only when you genuinely need to share one action sequence across several workflows or pin its version independently — otherwise keep it inline.

#2. Activate it

Activation is the consumer tenant turning the definition on: it merges env, reconciles trigger rows, binds an access policy the run acts under, and (for cron) provisions schedules. It is idempotent — re-activating with the same body produces the same state.

POST/workflows/{id}/activateActivate a workflow in your tenantAPI docs ↗Try it

The response returns each trigger with its webhook_url (what external callers POST to) and config_status. Cron and webhook-secret details are under Triggers below.

#3. Trigger a run

Four sources fire a run: an entity event, a webhook POST, a cron tick, or a direct dispatch. Direct dispatch is the ad-hoc path — pass the trigger's definition id (e.g. "manual"), not the row UUID:

POST/workflows/wrDispatch a runAPI docs ↗Try it

Returns 202 with the workflow_run.id. Webhook callers instead POST to the webhook_url from activation; cron and event triggers fire automatically.

#4. Monitor the run

List runs (filter by workflow_id, status_in, entity_id, …), then drill into one for its per-job and per-action errors.

GET/workflows/runs/workflowsList recent runsAPI docs ↗Try it
GET/workflows/runs/workflows/{id}Inspect a run (job + action detail)API docs ↗Try it

The workflow-run error is null unless an orchestrator-level error fired; per-step failures live on job_runs[].error (and action_runs[].error). Statuses are pending → dispatched → running → success | error | cancelled | skipped | timeout.

#Jobs & actions

Inline and named jobs run identically — both resolve to the same shape before execution. Prefer inline (actions directly on the workflow step): it keeps a workflow self-contained, with one definition and one version to manage. Reach for a named job definition (POST /definition/jobs, referenced by (name, version)) only when you need to share one action sequence across several workflows or pin its version independently.

#Step-level control (per job step)

A workflow job step accepts a condition gate and error/rerun policies:

Field Values Meaning
dependencies string[] Step ids that must finish first (defines the DAG).
condition bare JSONata Evaluated against context_data; if false, see conditionPolicy.
conditionPolicy continue | abort | fail On false condition: continue skips the step, abort ends the workflow as success, fail ends it as error. Default fail.
errorPolicy continue | abort | fail On step error: same three outcomes. Default fail.
rerunPolicy continue | allow | abort On a parent retry: reuse prior output, re-run, or end. Default allow.

#Action-level control (per action, inside a job)

Each action carries optional conditional and recovery fields. This is what lets a single job branch and self-heal without a separate step:

Field Values Meaning
if bare JSONata Evaluated before the action. A falsy result skips the action and its onSuccess and moves on. Mirrors a bridge step's if gate.
errorWhen bare JSONata Evaluated after the action on its result; a truthy value marks the action failed (for http, defaults to result.status >= 400).
onSuccess action sub-sequence Actions run after this action succeeds, before the parent sequence continues.
onError action sub-sequence Recovery actions run after this action fails, before errorPolicy is applied.
errorPolicy fail | continue After the action fails (and its onError runs): fail (default) ends the job with the error; continue consumes the error and resumes the parent sequence at the next action.

Action errorPolicy (fail/continue) is distinct from the job-step errorPolicy (continue/abort/fail). The action field governs flow inside a job; the step field governs the workflow outcome when the whole step errors. In the workflow above, the notify action sets errorPolicy: "continue" and an onError that flags the task — so a failed notification is recorded and the job still completes.

Authoring fields like config, body, if, and errorWhen are smart values: literals, {{ }} JSONata expressions (a whole-string {{ … }} stringifies), or $-directives for raw values. The full model — bindings (input, outputs, context_data, env, secrets), directives, and failure modes — is in Smart Values.

To reshape a row set inline — filter, map, join, sort, or dedupe a prior step's output before writing it — wrap it in a { $rows, $pipe } node in any action config / input / output. The $pipe vocabulary is the same one apps use; see Shaping a row set.

#Action catalog

The orchestration layer ships these action types. Every config is a smart value; see the API reference for each action's exact config schema.

Action Kind Purpose
http external Synchronous HTTP request
httpCallback external Async HTTP request; resumes on callback
llmCallback external Async LLM inference (Anthropic / OpenAI)
awaitInput workflow Pause until an operator submits structured input
invokeWorkflow workflow Spawn a child workflow run (fire-and-forget)
queryEntity entity Read one or many entities
upsertEntity entity Create / update entities (single or bulk)
removeEntities entity Delete entities by id
upsertRelationship entity Create / update relationship instances
removeRelationships entity Delete relationship instances by id
syncRelationships entity Set-replace one entity's links under a rule
uploadArtifact / downloadArtifact / listEntityArtifacts / createArtifactDownloadURL artifact Store, fetch, list, and sign artifact access
zipCompress / zipDecompress / archiveDecompress file Compress and extract archives
splitPdf / mergePdf / chunkPdf file Split, concatenate, and chunk PDFs
csvFromZipStream / transformCsvStream / mergeCsvStreams csv CSV extract, per-row transform, and join
importEntitiesFromCsv / exportEntitiesToCsv csv Bulk import/export entities via CSV

#Triggers

A workflow's definition_json.triggers[] declares when it runs. Each entry has an id plus exactly one of source (event), cron, or webhook; a webhook with no verification is the "API-only / manual" form. Triggers are reconciled on every activate. Optional condition (a bare JSONata gate), contextData (shapes context_data.input), and idempotencyKey apply to any type.

#Event trigger

Fires when an entity is created, updated, or deleted — optionally narrowed to one entity, one relationship rule, or matching attribute values.

{
  "id": "on-task-updated",
  "source": {
    "entityTypeId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "eventAction": "updated",            // created | updated | deleted
    "relationshipRuleId": "<uuid?>",     // optional — only this rule
    "entityId": "<uuid?>",               // optional — only this entity
    "attributeFilters": [ { "operator": "eq", "path": ["status"], "value": "open" } ]
  }
}

#Cron trigger

A standard five-field cron expression. Timezone comes from the activation's env.TZ (default UTC).

{ "id": "nightly", "cron": "0 0 * * *" }

#Webhook trigger

External callers POST to the trigger's webhook_url (returned at activation). verification checks request authenticity; challenge answers a validation handshake (e.g. Microsoft Graph) without dispatching a run.

{
  "id": "inbound",
  "webhook": {
    "methods": ["POST"],
    "verification": {
      "location": "header",              // header | body | query
      "key": "x-hub-signature-256",
      "method": "hmac-sha256"            // exact | hmac-sha256 | hmac-sha1
    },
    "challenge": { "enabled": true, "queryParam": "validationToken", "responseType": "text/plain" }
  }
}

A webhook secret exists only when verification is declared. Mint it (returned once as whsec_…; rotates any prior secret); the gateway then verifies every POST /workflows/hooks/:triggerId and rejects a bad signature with 401.

POST/workflows/{id}/triggers/{triggerId}/secretMint a webhook secret (returned once)API docs ↗Try it

After activation, toggle a trigger without re-activating via PUT /workflows/{id}/triggers/{triggerId}/{enable,disable}.

#Policy & secrets

  • Policy — an activation binds an access policy that authorizes everything the run does. See Provisioning.
  • Secrets — wire scoped secret refs into config.env; never put a ref in the definition. See Secrets.

#Inline jobs without a workflow

Apps (bridge) can run the same action sequences inline — synchronously, with no workflow run — for request handling. See Apps (Bridge).

#Share a workflow with another tenant

Publishing a definition for another tenant to install is its own topic — see Shares & Grants.

#API reference

Every workflow, job, trigger, and run operation — with full request/response schemas and an interactive console — is in the API reference.