Help Center/API Reference

Public REST API

Connect Cadenio to your entire stack

Automate compliance workflows, sync run data to external systems, and build custom dashboards or AI agents using scoped API keys and a standard REST interface.

01

Create an API key

Go to Settings → Integrations → API Keys and create a new key. Select only the scopes your integration requires.

02

Make a request

Include the key in the Authorization: Bearer header. The base URL is https://api.cadenio.com — there is no version prefix.

03

Handle the response

Responses are JSON with camelCase fields, matching what the Cadenio web app itself sends and receives. Errors include statusCode and error fields to branch on.

Authentication

Bearer token authentication

All API requests must include a valid API key in the Authorization header using the Bearer scheme. Keys are prefixed with sk_live_ and are available to organizations on the Business plan or higher, under Settings → Integrations → API Keys.

Note: The full key value is shown only once, at creation. Store it securely — it cannot be retrieved afterward. If lost, revoke it and create a new one.

Required header

Authorizationstringrequired

Must be Bearer followed by your sk_live_ API key.

Content-Typestringoptional

Required for POST and PATCH requests. Set to application/json.

Request
curl https://api.cadenio.com/runs \
  -H "Authorization: Bearer sk_live_a1b2c3..." \
  -H "Content-Type: application/json"

Scopes

Scopes reference

Each API key carries a set of scopes that define exactly which operations it can perform, plus a resource mode that further restricts which templates or folders it can touch. Session-based (browser) requests are always permitted regardless of scope — enforcement applies only to API key requests.

ScopeDescription
runs:readRead run lists, run details, analytics, and exports
runs:writeUpdate run title, task status/due-date/assignee, approvals
runs:executeLaunch new runs from a template
templates:readRead templates, tasks, fields, rules, and versions
templates:writeCreate and edit templates, tasks, fields, rules, and phases
templates:publishPublish a template draft as a new version
files:readDownload files, thumbnails, and check scan status
files:writeUpload and delete files attached to run tasks
data-sources:readRead data sources, columns, rows, and relations
data-sources:writeCreate and update data sources, columns, and rows
users:readRead the organization member list
webhooks:manageCreate, list, update, test, and delete webhook endpoints

Resource mode

Beyond scopes, every key has a resourceMode: ALL (default, reaches any template/run in the org), SELECTED_TEMPLATES (restricted to a list of templates), or SELECTED_FOLDERS (restricted to every template inside the selected folders). The restriction applies to templates, their drafts, runs, and task execution — a key scoped to one template cannot read or modify others, even if the request otherwise looks valid.

Rate limits

Request rate limits

Rate limits are applied per API key, independently of other keys or session users in the same organization. Read requests (GET) get a materially higher quota than write requests (POST/PATCH/DELETE), since listing and polling are far cheaper than mutations.

  • Write requests: 300 requests per minute per API key
  • Read requests (GET): 1,500 requests per minute per API key
  • Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers
  • Exceeding the limit returns HTTP 429 with a Retry-After header (seconds until the window resets)
Rate limit headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 294
X-RateLimit-Reset: 1785005060
429 response
HTTP/1.1 429 Too Many Requests
Retry-After: 47

{
  "statusCode": 429,
  "message": "Rate limit exceeded",
  "error": "Too Many Requests",
  "retryAfter": 47
}

Error responses

Error responses

Errors return a standard JSON body: statusCode (matches the HTTP status), error (a short, stable reason phrase such as "Forbidden" or "Not Found"), message (a human-readable string, or an array of strings for validation errors), timestamp, and path. There is no separate machine-readable error code for most errors — branch on statusCode and, where useful, on substrings of message.

Statuserror / message example
400Bad RequestFailed input validation, or a business-rule conflict (e.g. completing a run with pending required tasks)
401UnauthorizedMissing, malformed, or revoked API key ('Authentication required')
401UnauthorizedEndpoint requires a browser session; API keys cannot access it (e.g. /api-keys itself)
402Payment RequiredBody includes { code: "FEATURE_LOCKED", capability }. The org's plan does not include this feature
403ForbiddenKey is missing the required scope for this action
403ForbiddenKey's resource mode does not grant access to this template/folder
404Not FoundResource does not exist, was deleted, or is not accessible from this org
429Too Many RequestsRate limit exceeded. Check the Retry-After header for the retry delay in seconds
500Internal Server ErrorUnexpected server error. Retry with backoff; contact support if it persists
Error response
HTTP/1.1 403 Forbidden

