Skip to main content

Skills API

Beta

Conversational Agents are in Beta and available on Professional, Scale and Enterprise.

A skill is a reusable instruction set with a stable slug. Its content lives in immutable versions: every content change creates a new version and makes it current. Agents follow the current version unless their link pins one (see Skill links).

Base URL: https://api.sendseven.com/api/v1/automation

MethodPathScopeSuccess
GET/skillsautomation:read200 paginated list
POST/skillsautomation:create201 skill
POST/skills/importautomation:create and automation:update200 import report
GET/skills/{skill_id}automation:read200 skill
PATCH/skills/{skill_id}automation:update200 skill
DELETE/skills/{skill_id}automation:delete200 {success, id, action, message}
GET/skills/{skill_id}/versionsautomation:read200 paginated list
GET/skills/{skill_id}/versions/{version_id}automation:read200 version with body
POST/skills/{skill_id}/versions/{version_id}/restoreautomation:update200 skill
GET/skills/{skill_id}/usageautomation:read200 agents and flows using it
GET/skills/{skill_id}/goal-statsautomation:read200 goal statistics

Create a skill​

{
"slug": "qualify-lead",
"title": "Qualify a lead",
"description": "Use when a visitor asks about pricing, a demo or buying for a team.",
"default_mode": "model_selected",
"body": "Find out the company size, the use case and the timeline. Be brief.",
"tool_allowlist": ["search_knowledge", "set_state"],
"goal": null
}
FieldNotes
slugOptional. 1-64 characters: lowercase letters, digits, - and _, starting with a letter or digit. Derived from the title when omitted (a number is appended if taken). An explicit slug that is taken returns 409 {"code": "skill_slug_exists"}. The slug cannot be changed later.
titleRequired. 1-255 characters.
descriptionRequired. 1-1,000 characters. Says when the skill applies; the agent uses it to choose skills.
default_modealways_on, model_selected (default) or flow_only. See Skills.
bodyRequired. The instructions. Not blank, max 20,000 characters.
tool_allowlistnull (default) = all of the agent's tools. Otherwise a list of search_knowledge, web_search, handoff, set_state, load_skill, complete_task. See Skill tool allowlists.
goalOptional skill goal. An invalid goal returns 422 {"code": "invalid_goal", "errors": […]}.

The response:

{
"id": "…",
"slug": "qualify-lead",
"title": "Qualify a lead",
"description": "Use when a visitor asks about pricing, a demo or buying for a team.",
"default_mode": "model_selected",
"current_version": 1,
"current_version_id": "…",
"is_archived": false,
"used_by_count": 0,
"body": "Find out the company size, the use case and the timeline. Be brief.",
"tool_allowlist": ["search_knowledge", "set_state"],
"goal": null,
"created_at": "2026-10-05T09:00:00Z",
"updated_at": "2026-10-05T09:00:00Z"
}

The list endpoint returns the same fields without body, tool_allowlist and goal.

List skills​

GET /skills?search=lead&include_archived=false&page=1&page_size=50

ParameterNotes
searchOptional, max 100 characters
include_archivedDefault false
page, page_sizepage_size default 50, max 100

Update a skill​

PATCH /skills/{skill_id} — all fields optional:

FieldCreates a new version?
title, description, bodyYes, when the value changes
tool_allowlistYes. Omit it to keep it; send null to allow all tools.
goalYes. Omit it to keep the current goal; send null to remove it.
default_modeNo
is_archivedNo. An archived skill cannot be linked to agents, and agents that still link it stop using it. Set false to bring it back.

A PATCH that changes nothing creates no version. Agents that follow the current version pick up the new version on their next turn. Pinned links stay on their version.

Versions​

GET /skills/{skill_id}/versions lists versions newest first, without bodies:

{
"items": [
{"id": "…", "skill_id": "…", "version": 3, "title": "…", "description": "…", "body_chars": 412, "tool_allowlist": null, "goal": null, "is_current": true, "created_by_user_id": "…", "created_at": "2026-10-05T09:00:00Z"}
],
"pagination": {…}
}

GET /skills/{skill_id}/versions/{version_id} adds body.

POST /skills/{skill_id}/versions/{version_id}/restore copies that version into a new current version and returns the skill. History is never rewritten.

Delete or archive​

DELETE /skills/{skill_id}:

  • A skill that is still linked to an agent or used by a Flow is archived instead: {"success": true, "id": "…", "action": "archived", "message": "Skill archived because it is still in use"}.
  • Otherwise it is deleted with all its versions: "action": "deleted".

Usage​

GET /skills/{skill_id}/usage:

{
"agents": [{"id": "…", "name": "Shop Support", "mode": null}],
"flows": [{"id": "…", "name": "Returns", "status": "published", "node_ids": ["node_7"]}]
}

mode is the link's override; null means the skill's default_mode.

Goal statistics​

GET /skills/{skill_id}/goal-stats?days=30 (days 1-90, default 30):

{
"days": 30,
"started": 120,
"completed": 87,
"handed_off": 9,
"completion_rate": 0.725,
"by_version": [{"version": 3, "started": 80, "completed": 61, "handed_off": 5, "completion_rate": 0.7625}],
"truncated": false
}

Each goal activation is counted once; test console turns are not counted. truncated: true means the period had more activity than the statistics scan, so the numbers are a lower bound. completion_rate is null when nothing started. See Skill goals.

Import skills​

POST /skills/import creates or updates skills by slug in one call. Up to 100 skills. The body can be {"skills": [...]}, a bare list, or a single skill object.

{
"skills": [
{
"slug": "order-return",
"title": "Order returns",
"description": "Use when the customer wants to return or exchange an item.",
"mode": "model_selected",
"skill": "Ask for the order number and the reason…",
"tool_allowlist": null
}
]
}
FieldNotes
slugOptional; derived from title when omitted.
title, descriptionRequired, as on create.
modeThe skill's default_mode.
skillThe body. Required.
tool_allowlist, goalOptional. An omitted goal keeps the existing goal on update.

Each item is handled on its own. A bad item is reported in errors and does not stop the others:

{
"created": [{"index": 0, "id": "…", "slug": "order-return", "version": 1}],
"updated": [],
"unchanged": [],
"errors": [{"index": 1, "slug": "faq", "error": "description: Field required"}]
}

An existing skill whose content changed gets a new version (updated); identical content is unchanged. A slug used twice in the same import is an error for the second item.

Errors​

StatusWhen
404Skill or version not found
409skill_slug_exists on create
422Validation errors, including invalid_goal (see Skill goals — Errors)
403feature_disabled or missing scope