REST API Reference

The WEXTL REST v1 API — versioned, frozen-additive, and machine-readable via a single OpenAPI document.

AI-assisted documentation

This documentation is compiled from our own product source code and internal specs, the platform's public API specification, and anonymized requests logs we collect from our support team[2].

text
GET /api/v1/openapi.json
  1. WEXTL® REST v1 API — our own source implementation.
  2. Our users' real API integrations and automations.
  3. The machine-readable OpenAPI specification for the REST API.

Workflows

13endpoints
GET/workflowsAuth required

List workflows (bounded, cursor-paginated).

NameInTypeDescription
cursorquerystringOpaque continuation token from a previous response.
limitqueryintegerPage size. Default 50.
qquerystringFree-text search on name + description.
statusquerystring—
folderIdquerystringRestrict to this folder and its descendants.
sortByquerystring—
sortDirquerystring—
tagIdsquerystringComma-separated tag ids.
tagMatchquerystring—
200A page of workflow summaries.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<WorkflowSummary>—
next_cursor*—string | null—
data[] item (WorkflowSummary)
NameInTypeDescription
id*—string—
name*—string—
active*—boolean—
folderId—string | null—
nodeCount—integer—
tagIds—array<string>—
createdAt—integerEpoch milliseconds.
updatedAt—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "active": true,
      "folderId": "fld_01HXEXAMPLE",
      "nodeCount": 3,
      "tagIds": [
        "..."
      ],
      "createdAt": 1719792000000,
      "updatedAt": 1719792000000
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/workflows \
  -H "Authorization: Bearer wextl_..."
POST/workflowsAuth required

Create a new, empty (draft) workflow. Build its graph via POST .../ops afterwards.

NameInTypeDescription
name*bodystring—
folderIdbodystring | nullMust reference an accessible folder.
teamIdbodystring | nullMust belong to the caller's org. Omit to use the org's default team.
201The created (empty) draft workflow.
400Invalid body — missing/oversized name, or an unresolvable folderId/teamId.
401No valid bearer token.
403Missing workflow:write scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—WorkflowCreateResult—
data shape (WorkflowCreateResult)
NameInTypeDescription
id*—string—
name*—string—
teamId*—string—
folderId—string | null—
active*—boolean—
createdAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "teamId": "team_01HXEXAMPLE",
    "active": true,
    "createdAt": 1719792000000,
    "folderId": "fld_01HXEXAMPLE"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "folderId": "fld_01HXEXAMPLE",
  "teamId": "team_01HXEXAMPLE"
}'
GET/workflows/{id}Auth required

Read a workflow's full DRAFT graph, or its deployed snapshot via ?view=deployed.

NameInTypeDescription
id*pathstring—
viewquerystringOmit for the current draft. `deployed` reads the last Go Live snapshot; 404 workflow_not_deployed if never published.
200The workflow (draft or deployed, per ?view).
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Workflow not found (or, with ?view=deployed, never deployed — workflow_not_deployed).
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—one of 2 shapes—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "active": true,
    "nodes": [
      {
        "id": 12,
        "appId": "slack",
        "name": "Send a message",
        "moduleSlug": "sendMessage",
        "x": 420,
        "y": 180,
        "params": {
          "channel": "#general",
          "text": "Deployment finished."
        },
        "connectionId": "oauth2",
        "credentialId": "cred_01HXEXAMPLE"
      }
    ],
    "edges": [
      {
        "id": "e_12_18",
        "from": 12,
        "to": 18,
        "type": "normal",
        "order": 0
      }
    ],
    "description": "...",
    "folderId": "fld_01HXEXAMPLE",
    "teamId": "team_01HXEXAMPLE",
    "schedule": {
      "recurrence": {
        "kind": "interval",
        "every": 15,
        "unit": "min",
        "timezone": "Europe/London",
        "skipIfRunning": true
      },
      "executionTimeoutMs": 0
    },
    "createdAt": 1719792000000,
    "updatedAt": 1719792000000,
    "deployed": {
      "deployedAt": 1719792000000,
      "versionNo": 0,
      "contentHash": "..."
    }
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
PATCH/workflows/{id}Auth required

