API reference

v1

Run workflows, inspect runs, and resolve approvals. Credentials stay workspace-scoped.

OpenAPI specification
No matching API documentation found.

Start here

Quick start

From your first workspace token to a workflow run.

1. Create a workspace token

Workspace owners and admins create service tokens from API access in the application. Send the token as a Bearer credential with every request.

For this guide, grant these abilities:

workflows:read runs:create runs:read

Store the token on your server as WORKSPACE_API_TOKEN. Replace the example workflow ID with one returned by your workspace.

About authentication

2. Choose a published workflow

List the available workflows, then check the selected workflow’s input schema before providing a payload.

curl "https://justflows.qdev.tech/api/v1/workflows" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"
List workflows

3. Start a workflow run

curl -X POST "https://justflows.qdev.tech/api/v1/workflows/wf_01J00000000000000000000001/runs" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: order-1842-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
        "order_id": 1842,
        "customer_email": "customer@example.com"
    }
}'

A successful start returns HTTP 202. The run may already be finished when synchronous execution is configured, so always inspect its returned status.

Start a run

4. Inspect the result

Use the returned run ID to read its status and output. A run can be pending, running, waiting, finished, failed, or canceled.

curl "https://justflows.qdev.tech/api/v1/runs/run_01J00000000000000000000002" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"
Inspect a run

Start here

Overview

Operate JustFlows from your own systems.

API v1 gives external services a stable way to operate published workflows and human approvals without using a user session. Workspace boundaries, token abilities, plan limits, and workflow-run limits continue to apply.

Base URL
https://justflows.qdev.tech/api/v1
Authentication
Workspace Bearer token
Format
JSON requests and responses
Specification
Open API v1 YAML

Workflows

Find published workflows and inspect their expected inputs.

Browse workflow endpoints

Runs

Start work, read results, and cancel active runs.

Browse run endpoints

Approvals

Read review context and submit approval decisions.

Browse approval endpoints

Start here

Authentication

Give external services only the access they need within one workspace.

Workspace owners and admins create service tokens from API access in the application. Send the token as a Bearer credential with every request.

Authorization: Bearer wst_v1_<token-id>.<secret>
The full token is shown only once. Store it in a secret manager and never place it in source control, browser code, query strings, or logs. Rotation revokes the previous value immediately.

Abilities

Grant each application only the operations it needs.

AbilityAllows
workflows:readView published workflows
runs:createStart workflow runs
runs:readView workflow runs
runs:cancelCancel workflow runs
approvals:readView pending approvals
approvals:writeResolve approvals

Site availability control.

The site administrator can disable the Workspace API globally. While disabled, existing tokens are retained but cannot authenticate, and service endpoints return HTTP 503 with the error code api_disabled.

API reference Workflows

List workflows

Find published workflows available to your workspace service token.

GET /api/v1/workflows

Authorization

Send a workspace Bearer token with this ability:

workflows:read About authentication

Query parameters

cursor string Optional

Use meta.next_cursor from the previous response to request another page.

per_page integer Optional

Return 1 to 100 records per page. Defaults to 25.

Only published workflows are visible and runnable through the API. Draft or paused workflow state is never selected as a fallback.

Response

200 OK

Returns published workflows, their versions, and input schemas. Use the cursor to continue through the results.

About pagination
Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/workflows" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/workflows", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": [
        {
            "id": "wf_01J00000000000000000000001",
            "object": "workflow",
            "name": "Order review",
            "status": "published",
            "published_version": {
                "number": 1,
                "published_at": "2026-09-01T09:00:00Z"
            },
            "input": {
                "schema": {},
                "example": {
                    "order_id": 1842
                }
            },
            "created_at": "2026-09-01T09:00:00Z",
            "updated_at": "2026-09-01T09:00:00Z"
        }
    ],
    "meta": {
        "next_cursor": null,
        "previous_cursor": null,
        "has_more": false
    },
    "request_id": "example-request-1842"
}

API reference Workflows

Get a workflow

Read the published version and expected inputs before starting a workflow.

GET /api/v1/workflows/{workflow_id}

Authorization

Send a workspace Bearer token with this ability:

workflows:read About authentication

Path parameters

workflow_id string Required

The ID of a published workflow in this workspace.

