Getting started

Use the v2 API to run workflows and manage resources you can access. This guide makes a first call to a deployed workflow, then explains asynchronous execution, response envelopes, and pagination.

Base URL

Sim Cloud uses https://www.sim.ai, with API paths under /api/v2. There is no api.sim.ai host. For self-hosted Sim, replace the origin with your deployment URL.

Download the OpenAPI 3.1 specification for client generation, request validation, and API tooling.

Run a deployed workflow

Create an API key

Open Account settings → Sim API keys for a personal key, or Workspace settings → Sim API keys for a workspace key. Set SIM_API_KEY in your server environment. See Authentication for key types, access policies, and OAuth tokens. The CLI also supports browser sign-in with sim login.

Find the workflow ID

Open the workflow in the workflow builder. Its URL contains the ID:

https://www.sim.ai/workspace/{workspaceId}/w/{workflowId}

Set WORKFLOW_ID to that value. You can also use List workflows to find IDs in a workspace.

Deploy the workflow

Open Deploy in the workflow builder and deploy the version you want to run. Deployment requires workspace Admin access and the applicable deployment permission.

These examples run the active deployment. Draft edits take effect after you deploy an update. V2 also supports explicit manual draft execution for personal-key or OAuth callers with write access; see Execute workflow.

Call and inspect the result

Place named workflow input fields inside input. Replace the example input with fields your deployed trigger accepts.

curl --fail-with-body -X POST \
  "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \
  -H "X-API-Key: $SIM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"input": {}}'
const apiKey = process.env.SIM_API_KEY
const workflowId = process.env.WORKFLOW_ID
if (!apiKey || !workflowId) throw new Error('Set SIM_API_KEY and WORKFLOW_ID')