{
  "statusCode": 403,
  "timestamp": "2026-07-24T16:43:10Z",
  "path": "/runs",
  "message": "API key missing required scope: runs:read",
  "error": "Forbidden"
}

Runs

Runs

A run is an execution instance of a template. It represents an in-progress or completed process with assigned tasks, deadlines, and a full audit trail. Runs have both a UUID id (used in every URL) and a short, human-friendly publicId used for display.

GET/runsruns:read

List runs

Returns a paginated list of runs for the organization, newest first. Use query parameters to filter by status, template, or scheduled date.

Parameters

statusstringoptional

Filter by run status. One of: RUNNING, OVERDUE, COMPLETED, CANCELLED.

templateIdstringoptional

Filter runs launched from a specific template.

scheduledDatestringoptional

Filter by scheduled date (YYYY-MM-DD).

stalledForDaysintegeroptional

Only active runs (RUNNING/OVERDUE) with no activity for at least this many days.

limitintegeroptional

Items per page. Default and max: 200.

Request
curl -G https://api.cadenio.com/runs \
  -H "Authorization: Bearer sk_live_..." \
  -d status=RUNNING \
  -d limit=20
Response
HTTP/1.1 200 OK

{
  "data": [
    {
      "id": "3ed4dcf7-a102-4327-81ab-723b34d8a6b5",
      "publicId": "r_3ytXrD6WA7",
      "title": "Vendor Onboarding - ACME Corp",
      "status": "RUNNING",
      "templateId": "6795dfb5-15de-4f41-8a96-b83830526ca6",
      "ownerUserId": "2bc947d9-114d-4c7f-9d18-6af9cfa2393c",
      "scheduledDateLocal": "2026-07-24",
      "createdAt": "2026-07-24T14:22:00Z",
      "completedAt": null
    }
  ],
  "total": 1,
  "hasMore": false
}

// id is the UUID you use in every other endpoint. publicId is a short,
// human-friendly identifier (only runs have one) meant for display in UI/PDFs.
POST/runsruns:execute

Launch a run

Creates a new run from a published template. The run opens immediately in RUNNING status with all tasks generated from the template's published version. If your key's resourceMode is SELECTED_TEMPLATES or SELECTED_FOLDERS, templateId must be inside its allowed set.

Parameters

templateIdstringrequired

ID of the template to launch. The template must be published.

titlestringoptional

Custom display name for this run. Defaults to the template's run-title pattern or the template name.

scheduledDateLocalstringoptional

Scheduled date in YYYY-MM-DD format, in the org's timezone. Defaults to today.

ownerEmailstringoptional

Email of the user to set as run owner. Defaults to the API key's creator.

variablesobjectoptional

Key-value map overriding the template's flow variables for this run.

Request
curl -X POST https://api.cadenio.com/runs \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "6795dfb5-15de-4f41-8a96-b83830526ca6",
    "title": "Vendor Onboarding - ACME Corp"
  }'
Response
HTTP/1.1 201 Created

{
  "id": "3ed4dcf7-a102-4327-81ab-723b34d8a6b5",
  "publicId": "r_3ytXrD6WA7",
  "title": "Vendor Onboarding - ACME Corp",
  "status": "RUNNING",
  "templateId": "6795dfb5-15de-4f41-8a96-b83830526ca6",
  "templateVersionId": "fbc7dd41-334e-416b-8ddd-acb053aa0dd9",
  "ownerUserId": "2bc947d9-114d-4c7f-9d18-6af9cfa2393c",
  "createdAt": "2026-07-24T14:22:00Z"
}
PATCH/runs/tasks/:taskId/statusruns:write

Update a task's status

