Executing actions

Run an action on a connected app with POST /api/executions, including the confirm field and runnable curl for Gmail, Slack, and Instagram.

An execution runs one action on one of your connected apps. The recommended endpoint is POST /api/executions, which uses the canonical integration_id + action_id + input model.

POST /api/executions

integration_idstringrequired

The integration slug, e.g. gmail, slack, instagram. See discovering actions.

action_idstringrequired

The action to run, e.g. send_email. This is the tool name with the integration prefix removed (gmail_send_emailsend_email). The full tool name (gmail_send_email) also works.

inputobjectrequired

The action's arguments. Field names are specific to each action — fetch them with GET /api/actions/{integration_id}/{action_id}.

confirmbooleandefault: false

Required (true) for any write or destructive action. See The confirm field.

idempotency_keystring

Optional client-supplied key to safely retry a request without running the action twice.

POST /api/executions runs against your default connection for the integration. If you have multiple connections for the same app and need to target a specific one, use the tool endpoint with connectionId.

Response

The response is a normalized execution summary. status is the field to branch on.

statusstring

succeeded, blocked, or failed.

execution_idstring | null

Stable ID of the run. null when the action was blocked before running (e.g. missing confirmation). Pass to GET /api/executions/{id}.

integration_idstring
action_idstring
started_atstring
ISO 8601 timestamp.
finished_atstring
ISO 8601 timestamp.
outputany

The provider's result payload. Present on success.

displayobject

{ title, summary } — a short human-readable description of the outcome.

error_codestring

Present when blocked or failed. See Errors.

messagestring

Human-readable error message (on blocked / failed).

hintstring

Actionable guidance for recovering from a failure, when available.

recommended_next_actionobject

e.g. { "tool": "clawlink.connect_app", "input": { "integration_id": "gmail" } } when the app needs connecting or re-authing.

HTTP status: 200 succeeded · 409 blocked · 500 failed. A malformed request (missing integration_id/action_id/input) returns 400.

Succeeded (200)
{
  "execution_id": "f3c1…",
  "status": "succeeded",
  "integration_id": "gmail",
  "action_id": "send_email",
  "started_at": "2026-06-28T10:00:00.000Z",
  "finished_at": "2026-06-28T10:00:01.200Z",
  "output": { "id": "1990…", "threadId": "1990…", "labelIds": ["SENT"] },
  "display": { "title": "gmail_send_email succeeded", "summary": "Executed gmail_send_email successfully." }
}

The confirm field

Read-only actions run immediately. Write and destructive actions require confirm: true — this is a deliberate safety gate so an agent can't send an email or delete a record without an explicit go-ahead.

If you omit confirm (or set it false) on a write action, the execution is blocked before it runs:

  • status is "blocked", execution_id is null
  • error_code is "policy_blocked"
  • HTTP status is 409

To proceed, repeat the request with confirm: true.

Not sure if an action is a write? Fetch it with GET /api/actions/{integration_id}/{action_id} and check side_effect_level (read / write / delete / admin) and requires_confirmation.

Examples

Field names below come from each action's schema. Always confirm them with GET /api/actions/{integration_id}/{action_id} before going to production — schemas can change.

Send an email (gmail · send_email). user_id must be the literal string "me".

curl -X POST https://claw-link.dev/api/executions \
  -H "Authorization: Bearer cllk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_id": "gmail",
    "action_id": "send_email",
    "input": {
      "user_id": "me",
      "to": ["sarah@example.com"],
      "subject": "Hello from the API",
      "body": "Sent directly through ClawLink.",
      "is_html": false
    },
    "confirm": true
  }'

Discovering actions

You don't have to hard-code action IDs or guess input fields — the catalog is queryable.

List integrations

curl "https://claw-link.dev/api/integrations?connected_only=true" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Returns { items, page, page_size, total }. Each item includes integration_id, name, connected, connection_state, and capabilities (the action IDs it supports). Query params: query, category, connected_only, supports_action, page, page_size.

List an integration's actions

curl "https://claw-link.dev/api/actions?integration_id=gmail" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Returns { integration_id, items: [...] } where each item has action_id, title, description, and side_effect_level. Add &intent=send%20an%20email to rank by intent.

Get an action schema

This is how you find the exact input field names for an action:

curl "https://claw-link.dev/api/actions/gmail/send_email" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Returns the action detail, including input_schema (full JSON Schema), input_summary.required / input_summary.optional, requires_confirmation, side_effect_level, examples, and preconditions.

Search the whole catalog

curl "https://claw-link.dev/api/search?query=send%20message&connected_only=true" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Returns { items: [{ kind, integration_id, action_id, title, summary, connected, connection_state }] }.

Fetch a past execution

curl "https://claw-link.dev/api/executions/EXECUTION_ID" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Returns the same execution-summary shape with the stored output.

Alternative: tool-name endpoint

POST /api/tools/{tool_name}/execute is the lower-level endpoint the OpenClaw plugin itself uses. Reach for it when you need to target a specific connection or attach local file bytes (see File uploads). It is tool-name-centric — use the full tool name (e.g. gmail_send_email) in the path.

Two differences from /api/executions that bite people:

  • The confirmation field is confirmed (not confirm).
  • Omitting it on a write returns HTTP 412 with error.code: "confirmation_required" (the canonical endpoint returns 409).
curl -X POST https://claw-link.dev/api/tools/gmail_send_email/execute \
  -H "Authorization: Bearer cllk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "arguments": {
      "user_id": "me",
      "to": ["sarah@example.com"],
      "subject": "Hello",
      "body": "Sent via the tool endpoint."
    },
    "connectionId": 42,
    "confirmed": true
  }'

Request fields:

argumentsobject

The action arguments. If omitted, top-level keys (other than connectionId, confirmed, files) are treated as the arguments.

connectionIdnumber | string

Target a specific connection when you have more than one for the app. Omit to use the default.

confirmedbooleandefault: false

Confirmation gate for write actions (note the -ed spelling).

filesarray

Base64 file attachments. See File uploads.

The response carries the raw execution payload (ok, data/result, error, meta) plus a canonical object with the same execution-summary shape as /api/executions. The error envelope is documented in Errors.

On this page