const response = await fetch(`https://www.sim.ai/api/v2/workflows/${workflowId}/execute`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
  body: JSON.stringify({ input: {} }),
})
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`)

const result = await response.json()
process.stdout.write(JSON.stringify({ status: result.data.status, output: result.data.output }))
import os
import requests

workflow_id = os.environ["WORKFLOW_ID"]
response = requests.post(
    f"https://www.sim.ai/api/v2/workflows/{workflow_id}/execute",
    headers={"X-API-Key": os.environ["SIM_API_KEY"]},
    json={"input": {}},
    timeout=30,
)
response.raise_for_status()
result = response.json()["data"]
print(result["status"], result["output"])

A successful HTTP request can contain a failed workflow run. Always inspect data.status and data.error. A client timeout limits how long your application waits; it does not extend the server's execution limit or prove no run started.

Synchronous and asynchronous execution

The default waits for the workflow to settle and returns a run resource. For a long-running deployed workflow, set async: true to receive HTTP 202 with a run ID:

curl --fail-with-body -X POST \
  "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \
  -H "X-API-Key: $SIM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"input": {}, "async": true}'
{
  "data": {
    "runId": "c7a92e15-3f4b-4d8c-a1e6-9b0d5f2c8e74",
    "statusUrl": "https://www.sim.ai/api/v2/workflows/{workflowId}/runs/c7a92e15-3f4b-4d8c-a1e6-9b0d5f2c8e74"
  }
}

Async requires an API key or OAuth token. It cannot be combined with streaming, manual draft execution, or output-shaping options. An optional integer executionTimeoutSeconds from 1 to 604800 can shorten the account's execution policy, but cannot extend it. See the execution request for compatible options.

Set RUN_ID to the returned ID and poll with a delay:

curl --fail-with-body \
  "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID?includeOutput=true" \
  -H "X-API-Key: $SIM_API_KEY"
StatusAction
queued, pending, running, redactingContinue polling; redacting is a transient output-redaction state
completedRead data.output when includeOutput=true
failedInspect data.error
cancelledStop polling
pausedInspect pause details and the resume condition; the workflow has not completed

Runs need not pass through every state. A human pause requires submitted input; a time pause can resume automatically. See Get workflow run and the effective data retention policy.

Authenticated callers can send X-Run-Id to choose a run ID. It is a one-shot claim: reuse returns 409, not the original response. After an uncertain enqueue or lost response, reconcile the original run ID before starting another run. A missing record does not by itself prove that no work started.

For SSE tokens or a synchronous NDJSON response with heartbeats, see API streaming.

Response format

Single-resource v2 JSON responses wrap the resource in data. For example, a synchronous execution returns:

{
  "data": {
    "runId": "c7a92e15-3f4b-4d8c-a1e6-9b0d5f2c8e74",
    "workflowId": "{workflowId}",
    "status": "completed",
    "output": { "result": "Hello, world!" },
    "blockOutputs": null,
    "error": null,
    "startedAt": "2026-10-13T12:00:00.000Z",
    "endedAt": "2026-10-13T12:00:00.842Z",
    "durationMs": 842
  }
}

List responses use data as an array and include nextCursor when applicable. Streams and binary downloads have their own response formats.

Cost units are endpoint-specific: Logs APIs report USD; Billing and workflow-run resources report credits. Read the field description before combining amounts.

Handle failed requests

Rejected v2 requests use HTTP error status codes and a stable code/message envelope:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Workflow not found"
  }
}
StatusMeaningAction
400Invalid requestCheck the published schema and error.details, when present
401Missing, invalid, or expired credentialCheck the API key or OAuth token and its header
402Usage limit exceededInspect billing status and account policy
403Access deniedCheck role, scope, resource access, and permission policies
404Resource not found or concealedCheck the ID and selected workspace
409State, preview, or run-ID conflictFollow the endpoint's conflict/reconciliation procedure
429Rate or capacity limitHonor Retry-After before retrying an admitted-safe request

Other statuses and endpoint-specific recovery are documented in each reference. error.details may be a validation-issue array or an object with additional context. An execution that started and failed instead returns a run resource with status: "failed".

Unrecognized fields are rejected

V2 validates path parameters, query strings, and bodies against the published schema. Unknown fields return 400; for example, ?limt=20 is an error. The rule also applies to endpoints with no query parameters: omit tracking tags, cache busters, and other undeclared fields.

A validation error can look like:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid request",
    "details": [
      { "code": "unrecognized_keys", "keys": ["limt"], "path": [], "message": "Unrecognized key: \"limt\"" }
    ]
  }
}

Pagination

Paginated list endpoints, including workflows, logs, and audit logs, return an opaque nextCursor. Keep the workspace, filters, and sort choices the same when requesting the next page. A missing or null cursor means there is no next page.

This example requires WORKSPACE_ID, SIM_API_KEY, and jq:

PAGE=$(curl --silent --show-error --fail-with-body --get \
  'https://www.sim.ai/api/v2/logs' \
  -H "X-API-Key: $SIM_API_KEY" \
  --data-urlencode "workspaceId=$WORKSPACE_ID" \
  --data-urlencode 'limit=20')

CURSOR=$(printf '%s' "$PAGE" | jq -r '.nextCursor // empty')
if [ -n "$CURSOR" ]; then
  curl --fail-with-body --get 'https://www.sim.ai/api/v2/logs' \
    -H "X-API-Key: $SIM_API_KEY" \
    --data-urlencode "workspaceId=$WORKSPACE_ID" \
    --data-urlencode 'limit=20' \
    --data-urlencode "cursor=$CURSOR"
fi

Some endpoints return an unpaginated bounded inventory or a provider-specific partial result. Follow that endpoint's pagination and truncation fields.

Rate limits

V2 request limits apply to the credential and its user or workspace. Workflow execution also applies separate synchronous/asynchronous execution buckets, quota, and concurrency policy. Plan and deployment configuration determine the effective limits.

A rate-limited request returns 429; Retry-After gives seconds to wait. Inspect Billing status for a workspace's current credits and storage. Async mode does not bypass admission or usage limits.