Curated update: name, active, schedule (recurrence), and/or folderId.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
activebodybooleanActivate or deactivate the workflow.
recurrencebodyScheduleRecurrenceSchedule recurrence object, or null to clear. Setting a schedule does not activate.
folderIdbodystring | nullMove into folder; null to unassign.
200Fields that were updated.
400Invalid body.
401No valid bearer token.
403Missing workflow:write scope.
404Workflow not found.
409Conflict — re-read and retry.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—object—
data shape (object)
NameInTypeDescription
id—string—
updated—array<string>—
name—string—
active—boolean—
folderId—string | null—
Example response
json
{
  "data": {
    "id": "abc123",
    "updated": [
      "..."
    ],
    "name": "My workflow",
    "active": true,
    "folderId": "fld_01HXEXAMPLE"
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "active": true,
  "recurrence": {
    "kind": "interval",
    "every": 15,
    "unit": "min",
    "timezone": "Europe/London",
    "skipIfRunning": true
  },
  "folderId": "fld_01HXEXAMPLE"
}'
DELETE/workflows/{id}Auth required

Permanently delete a workflow. Refused while active or deployed.

NameInTypeDescription
id*pathstring—
200Deleted.
401No valid bearer token.
403Missing workflow:write scope.
404Workflow not found.
409Workflow is active or deployed — deactivate/undeploy first.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
POST/workflows/{id}/opsAuth required

Apply a batch of graph operations to a workflow.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
ops*bodyarray<object>Batch of GraphOp objects. One of: add_node, update_params, update_config, connect, disconnect, remove_node, rename_node, set_credential, set_edge_filter.
expectedUpdatedAt*bodyintegerREQUIRED optimistic-concurrency precondition — the workflow `updatedAt` this batch was computed against (take it from a prior GET /workflows/{id}). Mismatch → 409 workflow_modified. Without it two agents editing the same workflow silently overwrite each other, since a batch replaces the whole nodes/edges set; omitting it is rejected with 400 VALIDATION_ERROR.
200The batch result — best-effort; a non-empty errors[] does not mean the whole batch was rejected.
400Invalid body, or the resulting graph fails the topology gate.
401No valid bearer token.
403Missing workflow:write scope, or the plan lacks API access.
404Workflow not found.
409workflow_modified — expectedUpdatedAt no longer matches; reload and retry.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—GraphOpsResult—
data shape (GraphOpsResult)
NameInTypeDescription
applied*—objecttempId → real node id, for every add_node that landed.
errors*—array<string>Best-effort per-op failures — the rest of the batch still applies.
touched*—array<integer>Node ids added or param/config-updated by this batch, including hub-scaffolded satellite/placeholder ids.
updatedAt—integerThe workflow's new updatedAt — pass it as expectedUpdatedAt on the next ops call to avoid conflicts.
Example response
json
{
  "data": {
    "applied": {
      "tmp_1": "42",
      "tmp_2": "43"
    },
    "errors": [
      "..."
    ],
    "touched": [
      0
    ],
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/ops \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "ops": [
    {
      "op": "..."
    }
  ],
  "expectedUpdatedAt": 1719792000000
}'
POST/workflows/{id}/deployAuth required

Go Live — publish the current draft as the deployed snapshot (idempotent).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
expectedUpdatedAtbodyintegerOptimistic-concurrency precondition — the draft updatedAt this deploy was computed against. Mismatch → 409 workflow_modified.
200The new deployed snapshot summary.
401No valid bearer token.
403Missing workflow:write scope, or the plan lacks API access.
404Workflow not found.
409workflow_modified — expectedUpdatedAt no longer matches; reload and retry.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—DeployResult—
data shape (DeployResult)
NameInTypeDescription
workflowId*—string—
contentHash*—string—
versionNo*—integer—
deployedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "workflowId": "wf_01HXEXAMPLE",
    "contentHash": "...",
    "versionNo": 0,
    "deployedAt": 1719792000000
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/deploy \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "expectedUpdatedAt": 1719792000000
}'
POST/workflows/{id}/validateAuth required

Validate a workflow's structure (duplicate ids, orphan edges, cycles, trigger placement). Run this before declaring a workflow correct.

NameInTypeDescription
id*pathstring—
200The validation result.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Workflow not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—ValidateWorkflowResult—
data shape (ValidateWorkflowResult)
NameInTypeDescription
valid*—boolean—
issues*—array<string>Human-readable validation problems. Empty when valid is true.
Example response
json
{
  "data": {
    "valid": false,
    "issues": [
      "Node 7 has no incoming edges and is not the trigger."
    ]
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/validate \
  -H "Authorization: Bearer wextl_..."
POST/workflows/{id}/resolve-expressionAuth required

Resolve a {{expr}} template against a node's available input data from the latest (or a specific) run — validates references like {{4.user_id}} before wiring them.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
expression*bodystringThe expression template, e.g. '{{3.rows[0].name}}' or bare '3.rows[0].name'.
fromNodeIdbodystringThe node id that uses this expression — helps locate its upstream nodes from the latest run.
runIdbodystringOptional run id to use for sample data. Defaults to the most recent run.
200The resolution attempt — resolved is null with error set when it could not be resolved (e.g. no runs yet).
400expression is required.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Workflow not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—ResolveExpressionResult—
data shape (ResolveExpressionResult)
NameInTypeDescription
resolved*—anyThe resolved value (any JSON type), or null when resolution failed or no run data exists yet.
resolvedType—stringtypeof the resolved value, e.g. "string", "number", "object". Absent when resolved is null.
truncated—booleantrue when a large resolved string value was cut to fit the response budget.
error*—string | nullPresent when resolution failed, or when no runs exist yet for this workflow.
Example response
json
{
  "data": {
    "resolved": "user_42",
    "resolvedType": "string",
    "error": null
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/resolve-expression \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "expression": "{{3.rows[0].name}}",
  "fromNodeId": "4"
}'
POST/workflows/{id}/webhookAuth required

Mint (or return the existing) inbound webhook URL for a workflow trigger node.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
nodeId*bodystringThe webhook trigger node id (numeric id as a string).
200The webhook URL (idempotent — alreadyBound:true when a live one already existed).
400Missing nodeId, or the node is not a webhook trigger node.
401No valid bearer token.
403Missing webhook:write scope, or the plan lacks API access.
404Workflow or node not found.
409The node already has a DISABLED webhook record bound to it.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Webhook—
data shape (Webhook)
NameInTypeDescription
webhookId*—string—
url*—stringThe inbound URL to POST trigger payloads to.
alreadyBound—boolean—
Example response
json
{
  "data": {
    "webhookId": "wh_01HXEXAMPLE",
    "url": "https://eu1.wextl.com/hooks/wh_01HXEXAMPLE",
    "alreadyBound": true
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/webhook \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "nodeId": "abc123"
}'
POST/workflows/{id}/runsAuth required

Start a run of the workflow's current draft (billing and structure checks apply).

NameInTypeDescription
id*pathstring—
Idempotency-KeyheaderstringOptional but strongly recommended when the client may retry. A caller-chosen unique string; retrying with the same key returns the SAME run rather than starting another. Without it a timeout-and-retry starts a second run, double-charging credits and repeating any external side effects the workflow performs.
NameInTypeDescription
nodeIdbodystringOptional node id (numeric id as a string) to run from — a scoped run. Omit for a full-graph run.
upstreamOutputsbodyobjectOptional nodeId→payload map to seed as upstream inputs. Mutually exclusive with seedFromRun.
seedFromRunbodyobjectSeed from a past run node output (server-resolved). Mutually exclusive with upstreamOutputs.
201The run was created and enqueued.
400Invalid nodeId/inputs, or the workflow fails the topology gate (e.g. no runnable path).
401No valid bearer token.
402Payment required — billing problem blocking runs.
403Missing workflow:write scope, no active plan, or out of credits (PLAN_LIMIT_EXCEEDED).
404Workflow not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—StartRunResult—
data shape (StartRunResult)
NameInTypeDescription
runId*—string—
Example response
json
{
  "data": {
    "runId": "run_01HXEXAMPLE"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/runs \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "nodeId": "abc123",
  "upstreamOutputs": {
    "12": {
      "message": "Hello world",
      "channel": "#general"
    }
  },
  "seedFromRun": {
    "runId": "run_01HXEXAMPLE",
    "nodeId": 0
  }
}'
PUT/workflows/{id}/tagsAuth required

Replace the full tag set on a workflow.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
tagIds*bodyarray<string>—
200Tags assigned.
400Invalid body.
401No valid bearer token.
403Missing workflow:write scope.
404Workflow not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—SetWorkflowTagsResult—
data shape (SetWorkflowTagsResult)
NameInTypeDescription
ok*—boolean—
tagIds*—array<string>—
Example response
json
{
  "data": {
    "ok": true,
    "tagIds": [
      "tag_01HXEXAMPLE"
    ]
  }
}
Example request
bash
curl -X PUT https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/tags \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "tagIds": [
    "..."
  ]
}'
POST/workflows/{id}/test-moduleAuth required

Execute a single app node with its current parameters (module test).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
nodeId*bodyone of 2 shapes—
200Module test result.
400Invalid body or non-app node.
401No valid bearer token.
403Missing workflow:write scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—objectThe node's module output on success. Shape depends on the module — the same shape a real run's node output would have.
Example response
json
{
  "data": {
    "ok": true,
    "ts": "1719792000.000100",
    "channel": "#general"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/workflows/wf_01HXEXAMPLE/test-module \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "nodeId": "abc123"
}'

Variables

4endpoints
GET/variablesAuth required

List variable names and metadata for the organization (up to 500). Secret values are always returned as null.

200Every variable visible to this key.
401No valid bearer token.
403Missing variable:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Variable>—
data[] item (Variable)
NameInTypeDescription
id*—string—
name*—string—
isSecret*—boolean—
value*—string | null—
teamId*—string | null—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "isSecret": false,
      "value": null,
      "teamId": "team_01HXEXAMPLE",
      "createdAt": 1719792000000,
      "updatedAt": 1719792000000
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/variables \
  -H "Authorization: Bearer wextl_..."
GET/variables/{id}Auth required

Read one variable by id. A secret variable's value is always returned as null.

NameInTypeDescription
id*pathstring—
200The variable (value is null when isSecret is true).
401No valid bearer token.
403Missing variable:read scope, or the plan lacks API access.
404Variable not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Variable—
data shape (Variable)
NameInTypeDescription
id*—string—
name*—string—
isSecret*—boolean—
value*—string | null—
teamId*—string | null—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "isSecret": false,
    "value": null,
    "teamId": "team_01HXEXAMPLE",
    "createdAt": 1719792000000,
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/variables/var_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
PUT/variables/{id}Auth required

Create or update a variable by name (upsert) — the {id} path segment IS the variable name, not a database id. Secrets are write-only.

NameInTypeDescription
id*pathstringThe variable name (letters/numbers/underscores, must start with a letter or underscore) — this call upserts by name.
NameInTypeDescription
value*bodystringRequired for a new non-secret variable. For an existing secret, a blank value keeps the current stored value.
isSecretbodybooleanWhether this variable is a secret. Only takes effect on create — updating an existing variable never changes its stored secret status.
teamIdbodystring | nullMust belong to the caller's org. Omit for an org-level variable.
200An existing variable was updated.
201A new variable was created.
400Invalid body — bad name, missing value, a secret shorter than 6 characters, or an unresolvable teamId.
401No valid bearer token.
403Missing variable:write scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—SetVariableResult—
data shape (SetVariableResult)
NameInTypeDescription
id*—string—
name*—string—
isSecret*—boolean—
teamId*—string | null—
updatedAt*—integerEpoch milliseconds.
created*—booleantrue when this call created a new variable, false when it updated an existing one.
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "isSecret": false,
    "teamId": "team_01HXEXAMPLE",
    "updatedAt": 1719792000000,
    "created": true
  }
}
Example request
bash
curl -X PUT https://eu1.wextl.com/api/v1/variables/var_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "value": null,
  "isSecret": false,
  "teamId": "team_01HXEXAMPLE"
}'
DELETE/variables/{id}Auth required

Soft-delete a variable by database id (not name).

NameInTypeDescription
id*pathstringThe variable database id from list_variables / get_variable.
200Deleted.
401No valid bearer token.
403Missing variable:write scope.
404Variable not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/variables/var_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."

Runs

6endpoints
GET/runsAuth required

List runs of a workflow (bounded, cursor-paginated). workflowId is REQUIRED in v1 — org-wide listing is out of scope.

NameInTypeDescription
workflowId*querystringREQUIRED — scope the listing to this workflow.
cursorquerystring—
limitqueryintegerPage size. Default 50.
qquerystringFree-text search over status + id.
200A page of run summaries.
400workflowId query parameter is required.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<RunSummary>—
next_cursor*—string | null—
data[] item (RunSummary)
NameInTypeDescription
id*—string—
workflowId*—string | null—
status*—string—
createdAt*—string | nullISO-8601 timestamp.
finishedAt—string | nullISO-8601 timestamp; null while the run is non-terminal.
creditsUsed*—number—
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "workflowId": "wf_01HXEXAMPLE",
      "status": "succeeded",
      "createdAt": "2024-07-01T12:00:00.000Z",
      "creditsUsed": 50,
      "finishedAt": null
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/runs \
  -H "Authorization: Bearer wextl_..."
GET/runs/{id}Auth required

Get a run report: status, timestamps, error, and per-node status/error/output.

NameInTypeDescription
id*pathstring—
200The run report.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Run not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—RunReport—
data shape (RunReport)
NameInTypeDescription
id*—string—
workflowId—string—
status*—string—
createdAt—string | null—
finishedAt—string | null—
error—string | null—
nodes—array<RunNode>—
Example response
json
{
  "data": {
    "id": "abc123",
    "status": "succeeded",
    "workflowId": "wf_01HXEXAMPLE",
    "createdAt": "2024-07-01T12:00:00.000Z",
    "finishedAt": null,
    "error": null,
    "nodes": [
      {
        "nodeId": 12,
        "label": "Send a message",
        "status": "completed",
        "output": {
          "ok": true,
          "ts": "1719792000.000100"
        }
      }
    ]
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/runs/run_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
POST/runs/{id}/cancelAuth required

Cancel an in-flight workflow run.

NameInTypeDescription
id*pathstring—
200The run was cancelled.
400The run is already in a terminal state.
401No valid bearer token.
403Missing workflow:write scope, or the plan lacks API access.
404Run not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—CancelRunResult—
data shape (CancelRunResult)
NameInTypeDescription
ok*—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/runs/run_01HXEXAMPLE/cancel \
  -H "Authorization: Bearer wextl_..."
POST/runs/{id}/rerunAuth required

Re-queue a finished run as a new attempt.

NameInTypeDescription
id*pathstring—
201New attempt enqueued.
401No valid bearer token.
403Missing workflow:write scope.
404Run not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—RerunResult—
data shape (RerunResult)
NameInTypeDescription
runId*—string—
status*—string—
attemptNumber*—integer—
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "runId": "run_01HXEXAMPLE",
    "status": "queued",
    "attemptNumber": 2,
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/runs/run_01HXEXAMPLE/rerun \
  -H "Authorization: Bearer wextl_..."
POST/runs/{id}/retry-nodeAuth required

Resume a run from one failed node (same attempt).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
nodeId*bodyinteger—
attemptNumberbodyinteger—
200Resume enqueued.
400Invalid body.
401No valid bearer token.
403Missing workflow:write scope.
404Run not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—RetryNodeResult—
data shape (RetryNodeResult)
NameInTypeDescription
runId*—string—
status*—string—
attemptNumber*—integer—
nodeId*—integer—
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "runId": "run_01HXEXAMPLE",
    "status": "running",
    "attemptNumber": 1,
    "nodeId": 12,
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/runs/run_01HXEXAMPLE/retry-node \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "nodeId": 0,
  "attemptNumber": 0
}'
POST/runs/{id}/nodes/{nodeId}/respondAuth required

Submit a human-in-the-loop response and resume (or complete) the run.

NameInTypeDescription
id*pathstring—
nodeId*pathstring—
NameInTypeDescription
response*bodyobjectThe HITL response fields — shape depends on the node's configured response fields.
attemptNumberbodyinteger—
200Response recorded.
400Invalid body.
401No valid bearer token.
402Payment required for mid-flow resume.
403Missing workflow:write scope.
404Run not found.
409Conflict — resume already in flight or run terminal.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—RespondNodeResult—
data shape (RespondNodeResult)
NameInTypeDescription
ok*—boolean—
resumed*—booleantrue when the run resumed execution past this node.
terminal*—booleantrue when this response completed the run (no further nodes to run).
Example response
json
{
  "data": {
    "ok": true,
    "resumed": true,
    "terminal": false
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/runs/run_01HXEXAMPLE/nodes/node_1/respond \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "response": {
    "approved": true,
    "comment": "Looks good, ship it."
  },
  "attemptNumber": 0
}'

Credentials

6endpoints
GET/credentialsAuth required

List the organization's stored credentials (names and metadata only; secret payloads are never returned).

NameInTypeDescription
cursorquerystring—
limitqueryintegerPage size. Default 50.
appIdquerystringOptional app id to filter by.
200A page of credential summaries.
401No valid bearer token.
403Missing credential:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Credential>—
next_cursor*—string | null—
data[] item (Credential)
NameInTypeDescription
id*—string—
name*—string—
appId*—string—
type*—stringThe connection type id.
status*—string—
folderId—string | null—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "appId": "slack",
      "type": "oauth2",
      "status": "succeeded",
      "createdAt": 1719792000000,
      "updatedAt": 1719792000000,
      "folderId": "fld_01HXEXAMPLE"
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/credentials \
  -H "Authorization: Bearer wextl_..."
POST/credentialsAuth required

Create a credential when safe (no-auth or secrets already supplied). OAuth or missing secrets return status credential_required with a connect_url for a logged-in human.

NameInTypeDescription
appId*bodystring—
connectionId*bodystring—
name*bodystring—
databodyobjectSecret field values when the caller already has them — keyed by the connection's parameter names (from get_module_spec / the connection spec), e.g. an api-key connection's `apiKey`. Never invent placeholders when calling this for real — the value shown here is illustrative only.
teamIdbodystring | null—
200Created credential or credential_required handoff.
400Invalid body.
401No valid bearer token.
403Missing credential:write scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—CredentialCreateResult—
data shape (CredentialCreateResult)
NameInTypeDescription
credentialId—string—
status—string—
appId—string—
connectionId—string—
connect_url—string—
Example response
json
{
  "data": {
    "credentialId": "abc123",
    "status": "succeeded",
    "appId": "slack",
    "connectionId": "abc123",
    "connect_url": "..."
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/credentials \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "appId": "slack",
  "connectionId": "abc123",
  "name": "My workflow",
  "data": {
    "apiKey": "sk_live_your_api_key_here"
  },
  "teamId": "team_01HXEXAMPLE"
}'
PATCH/credentials/{id}Auth required

Rename a credential or move its folder (never returns secrets).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
folderIdbodystring | null—
200Updated credential summary.
400Invalid body.
401No valid bearer token.
403Missing credential:write scope.
404Credential not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Credential—
data shape (Credential)
NameInTypeDescription
id*—string—
name*—string—
appId*—string—
type*—stringThe connection type id.
status*—string—
folderId—string | null—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "appId": "slack",
    "type": "oauth2",
    "status": "succeeded",
    "createdAt": 1719792000000,
    "updatedAt": 1719792000000,
    "folderId": "fld_01HXEXAMPLE"
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/credentials/cred_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "folderId": "fld_01HXEXAMPLE"
}'
DELETE/credentials/{id}Auth required

Soft-delete a credential.

NameInTypeDescription
id*pathstring—
200Deleted.
401No valid bearer token.
403Missing credential:write scope.
404Credential not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/credentials/cred_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
POST/credentials/{id}/verifyAuth required

Test whether a stored credential is accepted by the third-party service (never returns the secret).

NameInTypeDescription
id*pathstring—
200Verification outcome.
401No valid bearer token.
403Missing credential:use scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—one of 2 shapes—
Example response
json
{
  "data": {
    "status": "ok"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/credentials/cred_01HXEXAMPLE/verify \
  -H "Authorization: Bearer wextl_..."
POST/credentials/dynamic-optionsAuth required

Fetch live RPC-backed field options (tables, channels, sheets, …).

NameInTypeDescription
appId*bodystring—
rpcId*bodystring—
credentialIdbodystring—
paramsbodyobjectOptional dependency parameters for nested RPCs, e.g. { "tableId": "users" } to get columns for a table.
200Option items.
400Invalid body.
401No valid bearer token.
403Missing credential:use scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—DynamicOptionsResult—
data shape (DynamicOptionsResult)
NameInTypeDescription
items*—array<object>—
truncated—booleantrue when the result was capped at 200 items.
total—integerPresent only when truncated.
Example response
json
{
  "data": {
    "items": [
      {
        "value": "C0123ABCDE",
        "label": "#general"
      },
      {
        "value": "C0456FGHIJ",
        "label": "#engineering"
      }
    ]
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/credentials/dynamic-options \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "appId": "slack",
  "rpcId": "abc123",
  "credentialId": "abc123",
  "params": {
    "tableId": "users"
  }
}'

Databases

6endpoints
GET/databasesAuth required

List the organization's built-in database tables.

NameInTypeDescription
limitqueryinteger—
200Database table summaries.
401No valid bearer token.
403Missing database:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<DatabaseSummary>—
truncated*—boolean—
data[] item (DatabaseSummary)
NameInTypeDescription
id*—string—
name*—string—
columnCount*—integer—
rowCount*—integer—
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "columnCount": 3,
      "rowCount": 3
    }
  ],
  "truncated": true
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/databases \
  -H "Authorization: Bearer wextl_..."
POST/databasesAuth required

Create a built-in database table (DDL). Row writes are not available on the public API.

NameInTypeDescription
name*bodystring—
descriptionbodystring—
columns*bodyarray<DatabaseColumnInput>—
teamIdbodystring | null—
201Created table with generated column ids.
400Invalid body.
401No valid bearer token.
403Missing database:write scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—DatabaseSchema—
data shape (DatabaseSchema)
NameInTypeDescription
id*—string—
name*—string—
columns*—array<object>—
rowCount*—integer—
uniqueKeyColumnId—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "columns": [
      {
        "id": "abc123",
        "name": "My workflow",
        "type": "action",
        "required": true,
        "indexed": true
      }
    ],
    "rowCount": 3,
    "uniqueKeyColumnId": "abc123"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/databases \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "columns": [
    {
      "name": "Status",
      "type": "select",
      "required": false,
      "indexed": true
    }
  ],
  "description": "...",
  "teamId": "team_01HXEXAMPLE"
}'
GET/databases/{id}Auth required

Read one database table's column schema.

NameInTypeDescription
id*pathstring—
200Schema projection.
401No valid bearer token.
403Missing database:read scope, or the plan lacks API access.
404Database not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—DatabaseSchema—
data shape (DatabaseSchema)
NameInTypeDescription
id*—string—
name*—string—
columns*—array<object>—
rowCount*—integer—
uniqueKeyColumnId—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "columns": [
      {
        "id": "abc123",
        "name": "My workflow",
        "type": "action",
        "required": true,
        "indexed": true
      }
    ],
    "rowCount": 3,
    "uniqueKeyColumnId": "abc123"
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/databases/db_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
PATCH/databases/{id}Auth required

Replace a table's column definitions with the full desired list (declarative).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
columns*bodyarray<DatabaseColumnInput>—
200Updated schema.
400Invalid body.
401No valid bearer token.
403Missing database:write scope, or the plan lacks API access.
404Database not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—DatabaseSchema—
data shape (DatabaseSchema)
NameInTypeDescription
id*—string—
name*—string—
columns*—array<object>—
rowCount*—integer—
uniqueKeyColumnId—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "columns": [
      {
        "id": "abc123",
        "name": "My workflow",
        "type": "action",
        "required": true,
        "indexed": true
      }
    ],
    "rowCount": 3,
    "uniqueKeyColumnId": "abc123"
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/databases/db_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "columns": [
    {
      "name": "Status",
      "type": "select",
      "required": false,
      "indexed": true
    }
  ]
}'
DELETE/databases/{id}Auth required

Soft-delete a built-in database table.

NameInTypeDescription
id*pathstring—
200Deleted.
401No valid bearer token.
403Missing database:write scope.
404Database not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/databases/db_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
GET/databases/{id}/rowsAuth required

Read rows from a built-in database table (bounded). No public DML row writes.

NameInTypeDescription
id*pathstring—
filtersquerystringJSON-encoded filter array.
sortColumnIdquerystring—
sortDirquerystring—
limitqueryinteger—
cursorquerystring—
200A page of rows keyed by column name.
400Invalid filters or query shape.
401No valid bearer token.
403Missing database:read scope, or the plan lacks API access.
404Database not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<object>—
count*—integer—
next_cursor*—string | null—
Example response
json
{
  "data": [
    {
      "id": "row_01HXEXAMPLE",
      "Name": "Ada Lovelace",
      "Status": "active",
      "createdAt": 1719792000000,
      "updatedAt": 1719792000000
    }
  ],
  "count": 3,
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/databases/db_01HXEXAMPLE/rows \
  -H "Authorization: Bearer wextl_..."

Structures

4endpoints
GET/structuresAuth required

List the organization's structures.

NameInTypeDescription
limitqueryinteger—
200Structure summaries.
401No valid bearer token.
403Missing structure:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<StructureSummary>—
truncated*—boolean—
data[] item (StructureSummary)
NameInTypeDescription
id*—string—
name*—string—
fieldCount*—integer—
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "fieldCount": 3
    }
  ],
  "truncated": true
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/structures \
  -H "Authorization: Bearer wextl_..."
POST/structuresAuth required

Create a structure. Honours the structures_created plan limit (no bypass).

NameInTypeDescription
name*bodystring—
descriptionbodystring—
fieldsbodyarray<StructureField>—
folderIdbodystring | null—
teamIdbodystring | null—
201Created structure.
400Invalid body.
401No valid bearer token.
403Missing structure:write scope, or plan structure limit reached.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Structure—
data shape (Structure)
NameInTypeDescription
id*—string—
name*—string—
fields*—array<object>—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "fields": [
      {
        "name": "My workflow",
        "type": "action",
        "required": true
      }
    ]
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/structures \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "description": "...",
  "fields": [
    {
      "name": "email",
      "type": "text",
      "required": true
    }
  ],
  "folderId": "fld_01HXEXAMPLE",
  "teamId": "team_01HXEXAMPLE"
}'
GET/structures/{id}Auth required

Read one structure's field list.

NameInTypeDescription
id*pathstring—
200Structure fields.
401No valid bearer token.
403Missing structure:read scope, or the plan lacks API access.
404Structure not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Structure—
data shape (Structure)
NameInTypeDescription
id*—string—
name*—string—
fields*—array<object>—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "fields": [
      {
        "name": "My workflow",
        "type": "action",
        "required": true
      }
    ]
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/structures/struct_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
PATCH/structures/{id}Auth required

Update a structure name, description, fields, or folderId.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
descriptionbodystring—
fieldsbodyarray<StructureField>—
folderIdbodystring | null—
200Updated structure.
400Invalid body.
401No valid bearer token.
403Missing structure:write scope.
404Structure not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Structure—
data shape (Structure)
NameInTypeDescription
id*—string—
name*—string—
fields*—array<object>—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "fields": [
      {
        "name": "My workflow",
        "type": "action",
        "required": true
      }
    ]
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/structures/struct_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "description": "...",
  "fields": [
    {
      "name": "email",
      "type": "text",
      "required": true
    }
  ],
  "folderId": "fld_01HXEXAMPLE"
}'

Functions

4endpoints
GET/functionsAuth required

List the organization's custom functions (metadata only).

NameInTypeDescription
cursorquerystring—
limitqueryinteger—
qquerystring—
200Function summaries.
401No valid bearer token.
403Missing function:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<FunctionSummary>—
next_cursor*—string | null—
data[] item (FunctionSummary)
NameInTypeDescription
id*—string—
name*—string—
description—string | null—
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "description": "..."
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/functions \
  -H "Authorization: Bearer wextl_..."
POST/functionsAuth required

Create a custom function. Requires the custom_functions plan feature (no bypass).

NameInTypeDescription
name*bodystringcamelCase name.
code*bodystring—
descriptionbodystring—
parametersbodyarray<FunctionParameter>—
folderIdbodystring | null—
teamIdbodystring | null—
201Created function.
400Invalid body.
401No valid bearer token.
403Missing function:write scope, or custom_functions not on plan.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Function—
data shape (Function)
NameInTypeDescription
id*—string—
name*—string—
description—string | null—
code*—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "code": "...",
    "description": "..."
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/functions \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "code": "...",
  "description": "...",
  "parameters": [
    {
      "name": "amount",
      "type": "number",
      "description": "Order total in cents.",
      "required": true
    }
  ],
  "folderId": "fld_01HXEXAMPLE",
  "teamId": "team_01HXEXAMPLE"
}'
GET/functions/{id}Auth required

