Skip to Content
New: meet Clu, and send email, LinkedIn and call steps with Sequences. Watch the videos →
API Reference (v2)Actions & Approval Cards
🔌

Audience: developers. API keys need a Pro or Enterprise plan (legacy Pro and Scale plans included) or an AppSumo Tier 5, 6 or 7 license, and they never work during a trial. Support agent: confirm the user’s plan grants API access before giving API advice.

TL;DR: GET /actions lists the Clu tools your credential can call, by group (lists, skills, agents, plays, sequences, crm), each with an input_schema. POST /actions/{name} runs one. A read or write answers with its result; anything that spends, sends, deletes or writes to a CRM answers with a card and runs nothing until you confirm it with POST /actions/confirm (or send commit: true). Sends, CRM writes and deletes also need a key that opted into sequences:write, crm:write or lists:delete.

Actions

Actions are the tools Clu uses in the app, callable from code by a stable public name such as lists.rename, skills.run_on_list or sequences.enroll. Each runs through the same toolkit Clu uses, in your workspace, with your data and credit balance.

EndpointMethodScope
List actionsGET /actionsnone; the list is filtered by your scopes
Call an actionPOST /actions/{name}The action’s own scope
Confirm a cardPOST /actions/confirmThe action’s own scope, plus its opt-in

These endpoints are in the served OpenAPI spec but not in the SDKs yet. The CluGTM CLI wraps them as cleanlist actions list|run|confirm.

List actions

GET /actions

Returns the actions this credential can use, after the plan, connection and scope checks, plus the groups they fall in.

curl https://api.cleanlist.ai/api/v2/actions \ -H "Authorization: Bearer clapi_your_api_key"
{ "version": "5d2c...", "groups": [ { "name": "lists", "title": "Lead lists", "summary": "Read, create, rename, import into, move and delete lead lists and their leads. 2 of its actions need lists:delete, which this credential doesn't hold, so they aren't listed.", "action_count": 6, "missing_scopes": ["lists:delete"] } ], "actions": [ { "name": "lists.rename", "title": "Rename a list", "description": "...", "group": "lists", "effect": "write", "card": false, "scope": "lists:write", "input_schema": { "type": "object", "properties": { "...": {} }, "required": ["..."] } } ] }
FieldMeaning
versionA hash of the action list. It changes when the list does
groups[].missing_scopesScopes this credential lacks for the group’s other actions. Those actions aren’t listed, and summary says so
actions[].effectread or write for an action that runs when called. For a card: spend, send, internal or crm_write
actions[].cardtrue when the action returns a card instead of running
actions[].scopeThe scope the action checks: the group’s read scope for a read, its write scope otherwise
actions[].input_schemaJSON Schema for arguments. An action that works on one agent requires agent_id (from agents.list)

An action your plan doesn’t include, or one that needs a connection you haven’t made, isn’t listed. GET /actions is the source of truth; the tables below show what exists.

Groups and scopes

GroupWhat it coversRead scopeWrite scope
listsRead, create, rename, import into, move and delete lead lists and their leadslists:readlists:write
skillsCreate and change skills and record skills, add columns to a list, run them on its leadslists:readlists:write
agentsList, draft, update, schedule, turn on or off and run GTM agents, read their runs and outcomessmart_agents:readsmart_agents:write
playsBuild an agent’s play: steps, fields, audience, the requirement review, the proposal, a test run, plays run oncesmart_agents:readsmart_agents:write
sequencesCreate, edit, launch and pause sequences, enroll people, send email and LinkedIn actionssequences:readsequences:write (opt-in)
crmRead, search and match CRM records and activity, log an activity, map fields, review and merge duplicatescrm:readcrm:write (opt-in)

sequences:write and crm:write are opt-in scopes: every action in those groups that isn’t a read needs a key that opted into them. lists.delete and lists.delete_leads check lists:write and also need the lists:delete opt-in.

The actions

GroupRun when calledReturn a card
listslists.list, lists.get_leads, lists.create, lists.renamelists.import, lists.move_leads, lists.delete†, lists.delete_leads†
skillsskills.list, skills.get, skills.list_columns, skills.create, skills.attach, skills.detach, skills.create_record_skill, skills.update_record_skill, skills.add_columnskills.set_column_values, skills.run_on_list, skills.run_smart_column
agentsagents.list, agents.list_saved, agents.get, agents.list_runs, agents.get_run, agents.get_run_records, agents.outcomes, agents.list_connections, agents.list_secrets, agents.create_draft, agents.update, agents.set_scheduleagents.run_sample, agents.set_status‡, agents.set_limits‡, agents.run_now‡, agents.approve_try‡
playsplays.describe_steps, plays.get_fields, plays.describe_audience_filters, plays.size_audience, plays.lookup_filter_values, plays.describe_sheet, plays.describe_notion_database, plays.list_sequencer_sequences, plays.list_sequencer_users, plays.get_webhook_samples, plays.crm_scan_status, plays.list_crm_values, plays.describe_crm_object, plays.list_crm_views, plays.draft_spec, plays.check_build, plays.check_configuration, plays.find_test_records, plays.get_run_results, plays.build_from_spec, plays.propose_changes, plays.discard_proposal, plays.run_test, plays.create_webhook_endpointplays.review_requirements, plays.accept_proposal, plays.run_once‡, plays.repeat‡
sequencessequences.list, sequences.get, sequences.list_mailboxes, sequences.list_linkedin_accounts, sequences.list_lead_calls, sequences.create†sequences.edit†, sequences.set_status†, sequences.enroll†, sequences.send_email†, sequences.linkedin_action†, sequences.post_comment†
crmcrm.match_people, crm.read_account, crm.search_records, crm.read_record, crm.count_activity, crm.list_activity_fields, crm.list_users, crm.read_integrations, crm.read_6sense_scores, crm.find_duplicates, crm.read_duplicate_group, crm.dismiss_duplicates†, crm.skip_duplicates†crm.create_activity†, crm.merge_duplicates†, crm.add_field_mappings†