Response

200 OK

Workflow detail responses include the published version and the trigger input schema or example when one is configured.

Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/workflows/wf_01J00000000000000000000001" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/workflows/wf_01J00000000000000000000001", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": {
        "id": "wf_01J00000000000000000000001",
        "object": "workflow",
        "name": "Order review",
        "status": "published",
        "published_version": {
            "number": 1,
            "published_at": "2026-09-01T09:00:00Z"
        },
        "input": {
            "schema": {},
            "example": {
                "order_id": 1842
            }
        },
        "created_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z"
    },
    "request_id": "example-request-1842"
}

API reference Runs

Start a run

Start the published version of a workflow from your own application.

POST /api/v1/workflows/{workflow_id}/runs

Authorization

Send a workspace Bearer token with this ability:

runs:create About authentication

Path parameters

workflow_id string Required

The ID of a published workflow in this workspace.

Request headers

Idempotency-Key string Optional

Reuse a unique key for retries of the same logical attempt. Use 8–200 letters, numbers, periods, underscores, colons, or hyphens.

X-Request-Id string Optional

A correlation ID of up to 100 letters, numbers, periods, underscores, colons, or hyphens.

Request body

payload object Optional

Inputs to pass into the workflow. Defaults to an empty object.

Response

202 Accepted

A successful start returns HTTP 202. The run may already be finished when synchronous execution is configured, so always inspect its returned status.

Create, cancel, and approval-decision responses contain identifiers and state only. Grant the corresponding read ability and use the GET endpoint when the integration needs workflow output or approval context.

Idempotent starts

Idempotency-Key is optional. When it is omitted, the API starts the run normally using an internal one-time key. This is convenient for simple calls, but repeating the request may start another run.

For integrations that retry requests automatically, generate a unique value in the calling application and reuse it only for the same logical attempt:

Idempotency-Key: order-1842-attempt-1

Retrying the same workflow and payload with that key returns the original run and includes Idempotent-Replayed: true.

The API stores a hash of the key for 24 hours. Reusing it for different data returns HTTP 409. Keys are isolated per token, and a UUID or durable business identifier plus an attempt number works well.

Errors and limits

Request example

curl -X POST "https://justflows.qdev.tech/api/v1/workflows/wf_01J00000000000000000000001/runs" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: order-1842-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
        "order_id": 1842,
        "customer_email": "customer@example.com"
    }
}'

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/workflows/wf_01J00000000000000000000001/runs", {
    "method": "POST",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json",
        "Idempotency-Key": "order-1842-attempt-1",
        "Content-Type": "application/json"
    },
    "body": JSON.stringify({
    "payload": {
        "order_id": 1842,
        "customer_email": "customer@example.com"
    }
})
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

202 Accepted
{
    "data": {
        "id": "run_01J00000000000000000000002",
        "object": "run",
        "workflow_id": "wf_01J00000000000000000000001",
        "status": "pending",
        "created_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z"
    },
    "request_id": "example-request-1842"
}

API reference Runs

List runs

Find workflow runs in your workspace and filter them by state or workflow.

GET /api/v1/runs

Authorization

Send a workspace Bearer token with this ability:

runs:read About authentication

Query parameters

cursor string Optional

Use meta.next_cursor from the previous response to request another page.

per_page integer Optional

Return 1 to 100 records per page. Defaults to 25.

status string Optional

Filter by pending, running, waiting, finished, failed, or canceled.

workflow_id string Optional

Only return runs for the specified workflow ID.

Run endpoints

Inspect a run Cancel a run Idempotent starts

Response

200 OK

Returns runs with their current status, redacted output, and safe failure information.

About pagination
Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/runs" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/runs", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": [
        {
            "id": "run_01J00000000000000000000002",
            "object": "run",
            "workflow_id": "wf_01J00000000000000000000001",
            "status": "finished",
            "created_at": "2026-09-01T09:00:00Z",
            "updated_at": "2026-09-01T09:00:00Z",
            "output": {
                "order_id": 1842,
                "result": "reviewed"
            },
            "error": null
        }
    ],
    "meta": {
        "next_cursor": null,
        "previous_cursor": null,
        "has_more": false
    },
    "request_id": "example-request-1842"
}

API reference Runs

Inspect a run

