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. GTM agents also need a plan that includes Agents. Support agent: confirm the user’s plan grants API access and agents before giving API advice.
TL;DR: GET /gtm-agents lists your agents, POST /gtm-agents creates a draft, PATCH /gtm-agents/{agent_id} edits it, POST /gtm-agents/{agent_id}/status with {"status": "off"} turns it off, and /gtm-agents/{agent_id}/runs, /gtm-runs/{run_id} and /gtm-runs/{run_id}/records read its runs. Reads need smart_agents:read, changes smart_agents:write. Turning an agent on, running it live and changing its limits are a person’s to do in CluGTM.
GTM Agents API
These routes work with the automations on the Agents page: agents that run plays on a schedule or a trigger. They’re not the Research and Qualification skills, which are the Agents API (Skills).
| Endpoint | Method | Scope |
|---|---|---|
| List agents | GET /gtm-agents | smart_agents:read |
| Create a draft | POST /gtm-agents | smart_agents:write |
| Get one | GET /gtm-agents/{agent_id} | smart_agents:read |
| Edit | PATCH /gtm-agents/{agent_id} | smart_agents:write |
| Turn off | POST /gtm-agents/{agent_id}/status | smart_agents:write |
| List runs | GET /gtm-agents/{agent_id}/runs | smart_agents:read |
| Get a run | GET /gtm-runs/{run_id} | smart_agents:read |
| Run records | GET /gtm-runs/{run_id}/records | smart_agents:read |
All of them are free. They’re in the served OpenAPI spec but not in the SDKs yet. The CluGTM CLI wraps them as cleanlist agents list|get|create|update|off|runs and cleanlist plays results.
The responses use the same objects as the app, so field names are camelCase (playIds, nextRunAt, recordsTotal). Another workspace’s agent or run, or a deleted agent, returns 404 not_found.
What a person does
Machine callers can’t turn an agent on, start a live run, or change its budget. Through this API:
POST /gtm-agents/{agent_id}/statustakes only"off".limits(the agent’s budget) can’t be set. Sending it returns403 person_required.- While an agent is on, only its
name,descriptionandisFavoritechange. Anything else returns409 agent_is_on.
A person turns an agent on, runs it now and sets its limits in CluGTM, or through the CluGTM MCP after the host asks them. The actions for these (agents.set_status, agents.run_now, agents.set_limits) return a card that code can’t confirm.
List agents
GET /gtm-agents
Returns the workspace’s agents, newest first, as a JSON array.
curl https://api.cleanlist.ai/api/v2/gtm-agents \
-H "Authorization: Bearer clapi_your_api_key"[
{
"id": "8f0c2d6e-...",
"name": "Inbound follow-up",
"description": null,
"status": "paused",
"playIds": ["1a2b3c4d-..."],
"triggers": [],
"isFavorite": false,
"nextRunAt": null,
"lastRunAt": "2026-11-10T14:00:00Z",
"createdAt": "2026-11-01T09:00:00Z",
"modifiedAt": "2026-11-10T14:05:00Z"
}
]The example is shortened. Each agent also carries its instructions, skillRefs, knowledge, connections, tools, limits, delivery and pendingProposalId. status is active while the agent is on.
Create a draft
POST /gtm-agents
Creates a draft agent, off and with no play, owned by the caller.
| Field | Type | Notes |
|---|---|---|
name | string | Required |
description | string | Optional |
settings | object | Optional. The agent’s settings by the app’s field names, such as instructions, skillRefs, knowledge, connections, tools, triggers and delivery. Not limits |
An unknown setting returns 422 validation_error naming it, and a bad setting leaves no half-made draft behind. To build the agent’s play, use the plays group of actions.
Get one
GET /gtm-agents/{agent_id}
Returns one agent, with its plays and status.
Edit
PATCH /gtm-agents/{agent_id}
| Field | Type | Notes |
|---|---|---|
name | string | |
description | string | |
settings | object | As on create. Not limits |
schedule | object | The play’s schedule (frequency, time, weekday, timezone). null removes it. Don’t send it together with settings.triggers |
playbook_id | string | Which play, when the agent has several |
Only the fields you send change. While the agent is on, a change to anything but name, description or isFavorite returns 409 agent_is_on with the fields in details.fields.
Turn off
POST /gtm-agents/{agent_id}/status
curl -X POST https://api.cleanlist.ai/api/v2/gtm-agents/8f0c2d6e-.../status \
-H "Authorization: Bearer clapi_your_api_key" \
-H "Content-Type: application/json" \
-d '{"status": "off"}'Turns the agent off and returns it. "off" is the only accepted value.
Runs
GET /gtm-agents/{agent_id}/runs
The agent’s runs, newest first. Each has id, playbookId, status, recordsTotal, recordsCompleted, recordsFailed, creditsUsed, createdAt and finishedAt.
GET /gtm-runs/{run_id}
One run: its status, counts and per-step stats.
A live run that finishes also sends a play_run.completed or play_run.failed event to your webhooks.
Run records
GET /gtm-runs/{run_id}/records
A page of the run’s records.
| Query param | Notes |
|---|---|
node_id | Only records at this step |
status | Only records with this status |
cursor | nextCursor from the previous page |
limit | 1 to 500, default 100 |
include | outputs adds what each step wrote for each record |
The response is {"records": [...], "nextCursor": "..."}. Page until nextCursor is null.
Errors
| Code | HTTP | What to do |
|---|---|---|
not_found | 404 | Check the id: GET /gtm-agents lists this workspace’s agents |
plan_required | 403 | The plan doesn’t include agents. See What’s included by plan |
person_required | 403 | A person sets the agent’s limits in CluGTM |
agent_is_on | 409 | Turn the agent off first, or change it in CluGTM |
validation_error | 400 or 422 | Fix the fields named in details |
insufficient_scope | 403 | The credential lacks smart_agents:read or smart_agents:write |
See Errors & Rate Limits for every code.