† Needs a key that opted into the group’s opt-in scope (lists:delete, sequences:write or crm:write). ‡ A person only: code can get the card but can’t confirm it (403 person_required).

Call an action

POST /actions/{name}

FieldTypeNotes
argumentsobjectThe action’s arguments, as its input_schema describes. Default {}
session_idstringThe session_id from an earlier call. Leave it out and a new session is created and returned
commitbooleanCode only. true confirms a card in the same call. Default false: a card is a preview and nothing runs
curl -X POST https://api.cleanlist.ai/api/v2/actions/lists.rename \ -H "Authorization: Bearer clapi_your_api_key" \ -H "Content-Type: application/json" \ -d '{"arguments": {"list_id": "9c1f7e2a-...", "new_name": "Q4 ABM"}}'

Read each action’s argument names from its input_schema.

An action that runs answers with its result:

{ "action": "lists.rename", "session_id": "0b8e6c1a-...", "kind": "result", "result": { "...": "..." }, "card": null, "confirmed": null }

A card action answers with kind: "card" and runs nothing:

{ "action": "lists.delete", "session_id": "0b8e6c1a-...", "kind": "card", "result": null, "card": { "card_id": "5f2b9c0e7d4a4b1f8e6a3c2d1b0a9f8e", "title": "Delete a list", "summary": "... Confirming it adds the 0.2-credit action fee.", "credits_required": 0.2, "expires_at": "2026-11-12T15:10:00+00:00" }, "confirmed": null }

Show the card to a person: title, summary and credits_required say what will happen and what it costs. A card that names a lead list is refused with 404 list_not_found before it’s issued if the list isn’t in your workspace. Every issued card also sends an approval.needed event to your webhooks.

Reads stop after 60 seconds (504 action_timeout). A write runs to the end, so it’s never left half done.

Confirm a card

POST /actions/confirm

FieldTypeNotes
card_idstringRequired. From the card
session_idstringRequired. The session the card was issued in
curl -X POST https://api.cleanlist.ai/api/v2/actions/confirm \ -H "Authorization: Bearer clapi_your_api_key" \ -H "Content-Type: application/json" \ -d '{"card_id": "5f2b9c0e7d4a4b1f8e6a3c2d1b0a9f8e", "session_id": "0b8e6c1a-..."}'
{ "card_id": "5f2b9c0e7d4a4b1f8e6a3c2d1b0a9f8e", "status": "done", "result": { "...": "..." } }

status is done or failed. A card runs exactly the arguments it was issued with, once:

  • A card confirms only on the channel that issued it. A card from the CluGTM MCP can’t be confirmed with an API key, and the reverse (404 card_not_found).
  • A card past its expires_at returns 410 card_expired. Call the action again.
  • Confirming the same card again, for example after a dropped connection, returns its first result. If it’s still running you get 409 card_already_used; confirm again in a minute to read the result.

To issue and confirm in one call, send "commit": true on POST /actions/{name}. The response then has the card and, in confirmed, the same body POST /actions/confirm returns. The same rules apply.

Who can confirm what

CardFrom code (API key, CLI)From the CluGTM MCP
Spends credits or changes data in CluGTM (an import, a skill run, a play proposal)The action’s scopeThe person’s yes in the chat
Sends, CRM writes and deletesThe key’s opt-in scope: sequences:write, crm:write or lists:deleteThe person approves in the host app’s own approval prompt
Turns an agent on, runs it now, changes its limits, runs or repeats a play, approves a TryNever: 403 person_requiredThe person approves in the host app’s own approval prompt

From code, a key without the opt-in is refused before a card is issued, with 403 opt_in_scope_required and details.required_scope. The person ticks it on the key under Settings → API keys → Permissions (see Opt-in scopes).

Cost

Each call is metered like the same tool called from Clu, on its own usage receipt. A card’s credits_required is the work’s estimate plus the 0.2-credit action fee that confirming it charges, and its summary says so. If the balance can’t cover a call you get 402 insufficient_credits.

Errors

CodeHTTPWhat to do
action_not_found404No action by that name for this credential, or it isn’t available to this workspace. List them with GET /actions
insufficient_scope403The credential lacks the action’s scope
opt_in_scope_required403The key hasn’t opted into details.required_scope. Tick it on the key, or do it in CluGTM
person_required403A person must confirm this card in CluGTM
plan_required403The plan doesn’t include this action. Upgrade, then call again
invalid_arguments422The arguments don’t match the action’s input_schema
list_not_found, agent_not_found404The list or agent isn’t in this workspace
session_not_found404No such session for this caller. Leave session_id out to start one
card_not_found404No such card for this caller and session, or it was issued on the other channel
card_expired410Call the action again for a new card
card_already_used409The card is still running. Confirm again in a minute to read its result
session_busy409Another call is running in this session. Retry when it ends
action_not_rerun409This call already ran and won’t run twice
insufficient_credits402The balance can’t cover the call
budget_stopped402The call doesn’t fit the session’s tool-call or credit budget
too_many_running429Too many calls are running in this workspace. Retry shortly
action_timeout504A read ran past 60 seconds. Retry with a narrower request
plan_unavailable, metering_unavailable503Retry shortly

See Errors & Rate Limits for every code.