Sets a task to PENDING or COMPLETED directly, bypassing form-field collection. For tasks with required fields, prefer the Execution flow below so field values are captured — completing a task this way does not submit any field values.

Parameters

statusstringrequired

New task status.

PENDINGCOMPLETED
Request
curl -X PATCH \
  https://api.cadenio.com/runs/tasks/22074d71-5767-48cf-ad21-88be0b52911c/status \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "COMPLETED" }'
Response
HTTP/1.1 204 No Content
PATCH/runs/tasks/:taskId/due-dateruns:write

Update a task's deadline

Sets or clears the per-task SLA deadline.

Parameters

dueAtdatetime | nullrequired

ISO 8601 timestamp for the new deadline, or null to clear it.

dueAtHasTimebooleanoptional

Whether dueAt carries a specific time (true) or is a date-only deadline due at end of day (false).

Request
curl -X PATCH \
  https://api.cadenio.com/runs/tasks/22074d71-5767-48cf-ad21-88be0b52911c/due-date \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "dueAt": "2026-08-01T17:00:00Z", "dueAtHasTime": true }'
Response
HTTP/1.1 204 No Content
PATCH/runs/tasks/:taskId/assigneeruns:write

Reassign a task

Reassigns a task to a different user or group. Pass both fields as null to unassign entirely.

Parameters

assigneeIdstring | nulloptional

User ID to assign the task to. Pass null to unassign.

assigneeGroupIdstring | nulloptional

Group ID to assign the task to instead of an individual user.

Request
curl -X PATCH \
  https://api.cadenio.com/runs/tasks/22074d71-5767-48cf-ad21-88be0b52911c/assignee \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "assigneeId": "2bc947d9-114d-4c7f-9d18-6af9cfa2393c" }'
Response
HTTP/1.1 204 No Content
MethodEndpointScopeDescription
GET/runs/countsruns:readRun counts by status
GET/runs/analyticsruns:readRun analytics summary
GET/runs/analytics/advancedruns:readAdvanced run analytics
POST/runs/analytics/filteredruns:readAnalytics with a custom filter body
POST/runs/analytics/advanced/filteredruns:readAdvanced analytics with a custom filter body
GET/runs/export/csvruns:readExport the run list as CSV
GET/runs/analytics/export/pdfruns:readExport analytics as PDF
GET/runs/analytics/export/csvruns:readExport analytics as CSV
POST/runs/archiveruns:writeBulk-archive runs by ID
GET/runs/:idruns:readGet a run
GET/runs/:id/summariesruns:readGet task/field summaries for a run
GET/runs/:id/export/csvruns:readExport a single run as CSV
GET/runs/:id/export/pdfruns:readExport a single run as PDF
GET/runs/:id/dependenciesruns:readTask dependency status for a run
GET/runs/:id/activityruns:readActivity log for a run
GET/runs/:id/variablesruns:readFlow variable values for a run
PATCH/runs/:idruns:writeRename a run
POST/runs/:id/completeruns:writeComplete a run (rejects if already terminal)
POST/runs/:id/cancelruns:writeCancel a run
POST/runs/:id/reopenruns:writeReopen a completed/cancelled run
POST/runs/:id/migrate-to-latestruns:writeMigrate a run to the template's latest version
POST/runs/tasks/:taskId/approvalruns:writeApprove a task pending approval
POST/runs/tasks/:taskId/approval/rejectruns:writeReject a task's approval
GET/runs/tasks/:taskId/approval-trailruns:readApproval history for a task
POST/runs/tasks/:taskId/force-unblockruns:writeForce-unblock a task stuck on a dependency

Execution

Execution

This is the primitive to actually fill out a task's form and complete it — what an agentic AI or a custom integration should call to do real work in a run, rather than the coarse status-only PATCH above. The flow is always: open an execution entry for the task, submit one or more field values against it, then complete it.

POST/execution/entriesruns:write

Open an execution entry

Starts a fillable execution entry for a task. Most tasks allow only one open entry at a time; repeatable tasks can have several. Get runTaskId from a run's task list (GET /runs/:id).

Parameters

runTaskIdstringrequired

