Agents API
Conversational Agents are in Beta and available on Professional, Scale and Enterprise. On other plans every endpoint returns 403 {"detail": {"code": "feature_disabled", "feature": "ai_agents"}}.
Base URL: https://api.sendseven.com/api/v1/automation
| Method | Path | Scope | Success |
|---|---|---|---|
GET | /agents | automation:read | 200 paginated list |
POST | /agents | automation:create | 201 agent |
GET | /agents/{agent_id} | automation:read | 200 agent |
PATCH | /agents/{agent_id} | automation:update | 200 agent |
DELETE | /agents/{agent_id} | automation:delete | 200 {success, id, message} |
PUT | /agents/{agent_id}/skills | automation:update | 200 agent |
GET | /agents/{agent_id}/knowledge-sources | automation:read | 200 list |
POST | /agents/{agent_id}/knowledge-sources | automation:update | 201 source |
PATCH | /agents/{agent_id}/knowledge-sources/{source_id} | automation:update | 200 source |
DELETE | /agents/{agent_id}/knowledge-sources/{source_id} | automation:update | 200 {success, id, message} |
POST | /agents/{agent_id}/test | automation:update | 200 — see Test console |
GET | /agents/{agent_id}/turns | automation:read | 200 — see Turn log |
List agents
GET /agents?page=1&page_size=50&search=support
| Parameter | Notes |
|---|---|
page | Default 1 |
page_size | Default 50, max 100 |
search | Optional, max 100 characters, matches the name |
Returns {"items": [Agent, …], "pagination": {…}}.
Create an agent
POST /agents — unknown fields are rejected with 422.
{
"name": "Shop Support",
"is_active": false,
"persona": "You are Mia, the friendly support assistant of Example Shop.",
"instructions": "Answer questions about orders, shipping and returns.",
"model_tier": "standard",
"display_name": "Mia",
"greeting_message": "Hi! I'm Mia. How can I help?",
"language_settings": {"base_language": "en", "response_language": null},
"escalation": {"enabled": true, "handoff_message": "I'm connecting you with a colleague."},
"tools_config": {"search_knowledge": true, "web_search": false, "handoff": true, "set_state": true},
"handoff_config": {"keywords": ["human"], "max_turns": 30, "max_consecutive_fallbacks": 2, "handoff_tag_ids": ["TAG_ID"]},
"skills": [{"skill_id": "SKILL_ID", "mode": null, "pinned_version_id": null}],
"knowledge_sources": [{"source_type": "faq"}]
}
Fields
| Field | Type | Notes |
|---|---|---|
name | string | Required on create. 1-255 characters. |
is_active | boolean | Default true. Create agents inactive, test them, then activate. |
persona | string | Who the agent is and how it speaks. Max 20,000 characters. |
instructions | string | What the agent does. Max 20,000 characters. |
model_tier | standard | advanced | Default standard ("Fast", 1 AI credit per message). advanced ("Deeper thinking") bills 2 AI credits per reply it writes and always uses a 15-second turn budget (turn_timeout_ms is ignored). Tool credits are the same. |
display_name | string | Name shown to contacts. Max 255. |
greeting_message | string | Max 2,000. Blank clears it. |
ai_disclosure_message | string | The notice that the contact is talking to an AI. Max 2,000. It cannot be removed: blank or null uses the built-in, localized default. |
ai_disclosure_include_escalation | boolean | Also tell the contact how to reach a human. Default true. |
language_settings | object | See Language settings. |
escalation | object | See Escalation settings. |
tools_config | object | See Tools. |
handoff_config | object | See Hand-off config. |
max_tool_calls | integer | Tool calls allowed per turn. Default 4. Values outside 1..6 are clamped, not rejected. |
turn_timeout_ms | integer | Time budget per turn for model_tier: standard. Default 8000. Values outside 2000..15000 are clamped. advanced agents always get 15000. |
source_footer_enabled | boolean | Show a "Sources" footer under answers based on your knowledge. Default false. |
source_footer_mode | urls_only | urls_and_kb | Default urls_only (links to your website pages only). urls_and_kb also adds a generic "Knowledge Base" line for FAQ and document sources. |
source_link_params | object | Query parameters added to your website links in the footer, per channel. See Source link parameters. |
settings | object | Free-form settings, max 16 KB, max 6 levels deep. |
skills | array | Create only. Up to 50 skill links. |
knowledge_sources | array | Create only. Up to 20 knowledge sources. |
PATCH /agents/{agent_id} accepts the same fields except skills and knowledge_sources, all optional. Use PUT /agents/{agent_id}/skills and the knowledge source endpoints for those.
Language settings
| Field | Notes |
|---|---|
base_language | Max 10 characters. The agent's main language. Response default en. |
response_language | null or auto = answer in the contact's language. A language code = always answer in that language. |
language_detection_strategy | cascade (default behaviour) or fixed (always answer in base_language). |
auto_translate_messages | boolean |
PATCH updates only the language fields you send; omitted fields keep their value.
Auto vs fixed. These are the two language modes the app and the agent builder use:
| Mode | language_detection_strategy | response_language | The agent answers in |
|---|---|---|---|
| Auto | cascade | null | The contact's language |
| Fixed | fixed | the base_language code | base_language |
To switch an agent from fixed to auto, send both fields. If you only change the strategy, the old response_language stays set and the agent keeps answering in that language:
PATCH /agents/{agent_id}
{"language_settings": {"language_detection_strategy": "cascade", "response_language": null}}
To switch to fixed, send {"language_detection_strategy": "fixed", "response_language": "<base_language>"}.
Escalation settings
Same names and meaning as on the FAQ Bot:
| Field | Notes |
|---|---|
enabled | Whether the agent may hand over to a human. With false, the handoff tool is not offered and the deterministic triggers do not fire. |
offers_escalation | boolean |
handoff_message | Sent to the contact on hand-over. Max 2,000. |
escalation_keywords | Used when handoff_config.keywords is not set. |
offline_escalation_behavior | Live chat: what happens when nobody is online. |
offline_message, outside_hours_message | Max 2,000 each. |
is_escalation_schedule_enabled, escalation_timezone, escalation_schedule | The hand-over schedule. |
Routing a hand-over to a team member is configured on the agent's bot record. See Hand-off & assignment.
Tools config
| Key | Default | Notes |
|---|---|---|
search_knowledge | true | |
web_search | false | Also needs an enabled web_search knowledge source. Set it explicitly. |
handoff | true | Only offered while escalation is enabled. |
set_state | true | |
load_skill | true |
Unknown keys are rejected. complete_task is not configurable: it exists only when a Flow gives the agent a task. Details in Tools & turn lifecycle.
Hand-off config
| Field | Notes |
|---|---|
keywords | Up to 50 words (max 100 characters each, de-duplicated case-insensitively). A contact message containing one hands over immediately, before any AI call. When not set, the escalation keywords are used. |
max_turns | 1..200. Hands over once the conversation goes past this many contact turns. |
max_consecutive_fallbacks | 1..20, default 2. Hands over after this many turns in a row in which the agent could not answer. |
handoff_tag_ids | Up to 20 tag ids from your workspace. The agent may pick one of them when it hands over, and the tag is added to the conversation. Unknown tags: 422 {"code": "invalid_handoff_tags", "message": "Unknown handoff tag(s)", "tag_ids": […]}. |
handoff_message | Max 2,000. Message sent on hand-over. |
handoff_config may be at most 8 KB serialized.
Source link parameters
Add tracking parameters to links to your website pages in the sources footer. Keys are channel types, or default:
{
"source_link_params": {
"default": {"utm_source": "sendseven", "utm_medium": "{channel_type}"},
"live_chat": {"utm_source": "chat", "utm_content": "{widget_id}"}
}
}
Placeholders: {bot_id}, {bot_name} (as a URL slug), {channel_type}, {channel_id}, {tenant_id}, {widget_id} (Live Chat only). A parameter whose placeholder cannot be filled for a message is left out.
Response
{
"id": "…",
"bot_id": "…",
"tenant_id": "…",
"name": "Shop Support",
"is_active": false,
"persona": "…",
"display_name": "Mia",
"avatar_url": null,
"greeting_message": "…",
"ai_disclosure_message": null,
"ai_disclosure_include_escalation": true,
"instructions": "…",
"model_tier": "standard",
"language_settings": {"response_language": null, "base_language": "en", "auto_translate_messages": false, "language_detection_strategy": null},
"escalation": {"enabled": true, "offers_escalation": true, "handoff_message": "…", "escalation_keywords": null, "offline_escalation_behavior": "leave_message", "offline_message": null, "outside_hours_message": null, "is_escalation_schedule_enabled": false, "escalation_timezone": "UTC", "escalation_schedule": null},
"source_footer_enabled": false,
"source_footer_mode": "urls_only",
"source_link_params": null,
"tools_config": {"search_knowledge": true, "web_search": false, "handoff": true, "set_state": true, "load_skill": true},
"handoff_config": {"keywords": ["human"], "max_turns": 30, "max_consecutive_fallbacks": null, "handoff_tag_ids": [], "handoff_message": null},
"max_tool_calls": 4,
"turn_timeout_ms": 8000,
"settings": null,
"skills": [
{"skill_id": "…", "slug": "order-return", "title": "Order returns", "mode": null, "effective_mode": "model_selected", "pinned_version_id": null, "current_version": 3, "pinned_version": null, "is_archived": false, "sort_order": 0}
],
"knowledge_sources": [
{"id": "…", "source_type": "faq", "kb_folder_id": null, "kb_folder_name": null, "allowed_domains": null, "is_enabled": true, "config": null, "sort_order": 0, "created_at": "2026-10-05T09:00:00Z", "updated_at": "2026-10-05T09:00:00Z"}
],
"created_at": "2026-10-05T09:00:00Z",
"updated_at": "2026-10-05T09:00:00Z"
}
Delete an agent
DELETE /agents/{agent_id} deletes the agent with its bot record, channel rules, sessions, skill links and knowledge sources. Skills themselves are kept.
While a published or paused Flow uses the agent, the delete is refused:
{
"detail": {
"code": "agent_in_use",
"message": "This agent is used by published or paused flows. Remove it from these flows first.",
"flows": [{"id": "…", "name": "Returns", "status": "published", "node_ids": ["node_7"]}]
}
}
Skill links
PUT /agents/{agent_id}/skills replaces all of the agent's skill links. Send an empty list to unlink every skill.
{
"skills": [
{"skill_id": "SKILL_ID_BASICS", "mode": "always_on"},
{"skill_id": "SKILL_ID_RETURNS", "pinned_version_id": "VERSION_ID", "sort_order": 1}
]
}
| Field | Notes |
|---|---|
skill_id | Required. A skill in your workspace. |
mode | always_on, model_selected, flow_only or null (use the skill's default_mode). |
pinned_version_id | null = follow the skill's current version. Otherwise a version of this skill; the agent keeps using it when the skill changes. |
sort_order | 0..10000 |
Max 50 links. Returns 422 for a duplicate skill_id, an unknown skill_id, an archived skill, or a pinned_version_id that does not belong to the skill. The response is the full agent; each link shows effective_mode, current_version and pinned_version.
Knowledge sources
source_type | Extra fields | Searches |
|---|---|---|
kb_folder | kb_folder_id (required) | One Knowledge Base folder |
kb_all | — | Every folder that is enabled for AI search |
faq | — | All published FAQ entries |
web_search | allowed_domains (optional, max 50) | The web, limited to these domains when set |
curl -X POST "https://api.sendseven.com/api/v1/automation/agents/AGENT_ID/knowledge-sources" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"source_type": "web_search", "allowed_domains": ["https://www.example.com/help", "docs.example.com"]}'
| Field | Notes |
|---|---|
source_type | Create only, cannot be changed. |
kb_folder_id | Only for kb_folder. |
allowed_domains | Only for web_search. Entries are normalised to bare host names: https://Www.Example.com/path becomes www.example.com, *.example.com becomes example.com. IP addresses are rejected. |
is_enabled | Default true. A disabled source is ignored. |
config | Free-form object, max 4 KB. |
sort_order | 0..10000 |
- When the agent has no
kb_folder,kb_allorfaqsource, it searches your whole AI-searchable Knowledge Base. - Conversation-history and ticket-summary folders are never searched.
search_knowledgesearches up to 8 sources per call, FAQ first.
GET …/knowledge-sources returns {"items": [...], "pagination": {...}} with all sources (max 20, no paging parameters).
Knowledge source errors
| Status | Detail |
|---|---|
422 | "kb_folder_id does not exist" |
422 | "This folder cannot be used as an agent knowledge source" (conversation-history and ticket-summary folders) |
422 | {"code": "use_faq_source", "message": "…"} — the managed FAQ folder cannot be added as a folder. Add a faq source instead. |
422 | "At most 20 knowledge sources per agent" |
422 | kb_folder_id or allowed_domains on the wrong source_type |
404 | "Knowledge source not found" |
Common errors
| Status | When |
|---|---|
403 | {"code": "feature_disabled", "feature": "ai_agents"} (or ai_features) — the plan does not include Conversational Agents. A missing scope returns 403 "Insufficient scopes". |
404 | "Agent not found" |
409 | agent_in_use on delete |
422 | Validation errors: unknown fields, lengths, enums, JSON size limits, handoff tags, skill links, knowledge sources |
See Billing, errors & limits for the full list.