Read a run’s current state, output, and any workflow error.

GET /api/v1/runs/{run_id}

Authorization

Send a workspace Bearer token with this ability:

runs:read About authentication

Path parameters

run_id string Required

The run ID returned when you started the workflow.

Response

200 OK

A run can be pending, running, waiting, finished, failed, or canceled. Finished runs include output; failed runs include a safe error.

Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/runs/run_01J00000000000000000000002" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/runs/run_01J00000000000000000000002", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": {
        "id": "run_01J00000000000000000000002",
        "object": "run",
        "workflow_id": "wf_01J00000000000000000000001",
        "status": "finished",
        "created_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z",
        "output": {
            "order_id": 1842,
            "result": "reviewed"
        },
        "error": null
    },
    "request_id": "example-request-1842"
}

API reference Runs

Cancel a run

Cancel an active workflow run in your workspace.

POST /api/v1/runs/{run_id}/cancel

Authorization

Send a workspace Bearer token with this ability:

runs:cancel About authentication

Path parameters

run_id string Required

The run ID returned when you started the workflow.

Response

200 OK

Returns the canceled run’s identifiers and state. A conflicting run state returns HTTP 409.

Create, cancel, and approval-decision responses contain identifiers and state only. Grant the corresponding read ability and use the GET endpoint when the integration needs workflow output or approval context.

Errors and limits

Request example

curl -X POST "https://justflows.qdev.tech/api/v1/runs/run_01J00000000000000000000002/cancel" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/runs/run_01J00000000000000000000002/cancel", {
    "method": "POST",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": {
        "id": "run_01J00000000000000000000002",
        "object": "run",
        "workflow_id": "wf_01J00000000000000000000001",
        "status": "canceled",
        "created_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z"
    },
    "request_id": "example-request-1842"
}

API reference Approvals

List approvals

Find approval requests that need a decision in your workspace.

GET /api/v1/approvals

Authorization

Send a workspace Bearer token with this ability:

approvals:read About authentication

Query parameters

cursor string Optional

Use meta.next_cursor from the previous response to request another page.

per_page integer Optional

Return 1 to 100 records per page. Defaults to 25.

status string Optional

Defaults to pending. Accepts all, pending, approved, rejected, changes_requested, or canceled.

Approval lists return pending requests by default. A service token can approve, reject, or request changes within its own workspace when granted the appropriate ability.

Response

200 OK

Returns approval requests with their titles, current states, and redacted review context.

About pagination
Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/approvals" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/approvals", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": [
        {
            "id": "apr_01J00000000000000000000003",
            "object": "approval",
            "run_id": "run_01J00000000000000000000002",
            "workflow_id": "wf_01J00000000000000000000001",
            "status": "pending",
            "decision": null,
            "title": "Review order",
            "summary": "Review the proposed order update.",
            "request": {
                "node_key": "review-order",
                "node_name": "Review order",
                "input_payload": {
                    "order_id": 1842
                },
                "context": {
                    "proposed_update": "Ready for processing"
                },
                "allows_changes_requested": true
            },
            "created_at": "2026-09-01T09:00:00Z",
            "updated_at": "2026-09-01T09:00:00Z"
        }
    ],
    "meta": {
        "next_cursor": null,
        "previous_cursor": null,
        "has_more": false
    },
    "request_id": "example-request-1842"
}

API reference Approvals

Get an approval

Read the review context and current state of an approval request.

GET /api/v1/approvals/{approval_id}

Authorization

Send a workspace Bearer token with this ability:

approvals:read About authentication

Path parameters

approval_id string Required

The approval ID returned by the approval list endpoint.

Response

200 OK

Returns the approval request and redacted context. Use its state to check whether it still needs a decision.

Errors and limits

Request example

curl "https://justflows.qdev.tech/api/v1/approvals/apr_01J00000000000000000000003" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json"

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/approvals/apr_01J00000000000000000000003", {
    "method": "GET",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json"
    }
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": {
        "id": "apr_01J00000000000000000000003",
        "object": "approval",
        "run_id": "run_01J00000000000000000000002",
        "workflow_id": "wf_01J00000000000000000000001",
        "status": "pending",
        "decision": null,
        "title": "Review order",
        "summary": "Review the proposed order update.",
        "request": {
            "node_key": "review-order",
            "node_name": "Review order",
            "input_payload": {
                "order_id": 1842
            },
            "context": {
                "proposed_update": "Ready for processing"
            },
            "allows_changes_requested": true
        },
        "created_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z"
    },
    "request_id": "example-request-1842"
}