Read one custom function including user-owned code.

NameInTypeDescription
id*pathstring—
200Function with code.
401No valid bearer token.
403Missing function:read scope, or the plan lacks API access.
404Function not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Function—
data shape (Function)
NameInTypeDescription
id*—string—
name*—string—
description—string | null—
code*—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "code": "...",
    "description": "..."
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/functions/fn_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."
PATCH/functions/{id}Auth required

Update a custom function. Requires the custom_functions plan feature (no bypass).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
codebodystring—
descriptionbodystring—
parametersbodyarray<FunctionParameter>—
folderIdbodystring | null—
200Updated function.
400Invalid body.
401No valid bearer token.
403Missing function:write scope, or custom_functions not on plan.
404Function not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Function—
data shape (Function)
NameInTypeDescription
id*—string—
name*—string—
description—string | null—
code*—string—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "code": "...",
    "description": "..."
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/functions/fn_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "code": "...",
  "description": "...",
  "parameters": [
    {
      "name": "amount",
      "type": "number",
      "description": "Order total in cents.",
      "required": true
    }
  ],
  "folderId": "fld_01HXEXAMPLE"
}'

Teams

1endpoint
GET/teamsAuth required

List the organization's teams (discovery for create_workflow; requires workflow:read).

200Team summaries.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Team>—
data[] item (Team)
NameInTypeDescription
id*—string—
name*—string—
createdAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "createdAt": 1719792000000
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/teams \
  -H "Authorization: Bearer wextl_..."