ID of the run task to open an execution entry for.

Request
curl -X POST https://api.cadenio.com/execution/entries \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "runTaskId": "22074d71-5767-48cf-ad21-88be0b52911c" }'
Response
HTTP/1.1 201 Created

{
  "id": "4abc71a1-4c8d-4ac0-ae3d-4333f33ad886",
  "runTaskId": "22074d71-5767-48cf-ad21-88be0b52911c",
  "createdByUserId": "2bc947d9-114d-4c7f-9d18-6af9cfa2393c",
  "createdAt": "2026-07-24T17:28:10Z",
  "fieldValues": []
}
POST/execution/field-valuesruns:write

Submit a field value

Writes one field's value into an open execution entry. Call once per field, or use the batch variant below for multiple fields at once. Field IDs are stable per published version — fetch them from GET /templates/:id/published-fields.

Parameters

executionEntryIdstringrequired

ID of the execution entry returned by POST /execution/entries.

runTaskFieldIdstringrequired

ID of the field being filled. Get stable field IDs from GET /templates/:id/published-fields.

valueanyrequired

The value to submit. Shape depends on the field type (string for text, ISO date for DATE, option key for DROPDOWN, etc.).

Request
curl -X POST https://api.cadenio.com/execution/field-values \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "executionEntryId": "4abc71a1-4c8d-4ac0-ae3d-4333f33ad886",
    "runTaskFieldId": "607ebeee-afd1-4834-8c9d-e5019e1373ad",
    "value": "42"
  }'
Response
HTTP/1.1 201 Created

{ "autoFilledFields": [] }

// autoFilledFields lists any other field the platform derived from this
// write (e.g. a lookup field populated from a linked data source row).
POST/execution/entries/completeruns:write

Complete an execution entry

Validates all required fields are filled, then marks the task COMPLETED. Rejects with 400 if a required field is still missing or a required approval is pending.

Parameters

executionEntryIdstringrequired

ID of the execution entry to complete. Marks the underlying task COMPLETED.

idempotencyKeystringoptional

Client-generated UUID. Replaying the same key returns the original result instead of completing twice.

Request
curl -X POST https://api.cadenio.com/execution/entries/complete \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "executionEntryId": "4abc71a1-4c8d-4ac0-ae3d-4333f33ad886" }'
Response
HTTP/1.1 204 No Content

// Completing the last required, visible task in a run auto-completes the
// run itself — no separate call to POST /runs/:id/complete is needed.
MethodEndpointScopeDescription
POST/execution/field-values/batchruns:writeSubmit multiple field values in one call
POST/execution/entries/reopenruns:writeReopen a completed execution entry
GET/execution/tasks/:runTaskIdruns:readList execution entries for a task (repeatable tasks can have several)
GET/execution/field-values/:fieldValueId/historyruns:readGet the edit history of a submitted field value

Templates

Templates

Templates are process blueprints: phases, tasks, form fields, conditional logic rules, dependencies, and flow variables. Editing a template only ever touches its unpublished draft — publishing snapshots the draft into a new immutable version, which is what new runs are launched from.