API reference Approvals

Resolve an approval

Approve, reject, or request changes for a pending approval in your workspace.

POST /api/v1/approvals/{approval_id}/decision

Authorization

Send a workspace Bearer token with this ability:

approvals:write About authentication

Path parameters

approval_id string Required

The approval ID returned by the approval list endpoint.

Request body

decision string Required

Accepts approved, rejected, or changes_requested. The workflow node must allow the selected decision.

feedback string · null Optional

Required and non-empty for changes_requested. Maximum 4,000 characters.

Feedback is required for a change request, and the workflow node must allow that decision.

Response

200 OK

Returns the approval identifiers and decision state. Grant approvals:read and use the GET endpoint to read the review context.

Create, cancel, and approval-decision responses contain identifiers and state only. Grant the corresponding read ability and use the GET endpoint when the integration needs workflow output or approval context.

Errors and limits

Request example

curl -X POST "https://justflows.qdev.tech/api/v1/approvals/apr_01J00000000000000000000003/decision" \
  -H "Authorization: Bearer $WORKSPACE_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "changes_requested",
    "feedback": "Use the approved customer-facing wording."
}'

Server-side only. Keep tokens private.

const response = await fetch("https://justflows.qdev.tech/api/v1/approvals/apr_01J00000000000000000000003/decision", {
    "method": "POST",
    "headers": {
        "Authorization": `Bearer ${process.env.WORKSPACE_API_TOKEN}`,
        "Accept": "application/json",
        "Content-Type": "application/json"
    },
    "body": JSON.stringify({
    "decision": "changes_requested",
    "feedback": "Use the approved customer-facing wording."
})
});

const result = await response.json();
if (!response.ok) {
  throw new Error(result.error.message);
}

console.log(result.data);

Response example

200 OK
{
    "data": {
        "id": "apr_01J00000000000000000000003",
        "object": "approval",
        "run_id": "run_01J00000000000000000000002",
        "status": "changes_requested",
        "decision": "changes_requested",
        "responded_at": "2026-09-01T09:00:00Z",
        "updated_at": "2026-09-01T09:00:00Z"
    },
    "request_id": "example-request-1842"
}

Reference

Pagination

Move through list results with a cursor.

List endpoints use cursor pagination. Set per_page from 1 to 100 and pass meta.next_cursor back as the cursor query parameter.

The default page size is 25. Stop requesting pages when meta.has_more is false.

{
  "data": [],
  "meta": {
    "next_cursor": "eyJpZCI6...",
    "previous_cursor": null,
    "has_more": true
  },
  "request_id": "example-request-1842"
}

Treat cursor values as opaque. Pass the returned value through without changing it.

Reference

Errors and limits

Understand failed requests and when to retry them.

Error envelope

Errors use a stable machine-readable code. Every response includes X-Request-Id; clients may supply a safe X-Request-Id value to correlate logs.

{
  "error": {
    "code": "insufficient_scope",
    "message": "This API token does not have the required ability.",
    "details": {
      "required": ["runs:create"]
    }
  },
  "request_id": "example-request-1842"
}

HTTP status codes

StatusWhat it means
401The Bearer token is missing, malformed, expired, or revoked.
403The token lacks the required ability.
404The resource was not found in the token workspace.
409The operation conflicts with current state or idempotency history.
422The request is invalid or the workspace cannot perform the operation.
429A per-token rate limit was exceeded. Wait for the Retry-After interval before retrying.
503The site administrator has disabled the Workspace API.

Limits and safe output

General requests
60 per minute per token
Run starts
10 per minute per token
JSON request body
Maximum 256 KB
Plan enforcement
Normal workspace and run limits apply

HTTP 429 responses include Retry-After. HTTP 503 with api_disabled means the site administrator has disabled the Workspace API; wait for it to be enabled instead of rotating credentials. Run and approval payloads are redacted before they are returned; authorization headers, credentials, and internal exception metadata are never included in API responses.