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_idstringrequiredThe integration slug, e.g. gmail, slack, instagram. See
discovering actions.
action_idstringrequiredThe action to run, e.g. send_email. This is the tool name with the integration prefix
removed (gmail_send_email → send_email). The full tool name (gmail_send_email)
also works.
inputobjectrequiredThe action's arguments. Field names are specific to each action — fetch them with
GET /api/actions/{integration_id}/{action_id}.
confirmbooleandefault: falseRequired (true) for any write or destructive action. See The confirm field.
idempotency_keystringOptional 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.
statusstringsucceeded, blocked, or failed.
execution_idstring | nullStable ID of the run. null when the action was blocked before running (e.g. missing
confirmation). Pass to GET /api/executions/{id}.
integration_idstringaction_idstringstarted_atstringfinished_atstringoutputanyThe provider's result payload. Present on success.
displayobject{ title, summary } — a short human-readable description of the outcome.
error_codestringPresent when blocked or failed. See Errors.
messagestringHuman-readable error message (on blocked / failed).
hintstringActionable guidance for recovering from a failure, when available.
recommended_next_actionobjecte.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.
{
"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:
statusis"blocked",execution_idisnullerror_codeis"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(notconfirm). - Omitting it on a write returns HTTP
412witherror.code: "confirmation_required"(the canonical endpoint returns409).
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:
argumentsobjectThe action arguments. If omitted, top-level keys (other than connectionId,
confirmed, files) are treated as the arguments.
connectionIdnumber | stringTarget a specific connection when you have more than one for the app. Omit to use the default.
confirmedbooleandefault: falseConfirmation gate for write actions (note the -ed spelling).
filesarrayBase64 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.