MethodEndpointScopeDescription
GET/templatestemplates:readList templates
POST/templatestemplates:writeCreate a template draft
GET/templates/:idtemplates:readGet a template
PUT/templates/:idtemplates:writeUpdate a template's own settings
DELETE/templates/:idtemplates:writePermanently delete a template. Blocked while RUNNING/OVERDUE runs exist.
GET/templates/:id/runstemplates:readList runs launched from this template
POST/templates/:id/runsruns:executeLaunch a run from this template (alias of POST /runs)
POST/templates/:id/duplicatetemplates:writeDuplicate a template
POST/templates/:id/archivetemplates:writeArchive a template
POST/templates/:id/unarchivetemplates:writeUnarchive a template
POST/templates/:id/background-imagetemplates:writeUpload a background image (multipart/form-data)
GET/templates/:id/published-fieldstemplates:readList fields from the published version — the stable IDs to use with /execution/field-values
GET/templates/:id/rules-sync-statustemplates:readCheck background rule-sync progress after publishing with active runs
POST/templates/:id/publishtemplates:publishPublish the draft as a new version
POST/templates/:id/discard-drafttemplates:writeDiscard unpublished draft changes
GET/templates/:id/versionstemplates:readList published versions
GET/templates/:id/versions/:versionIdtemplates:readGet a specific version snapshot
GET/templates/:id/versions/draft-difftemplates:readDiff the current draft against the last published version
GET/templates/:id/versions/:versionId/difftemplates:readDiff two published versions
POST/templates/:id/versions/:versionId/restoretemplates:writeRestore an older version into the draft
GET/templates/:id/taskstemplates:readList draft tasks
POST/templates/:id/taskstemplates:writeAdd a task to the draft
PUT/templates/:id/tasks/:taskIdtemplates:writeUpdate a task
DELETE/templates/:id/tasks/:taskIdtemplates:writeDelete a task
POST/templates/:id/tasks/bulk-deletetemplates:writeDelete multiple tasks
POST/templates/:id/tasks/bulk-duplicatetemplates:writeDuplicate multiple tasks
PATCH/templates/:id/tasks/bulk-updatetemplates:writeBulk-update multiple tasks
POST/templates/:id/tasks/:taskId/fieldstemplates:writeAdd a field to a task
PUT/templates/:id/tasks/:taskId/fields/:fieldIdtemplates:writeUpdate a field
PATCH/templates/:id/tasks/:taskId/fields/:fieldId/movetemplates:writeMove a field to a different task
DELETE/templates/:id/tasks/:taskId/fields/:fieldIdtemplates:writeDelete a field
POST/templates/:id/tasks/:taskId/rulestemplates:writeAdd a conditional logic rule (show/hide/assign/set variable)
PUT/templates/:id/tasks/:taskId/rules/:ruleIdtemplates:writeUpdate a logic rule
PATCH/templates/:id/tasks/:taskId/rules/reordertemplates:writeReorder logic rules
DELETE/templates/:id/tasks/:taskId/rules/:ruleIdtemplates:writeDelete a logic rule
GET/templates/:id/tasks/:taskId/dependenciestemplates:readList a task's dependencies
PUT/templates/:id/tasks/:taskId/dependenciestemplates:writeSet a task's dependencies
GET/templates/:id/tasks/:taskId/dependency-treetemplates:readGet the full dependency tree for a task
GET/templates/:id/phasestemplates:readList phases
POST/templates/:id/phasestemplates:writeCreate a phase
PUT/templates/:id/phases/:phaseIdtemplates:writeUpdate a phase
DELETE/templates/:id/phases/:phaseIdtemplates:writeDelete a phase
GET/templates/:id/variablestemplates:readList flow variables
POST/templates/:id/variablestemplates:writeCreate a flow variable
PUT/templates/:id/variables/:variableIdtemplates:writeUpdate a flow variable
DELETE/templates/:id/variables/:variableIdtemplates:writeDelete a flow variable

Webhooks

Webhooks

Webhooks deliver real-time event notifications to your system. Every delivery is signed with HMAC-SHA256 using a single org-wide signing secret (not returned by this endpoint — see Settings → Integrations → Webhooks), so you can verify payloads genuinely came from Cadenio.

POST/webhookswebhooks:manage

Register a webhook

Registers a new webhook endpoint. url must be HTTPS — plain HTTP and private/loopback/link-local addresses are rejected outright, and the URL is re-validated on every delivery attempt to close DNS-rebind windows.

Parameters

namestringrequired

Display name for this webhook.

urlstringrequired

HTTPS endpoint to deliver event payloads to. Plain HTTP and private/loopback/link-local addresses are rejected.

enabledEventsstring[]required

Events this webhook subscribes to.

run.startedrun.completedrun.cancelledrun.reopenedtask.completedtask.overdueapproval.requestedapproval.grantedapproval.rejected
enabledbooleanoptional

Whether the webhook is active. Default: true.

templateModestringoptional

Scope deliveries to all flows or a selected subset of templates.

ALL_FLOWSSELECTED_TEMPLATES
templateIdsstring[]optional