Folders

4endpoints
GET/foldersAuth required

List the organization's folder tree (discovery for create_workflow; requires workflow:read).

200Folder summaries.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Folder>—
data[] item (Folder)
NameInTypeDescription
id*—string—
name*—string—
parentId*—string | null—
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "name": "My workflow",
      "parentId": "abc123"
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/folders \
  -H "Authorization: Bearer wextl_..."
POST/foldersAuth required

Create a folder (requires workflow:write).

NameInTypeDescription
name*bodystring—
parentIdbodystring | null—
201Created folder.
400Invalid name or parentId.
401No valid bearer token.
403Missing workflow:write scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—Folder—
data shape (Folder)
NameInTypeDescription
id*—string—
name*—string—
parentId*—string | null—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "parentId": "abc123"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/folders \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "parentId": "abc123"
}'
PATCH/folders/{id}Auth required

Rename or reparent a folder (requires workflow:write).

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
parentIdbodystring | null—
200Updated folder.
400Invalid name or parentId.
401No valid bearer token.
403Missing workflow:write scope.
404Folder not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—Folder—
data shape (Folder)
NameInTypeDescription
id*—string—
name*—string—
parentId*—string | null—
Example response
json
{
  "data": {
    "id": "abc123",
    "name": "My workflow",
    "parentId": "abc123"
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/folders/fld_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "parentId": "abc123"
}'
DELETE/folders/{id}Auth required

Delete a folder (requires workflow:write). Contents are not cascade-deleted.

NameInTypeDescription
id*pathstring—
200Deleted.
401No valid bearer token.
403Missing workflow:write scope.
404Folder not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/folders/fld_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."

Activity

1endpoint
GET/activityAuth required

List the organization's activity feed (audit log). Requires activity:read (owner/admin).

NameInTypeDescription
targetTypequerystring—
targetIdquerystring—
actorUserIdquerystring—
actionquerystring—
sincequeryintegerEpoch ms lower bound.
untilqueryintegerEpoch ms upper bound (exclusive).
limitqueryinteger—
cursorquerystringOpaque "{ts}_{id}" from a previous page.
200Activity page with labeled events and actor map.
401No valid bearer token.
403Missing activity:read scope, or not an org admin.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—ActivityPage—
data shape (ActivityPage)
NameInTypeDescription
events*—array<object>—
actors*—objectactorUserId → actor, for every distinct actor referenced in events.
next_cursor*—string | null—
Example response
json
{
  "data": {
    "events": [
      {
        "id": "abc123",
        "ts": 0,
        "action": "...",
        "label": "My workflow",
        "targetType": "...",
        "targetId": "abc123",
        "actorUserId": "abc123",
        "metadata": "..."
      }
    ],
    "actors": {
      "usr_01HXEXAMPLE": {
        "id": "usr_01HXEXAMPLE",
        "name": "Ada Lovelace",
        "email": "[email protected]"
      }
    },
    "next_cursor": null
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/activity \
  -H "Authorization: Bearer wextl_..."

Invitations

3endpoints
GET/invitationsAuth required

List organization invitations. Requires invitation:read (owner/admin).

NameInTypeDescription
statusquerystring—
limitqueryinteger—
200Invitation summaries (includes invite_url).
401No valid bearer token.
403Missing invitation:read scope, or not an org admin.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Invitation>—
data[] item (Invitation)
NameInTypeDescription
id*—string—
email*—string—
role—string | null—
teamId—string | null—
status*—string—
expiresAt*—integerEpoch milliseconds.
createdAt*—integerEpoch milliseconds.
inviterId*—string—
invite_url*—stringAbsolute URL for the invitee; relay if email delivery fails.
Example response
json
{
  "data": [
    {
      "id": "abc123",
      "email": "...",
      "status": "succeeded",
      "expiresAt": 1719792000000,
      "createdAt": 1719792000000,
      "inviterId": "abc123",
      "invite_url": "...",
      "role": "...",
      "teamId": "team_01HXEXAMPLE"
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/invitations \
  -H "Authorization: Bearer wextl_..."
POST/invitationsAuth required

Create an invitation. Requires invitation:write. Returns invite_url for headless relay.

NameInTypeDescription
email*bodystring—
role*bodystring—
teamIdbodystring | null—
201Created invitation.
401No valid bearer token.
403Missing invitation:write, seat cap, or role escalation denied.
409Pending invitation already exists for this email.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—Invitation—
data shape (Invitation)
NameInTypeDescription
id*—string—
email*—string—
role—string | null—
teamId—string | null—
status*—string—
expiresAt*—integerEpoch milliseconds.
createdAt*—integerEpoch milliseconds.
inviterId*—string—
invite_url*—stringAbsolute URL for the invitee; relay if email delivery fails.
Example response
json
{
  "data": {
    "id": "abc123",
    "email": "...",
    "status": "succeeded",
    "expiresAt": 1719792000000,
    "createdAt": 1719792000000,
    "inviterId": "abc123",
    "invite_url": "...",
    "role": "...",
    "teamId": "team_01HXEXAMPLE"
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/invitations \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "email": "...",
  "role": "...",
  "teamId": "team_01HXEXAMPLE"
}'
DELETE/invitations/{id}Auth required

Cancel a pending invitation. Requires invitation:write.

NameInTypeDescription
id*pathstring—
200Cancelled.
401No valid bearer token.
403Missing invitation:write scope, or not an org admin.
404Invitation not found.
409Invitation is not pending.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/invitations/inv_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."

Tags

4endpoints
GET/tagsAuth required

List workflow tags (requires workflow:read).

200Tag list.
401No valid bearer token.
403Missing workflow:read scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—array<Tag>—
data[] item (Tag)
NameInTypeDescription
id*—string—
name*—string—
color*—string—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "tag_01HXEXAMPLE",
      "name": "Priority",
      "color": "amber",
      "createdAt": 1719792000000,
      "updatedAt": 1719792000000
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/tags \
  -H "Authorization: Bearer wextl_..."
POST/tagsAuth required

Create a workflow tag.

NameInTypeDescription
name*bodystring—
color*bodystring—
201Created tag.
400Invalid body.
401No valid bearer token.
403Missing workflow:write scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Tag—
data shape (Tag)
NameInTypeDescription
id*—string—
name*—string—
color*—string—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "id": "tag_01HXEXAMPLE",
    "name": "Priority",
    "color": "amber",
    "createdAt": 1719792000000,
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X POST https://eu1.wextl.com/api/v1/tags \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "color": "..."
}'
PATCH/tags/{id}Auth required

Rename or recolour a tag.

NameInTypeDescription
id*pathstring—
NameInTypeDescription
namebodystring—
colorbodystring—
200Updated tag.
400Invalid body.
401No valid bearer token.
403Missing workflow:write scope.
404Tag not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—Tag—
data shape (Tag)
NameInTypeDescription
id*—string—
name*—string—
color*—string—
createdAt*—integerEpoch milliseconds.
updatedAt*—integerEpoch milliseconds.
Example response
json
{
  "data": {
    "id": "tag_01HXEXAMPLE",
    "name": "Priority",
    "color": "amber",
    "createdAt": 1719792000000,
    "updatedAt": 1719792000000
  }
}
Example request
bash
curl -X PATCH https://eu1.wextl.com/api/v1/tags/tag_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My workflow",
  "color": "..."
}'
DELETE/tags/{id}Auth required

Delete a tag and its assignments.

NameInTypeDescription
id*pathstring—
200Deleted.
401No valid bearer token.
403Missing workflow:write scope.
404Tag not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—object—
data shape (object)
NameInTypeDescription
ok—boolean—
Example response
json
{
  "data": {
    "ok": true
  }
}
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/tags/tag_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."

Webhooks

2endpoints
GET/webhooksAuth required

List inbound webhooks (requires workflow:read).

NameInTypeDescription
cursorquerystring—
limitqueryinteger—
qquerystring—
200Webhook page.
401No valid bearer token.
403Missing workflow:read scope.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<WebhookSummary>—
next_cursor*—string | null—
data[] item (WebhookSummary)
NameInTypeDescription
id*—string—
name*—string—
url*—string—
enabled*—boolean—
method*—string—
workflowId*—string | null—
nodeId*—string | null—
createdAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "id": "wh_01HXEXAMPLE",
      "name": "Webhook",
      "url": "https://eu1.wextl.com/hooks/wh_01HXEXAMPLE",
      "enabled": true,
      "method": "POST",
      "workflowId": "wf_01HXEXAMPLE",
      "nodeId": "12",
      "createdAt": 1719792000000
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/webhooks \
  -H "Authorization: Bearer wextl_..."
DELETE/webhooks/{id}Auth required

Delete a webhook. Pass force=1 if still bound to a workflow.

NameInTypeDescription
id*pathstring—
forcequerystring—
204Deleted.
401No valid bearer token.
403Missing workflow:write scope.
404Webhook not found.
409Webhook in use — pass force=1.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
Example request
bash
curl -X DELETE https://eu1.wextl.com/api/v1/webhooks/wh_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."

Members

1endpoint
GET/membersAuth required

List organization members, bounded and cursor-paginated (requires invitation:read / owner-admin).

NameInTypeDescription
cursorquerystringOpaque continuation token from a previous response.
limitqueryintegerPage size. Default 100.
200A page of the member roster.
401No valid bearer token.
403Missing invitation:read scope, or not an org admin.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data*—array<Member>—
next_cursor*—string | null—
data[] item (Member)
NameInTypeDescription
userId*—string—
email*—string | null—
name*—string | null—
role*—string—
createdAt*—integerEpoch milliseconds.
Example response
json
{
  "data": [
    {
      "userId": "usr_01HXEXAMPLE",
      "email": "[email protected]",
      "name": "Ada Lovelace",
      "role": "admin",
      "createdAt": 1719792000000
    }
  ],
  "next_cursor": null
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/members \
  -H "Authorization: Bearer wextl_..."

Catalog

3endpoints
GET/catalog/appsAuth required

Search the app and module catalog by keyword. Use the returned app and module ids when creating or updating workflow nodes.

NameInTypeDescription
query*querystringSearch keywords (app or capability name).
limitqueryintegerMax apps to return. Default 10.
200Matching apps with their modules.
400query is required.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—array<CatalogApp>—
data[] item (CatalogApp)
NameInTypeDescription
appId*—string—
name*—string—
description—string | null—
modules*—array<object>—
Example response
json
{
  "data": [
    {
      "appId": "slack",
      "name": "My workflow",
      "modules": [
        {
          "id": "abc123",
          "label": "My workflow",
          "type": "action"
        }
      ],
      "description": "..."
    }
  ]
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/catalog/apps \
  -H "Authorization: Bearer wextl_..."
GET/catalog/apps/{appId}/modules/{moduleId}Auth required

Read a module's parameter schema and metadata. Does not expose internal request implementation details.

NameInTypeDescription
appId*pathstring—
moduleId*pathstring—
200The module spec (lean projection — meta + mappable/static fields).
400appId and moduleId are required, or the module cannot be projected for the public API.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Module not found.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—ModuleSpec—
data shape (ModuleSpec)
NameInTypeDescription
meta*—objectCompact module metadata — label, description, which connection it needs, etc. Shape varies per module.
mappableFields*—array<object>The fields the caller fills at run time (bindable to upstream data). Shape depends on the field type.
staticFields*—array<object>Fixed UI-configuration params for this module — often empty. Shape depends on the field type.
emitsMultipleBundles—boolean—
requiresConnection—boolean—
Example response
json
{
  "data": {
    "meta": {
      "label": "Send a message",
      "description": "Post a message to a channel.",
      "connection": "oauth2"
    },
    "mappableFields": [
      {
        "name": "channel",
        "label": "Channel",
        "type": "select",
        "required": true
      }
    ],
    "staticFields": [
      {
        "name": "includeAttachments",
        "label": "Include attachments",
        "type": "boolean",
        "required": false
      }
    ],
    "emitsMultipleBundles": true,
    "requiresConnection": true
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/catalog/apps/slack/modules/send_message \
  -H "Authorization: Bearer wextl_..."
GET/catalog/nodes/{kind}Auth required

Read the machine-readable spec for a NATIVE (built-in) workflow node kind — where its data persists, the exact field shape, a copyable example, and its outgoing routes. App/module nodes are not covered here; use GET /catalog/apps/{appId}/modules/{moduleId} for those.

NameInTypeDescription
kind*pathstringNative node kind, e.g. 'condition', 'splitter', 'wait', 'js_code'.
200The native node-kind spec.
401No valid bearer token.
403Missing workflow:read scope, or the plan lacks API access.
404Unknown kind — use search_catalog for app/module nodes.
421Wrong regional endpoint — follow error.base_url.
429Rate limited — retry after error.retry_after_s seconds.
NameInTypeDescription
data—NodeSpec—
data shape (NodeSpec)
NameInTypeDescription
kind*—string—
label*—string—
description*—string—
insertable*—booleanTrue when this kind appears in the builder palette.
persists_under*—stringWhere this kind's data lives on the node.
shape*—objectField name -> { type, required, description }.
example*—objectA filled config/params object for this kind, ready to copy into update_config / update_params.
routes*—array<string>Outgoing edge types this kind can emit, e.g. 'normal', 'error', 'fallback'.
expressionGrammar*—stringHow to reference upstream values inside wire strings.
edgeModel*—stringEdge topology notes — how to wire this kind's outgoing/incoming edges.
Example response
json
{
  "data": {
    "kind": "condition",
    "label": "Condition",
    "description": "Branches execution based on a boolean expression.",
    "insertable": true,
    "persists_under": "config",
    "shape": {
      "conditions": {
        "type": "array",
        "required": true,
        "description": "Ordered list of condition branches."
      }
    },
    "example": {
      "conditions": [
        {
          "expression": "{{1.status}} == \"ok\"",
          "label": "OK"
        }
      ]
    },
    "routes": [
      "normal"
    ],
    "expressionGrammar": "{{nodeId.path}} references an upstream node's output.",
    "edgeModel": "Each condition branch has its own outgoing port, in the order listed."
  }
}
Example request
bash
curl -X GET https://eu1.wextl.com/api/v1/catalog/nodes/id_01HXEXAMPLE \
  -H "Authorization: Bearer wextl_..."