Agents API
Agents are AI workers that monitor contacts matching a filter, analyze their activity, and propose actions. Each agent has a playbook (a markdown prompt) that defines its reasoning, plus capabilities, monitoring config, and an LLM config.
List Agents
Section titled “List Agents”GET /v1/agentsRequired scope: agents:read
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | boolean | — | Filter by enabled/disabled status. |
playbook_template | string | — | Filter by playbook template. |
limit | number | 20 | Results per page (1–100). |
offset | number | 0 | Pagination offset. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "agents": [ /* agent objects */ ], "total": 5, "limit": 20, "offset": 0}Create an Agent
Section titled “Create an Agent”POST /v1/agentsRequired scope: agents:write
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Agent display name. |
description | string | no | Human-readable description. |
playbook_template | string | no | Predefined template (e.g. cold_outreach, pricing_visitor_followup). |
playbook | object | no | Custom playbook — { playbook_md: "..." } plus optional structured config. |
capabilities | string[] | no | Allowed capabilities (e.g. email, linkedin, notes, crm_sync). |
identity_id | string | no | Default identity used for outreach actions. |
monitoring | object | no | { filter, schedule_cron, max_contacts_per_run } — who/when to monitor. |
llm_config | object | no | { provider, model, temperature, max_tokens }. |
enabled | boolean | no | Whether the agent is active (default: false). |
Example — minimal agent with a custom playbook
Section titled “Example — minimal agent with a custom playbook”curl -X POST https://api.pathbound.ai/v1/agents \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Pricing visitor follow-up", "description": "Drafts a personal email when a contact visits /pricing twice in 7 days.", "playbook": { "playbook_md": "You are an SDR. For each contact, look at their recent events. If they visited /pricing 2+ times in the last 7 days and have not received an email from us in the last 3 days, propose a short, personal follow-up email referencing what they did on the site. Keep it under 80 words. If conditions are not met, propose no action." }, "capabilities": ["email"], "identity_id": "id_123", "monitoring": { "filter": { "lifecycle_stage": "lead" }, "schedule_cron": "0 14 * * 1-5", "max_contacts_per_run": 25 }, "llm_config": { "provider": "anthropic", "model": "claude-opus-4-7", "temperature": 0.4 }, "enabled": true }'Response — 201 Created
Section titled “Response — 201 Created”{ "status": "success", "agent": { /* agent object */ }}Get an Agent
Section titled “Get an Agent”GET /v1/agents/:idRequired scope: agents:read
Update an Agent
Section titled “Update an Agent”PATCH /v1/agents/:idRequired scope: agents:write
Send only the fields you want to update. To revise just the playbook prompt, send { "playbook": { "playbook_md": "..." } }.
Delete an Agent
Section titled “Delete an Agent”DELETE /v1/agents/:idRequired scope: agents:write
Deleting an agent also removes its associated runs.
Trigger an Agent Run
Section titled “Trigger an Agent Run”POST /v1/agents/:id/triggerRequired scope: agents:trigger
Manually trigger a run, optionally targeting specific contacts.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
contact_ids | string[] | no | Specific contacts to target. If omitted, the agent uses its monitoring filter. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "job_id": "job_xyz789"}The run is enqueued for asynchronous execution. Poll with GET /v1/agents/:id/runs to see when it completes.
List Agent Runs
Section titled “List Agent Runs”GET /v1/agents/:id/runsRequired scope: agents:read
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Results per page (1–100). |
offset | number | 0 | Pagination offset. |
status | string | — | Filter by run status. |
Get a Single Run
Section titled “Get a Single Run”GET /v1/agents/runs/:runIdRequired scope: agents:read
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | full | summary (counts + status only) or full (per-contact results). |
In full mode, the response is capped at 25 contacts and includes proposed actions per contact, each addressed by (run_id, contact_id, action_index) for approval.
Response — 200 OK (summary)
Section titled “Response — 200 OK (summary)”{ "status": "success", "run": { "_id": "run_abc", "agent_id": "ag_123", "status": "completed", "started_at": "...", "completed_at": "...", "summary": { "contacts_evaluated": 42, "actions_proposed": 18, "actions_auto_approved": 6, "actions_pending_approval": 12, "errors": 0 } }}Response — 200 OK (full)
Section titled “Response — 200 OK (full)”{ "status": "success", "run": { "_id": "run_abc", "agent_id": "ag_123", "status": "completed", "summary": { /* same as above */ }, "contact_results": [ { "contact_id": "ct_abc", "contact": { "email": "...", "firstname": "..." }, "reasoning": "Visited /pricing 3 times this week, no email in 5 days...", "proposed_actions": [ { "type": "email_message", "params": { "subject": "...", "message": "..." }, "status": "pending_approval" } ] } ] }}Approve a Pending Action
Section titled “Approve a Pending Action”POST /v1/agents/runs/:runId/contacts/:contactId/actions/:actionIndex/approveRequired scope: agents:approve
Approves a single action proposed in a run. The action is then queued for execution.
Reject a Pending Action
Section titled “Reject a Pending Action”POST /v1/agents/runs/:runId/contacts/:contactId/actions/:actionIndex/rejectRequired scope: agents:approve
Rejects a single proposed action. It will not execute.
Playbook authoring
Section titled “Playbook authoring”Playbooks are markdown prompts that define the agent’s reasoning. They are sent to the LLM with structured context about each contact. A few patterns that work well:
- Be explicit about what to skip. “If the contact has not had a pageview in 14 days, propose no action.”
- Constrain the action shape. “Keep emails under 80 words. Always reference a specific event in their timeline.”
- Use the structured fields when possible. Agents have access to
events,unified_profile,recent_actions— instruct the playbook to reason from those before generating output. - Set
require_approval: truefor outbound actions until you trust the agent. Auto-approval is convenient but cannot be undone after execution.
For approval at scale, prefer the agent run approval endpoints over per-action endpoints — they share state (run_id) and let you bulk-approve a run from your UI.