Template IDs to scope to, when templateMode is SELECTED_TEMPLATES.

descriptionstringoptional

Optional free-text note for your own reference.

Request
curl -X POST https://api.cadenio.com/webhooks \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sync to ERP",
    "url": "https://your-system.com/hooks/cadenio",
    "enabledEvents": ["run.completed", "task.overdue"]
  }'
Payload sample
POST https://your-system.com/hooks/cadenio
content-type: application/json
x-flow-timestamp: 1785005000000
x-flow-signature: 6f9b1c...  (hex HMAC-SHA256)

{
  "event": "run.completed",
  "deliveryId": "9b1e2c3d-...",
  "timestamp": "2026-07-24T16:05:00Z",
  "orgId": "0c861a32-d927-47d7-a8f5-861a4adf28ed",
  "data": {
    "runId": "3ed4dcf7-a102-4327-81ab-723b34d8a6b5",
    "templateId": "6795dfb5-15de-4f41-8a96-b83830526ca6"
  }
}
Verify signature (Node.js)
const crypto = require("crypto");

function isValid(req, secret) {
  const timestamp = req.headers["x-flow-timestamp"];
  const signature = req.headers["x-flow-signature"];
  const body = JSON.stringify(req.body); // raw body, exactly as received
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${body}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

// The signing secret is a single org-wide value (WEBHOOK_SIGNING_SECRET),
// shared across all of your org's webhooks — not returned per-webhook by
// this endpoint. Find it under Settings → Integrations → Webhooks.
MethodEndpointScopeDescription
GET/webhookswebhooks:manageList webhooks
GET/webhooks/deliverieswebhooks:manageList recent deliveries across all webhooks
GET/webhooks/:idwebhooks:manageGet a webhook
PATCH/webhooks/:idwebhooks:manageUpdate a webhook (URL is re-validated)
DELETE/webhooks/:idwebhooks:manageDelete a webhook
POST/webhooks/:id/testwebhooks:manageSend a test delivery
GET/webhooks/:id/deliverieswebhooks:manageList deliveries for one webhook

Files

Files

Upload and download files attached to run tasks. Direct uploads must be tied to a specific FILE_UPLOAD/SIGNATURE field's execution entry; large uploads can instead use a presigned upload-url + confirm flow.

MethodEndpointScopeDescription
POST/files/direct-uploadfiles:writeUpload a file (multipart/form-data) and attach it to a task's execution entry in one call
POST/files/upload-urlfiles:writeGet a presigned upload URL for large files (step 1 of 2)
POST/files/confirmfiles:writeConfirm a presigned upload finished (step 2 of 2)
GET/files/:id/downloadfiles:readGet a presigned download URL for a file
GET/files/:id/thumbnailfiles:readGet a thumbnail URL for an image/video attachment
GET/files/:id/scan-statusfiles:readCheck the antivirus scan status of an upload
POST/files/bulk-download-zipfiles:readDownload multiple files as a single ZIP
GET/filesfiles:readList files attached to a field/execution entry
DELETE/files/:idfiles:writeDelete a file
POST/files/template-assetfiles:writeUpload a template-level image asset (e.g. an IMAGE field's picture)
GET/files/template-asset/download-urlfiles:readGet a download URL for a template asset

Data sources

Data sources

Structured tables used to populate form fields (DATA_SOURCE / lookup fields) and drive conditional logic. Rows are made of typed cells; bulk row operations are atomic — a single invalid row rejects the whole batch.

MethodEndpointScopeDescription
GET/data-sourcesdata-sources:readList data sources
POST/data-sourcesdata-sources:writeCreate a data source (name + column names)
GET/data-sources/:iddata-sources:readGet a data source and its columns
PATCH/data-sources/:iddata-sources:writeUpdate a data source's name/description
DELETE/data-sources/:iddata-sources:writeDelete a data source
POST/data-sources/:id/columnsdata-sources:writeAdd a column. Types: TEXT, DATE, DATETIME, NUMBER, BOOLEAN, STATUS, RELATION
PATCH/data-sources/:id/columns/:columnIddata-sources:writeUpdate a column (name, type, or config)
DELETE/data-sources/:id/columns/:columnIddata-sources:writeDelete a column
PATCH/data-sources/:id/columns/reorderdata-sources:writeReorder columns
GET/data-sources/:id/rowsdata-sources:readList rows (supports search, active-only, and column filters)
GET/data-sources/:id/rows/:rowIddata-sources:readGet a single row
POST/data-sources/:id/rowsdata-sources:writeCreate a row
POST/data-sources/:id/rows/bulkdata-sources:writeBulk-create rows (up to the org's row limit)
PATCH/data-sources/:id/rows/:rowIddata-sources:writeUpdate a row's cell values
POST/data-sources/:id/rows/bulk-updatedata-sources:writeApply the same cell update to multiple rows atomically
DELETE/data-sources/:id/rows/:rowIddata-sources:writeDelete a row
POST/data-sources/:id/rows/bulk-deletedata-sources:writeDelete multiple rows atomically
GET/data-sources/:id/rows/:rowId/impactdata-sources:readSee where a row is referenced (runs, other rows)
GET/data-sources/:id/rows/:rowId/timelinedata-sources:readGet a row's change history
GET/data-sources/:id/rows/:rowId/relationsdata-sources:readList RELATION links to/from a row
POST/data-sources/:id/relationsdata-sources:writeLink two rows via a RELATION column
DELETE/data-sources/:id/relationsdata-sources:writeRemove a link between two rows
GET/data-sources/:id/lookupdata-sources:readLook up rows for a DATA_SOURCE-type template field

Data source triggers

Data source triggers

Automation triggers that fire when a data source row matches a condition (most commonly a DATE column reaching today) — the backbone of scheduled/recurring automations built on top of a data source.

MethodEndpointScopeDescription
GET/data-source-triggersdata-sources:readList automation triggers
POST/data-source-triggersdata-sources:writeCreate a trigger (e.g. fire when a DATE column is reached)
GET/data-source-triggers/:iddata-sources:readGet a trigger
PATCH/data-source-triggers/:iddata-sources:writeUpdate a trigger
DELETE/data-source-triggers/:iddata-sources:writeDelete a trigger
GET/data-source-triggers/:id/firingsdata-sources:readList past firings for a trigger
POST/data-source-triggers/:id/dry-rundata-sources:readPreview which rows would fire right now, without dispatching

Saved views

Saved views

Named, reusable run filter sets — the same filters available in the Runs UI, saved server-side so a dashboard or scheduled report can reference them by ID instead of re-encoding the filter logic.

MethodEndpointScopeDescription
GET/saved-viewsruns:readList saved views
POST/saved-viewsruns:readCreate a saved view (a stored run filter set)
GET/saved-views/:idruns:readGet a saved view
PATCH/saved-views/:idruns:readUpdate a saved view
DELETE/saved-views/:idruns:readDelete a saved view
POST/saved-views/previewruns:readPreview run counts for a filter set without saving it
GET/saved-views/:id/runsruns:readList the runs matching a saved view

Shared templates

Shared templates

Cross-organization template sharing via a public token: publish a share link, let another org preview and import your template as their own independent copy.

MethodEndpointScopeDescription
POST/templates/:templateId/sharestemplates:writeCreate a shareable link/token for a template
GET/templates/:templateId/sharestemplates:readList shares for a template
PATCH/shared-templates/:shareIdtemplates:writeUpdate a share
POST/shared-templates/:shareId/refreshtemplates:writeRotate a share's token
DELETE/shared-templates/:shareIdtemplates:writeRevoke a share
GET/shared-templates/:token/previewtemplates:readPreview a shared template by its public token
POST/shared-templates/:token/importtemplates:writeImport a shared template into your org as a new template

Portal

Portal

Customer-facing portal builder: pages made of content blocks (including live report widgets), access rules per user/group, and a published public view served at a slug.

MethodEndpointScopeDescription
GET/portalstemplates:readList portals
POST/portalstemplates:writeCreate a portal
GET/portals/metemplates:readGet the portal(s) the caller can access
GET/portals/:portalIdtemplates:readGet a portal
PATCH/portals/:portalIdtemplates:writeUpdate a portal
DELETE/portals/:portalIdtemplates:writeDelete a portal
POST/portals/:portalId/publishtemplates:writePublish a portal
POST/portals/:portalId/unpublishtemplates:writeUnpublish a portal
GET/portals/by-slug/:slug/viewtemplates:readGet a published portal's content by its public slug
GET/portals/:portalId/pagestemplates:readList a portal's pages
POST/portals/:portalId/pagestemplates:writeCreate a page
GET/portals/:portalId/pages/:pageIdtemplates:readGet a page
PATCH/portals/:portalId/pages/:pageIdtemplates:writeUpdate a page
DELETE/portals/:portalId/pages/:pageIdtemplates:writeDelete a page
PUT/portals/:portalId/pages/:pageId/blockstemplates:writeReplace a page's content blocks
POST/portals/:portalId/pages/:pageId/publish-changestemplates:writePublish a single page's pending changes
GET/portals/:portalId/access-rulestemplates:readList access rules
POST/portals/:portalId/access-rulestemplates:writeGrant a user/group access to the portal
DELETE/portals/:portalId/access-rules/:ruleIdtemplates:writeRevoke an access rule
GET/portals/report-presetstemplates:readList saved report presets
POST/portals/report-presetstemplates:writeSave a report preset
DELETE/portals/report-presets/:presetIdtemplates:writeDelete a report preset

Users

Users

Read the organization member list. Use member IDs to assign runs and tasks via the Runs API.

MethodEndpointScopeDescription
GET/usersusers:readList organization members

API key management

Managing API keys

API keys are created and revoked from Settings → Integrations → API Keys. Each key has a name, a set of scopes, an optional expiry date, and a resource mode (all templates/folders, or a selected subset). Only organization owners and privileged admins can manage keys. The full key value is shown only once, at creation.

Important: These endpoints require session-based authentication (browser cookie), not an API key. An API key cannot manage other API keys — treat this as a dashboard-only operation.

Endpoints

GET/api-keysList active API keys
POST/api-keysCreate a new API key
DELETE/api-keys/:idRevoke an API key

Create parameters

namestringrequired

Display name for this key.

scopesstring[]required

Permission scopes granted to this key. See the Scopes reference.

resourceModestringoptional

Which templates/folders this key can reach. Default: ALL.

ALLSELECTED_TEMPLATESSELECTED_FOLDERS
scopedTemplateIdsstring[]optional

Template IDs accessible to this key when resourceMode is SELECTED_TEMPLATES.

scopedFolderIdsstring[]optional

Folder IDs accessible to this key (and every template inside them) when resourceMode is SELECTED_FOLDERS.

expiresAtdatetimeoptional

ISO 8601 timestamp after which the key is automatically rejected. Default: never expires.

Request
curl -X POST https://api.cadenio.com/api-keys \
  -H "Cookie: flow_session=...; flow_csrf=..." \
  -H "x-cadenio-csrf: ..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ERP Sync Integration",
    "scopes": ["runs:read", "runs:execute"],
    "resourceMode": "ALL"
  }'
Response
HTTP/1.1 201 Created

{
  "id": "1105c74c-bc73-4d7c-b9b0-c88ca1824a5f",
  "name": "ERP Sync Integration",
  "keyPrefix": "sk_live_...93f7",
  "scopes": ["runs:read", "runs:execute"],
  "resourceMode": "ALL",
  "scopedTemplateIds": [],
  "scopedFolderIds": [],
  "status": "ACTIVE",
  "expiresAt": null,
  "createdAt": "2026-07-24T16:41:11Z",
  "plainKey": "sk_live_beda794d400a159f4214c69965412267bacfb9eafc8893f7"
}

// plainKey is shown only in this response, store it securely.

Public API access requires the Business plan or higher

API keys, scoped permissions, webhooks, and programmatic access to runs, templates, and data sources are available on the Business and Enterprise plans. Talk to us to enable it for your organization.