Sections API
Read and replace an agent's instruction sections over the REST API, for example to keep them in sync with files in a Git repository.
On this page
The Sections API reads and writes an agent's instruction sections: the named blocks of guidance the agent reads after its main instructions, in order. Use it to keep sections in version control and publish them from CI, so the agent's guidance changes through the same review process as your code.
The main instructions themselves are the agent's systemPrompt, set through the Agents API.
Authenticate with a bearer API key; see API keys. Reading sections needs no particular capability. PUT, POST, PATCH, and DELETE require the manageAgents capability. Full request/response schemas live in the OpenAPI reference.
Endpoints#
| Endpoint | Purpose |
|---|---|
GET /v1/agents/{agentId}/sections | List the agent's sections in prompt order |
PUT /v1/agents/{agentId}/sections | Replace the full list of sections, matched by name |
POST /v1/agents/{agentId}/sections | Add one section at the end. Answers 201 with the section |
PATCH /v1/agents/{agentId}/sections/{sectionId} | Rename a section or change its content. Answers 200 with the section |
DELETE /v1/agents/{agentId}/sections/{sectionId} | Delete a section. Answers 204 |
Sections are managed through the API on Anthropic, OpenAI Responses, Gemini, and Claude Agent SDK agents (Claude Agent SDK agents only when your organization has API access to them). Every endpoint answers 404 with error: "agent_not_found" for an agent that doesn't exist in your organization or isn't one of these types, and the {sectionId} endpoints answer 404 with error: "section_not_found" for a section that doesn't belong to that agent. A write with a key that lacks manageAgents answers 403.
A section#
{
"id": "6f1c2a9e-3b7d-4c55-9a0e-1d2f3a4b5c6d",
"name": "Tone",
"content": "Answer in short, plain sentences. Avoid jargon.",
"position": 0,
"createdAt": "2026-10-01T09:30:00.000Z",
"updatedAt": "2026-10-13T14:05:12.000Z"
}| Field | Meaning |
|---|---|
id | The section's id, used by PATCH and DELETE |
name | The section's title, 1 to 200 characters. Section names should be unique within the agent (see Limits and errors) |
content | The guidance itself, 1 to 100,000 characters |
position | Read-only. The section's place in the prompt, starting at 0 (see Order) |
createdAt, updatedAt | When the section was created and last changed |
GET returns the list in the order the agent reads it:
curl -s https://api.runbear.io/v1/agents/$AGENT_ID/sections \
-H "Authorization: Bearer $RUNBEAR_API_KEY"{
"sections": [
{ "id": "6f1c…", "name": "Tone", "content": "Answer in short, plain sentences.", "position": 0, "createdAt": "…", "updatedAt": "…" },
{ "id": "a03e…", "name": "When to escalate", "content": "Hand off to a human when…", "position": 1, "createdAt": "…", "updatedAt": "…" }
]
}Replacing all sections#
PUT takes the complete list of sections the agent should have and makes the agent match it in one step:
curl -s -X PUT https://api.runbear.io/v1/agents/$AGENT_ID/sections \
-H "Authorization: Bearer $RUNBEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sections": [
{ "name": "Tone", "content": "Answer in short, plain sentences." },
{ "name": "When to escalate", "content": "Hand off to a human when…" }
]
}'It answers with the resulting list, in the same shape as GET. Sections are matched to the agent's existing ones by name:
- A section whose name already exists is updated in place and keeps its
id. If neither its content nor its position changed, it is left untouched. - A section with a new name is created.
- An existing section whose name is not in the payload is deleted. Sending an empty list deletes every section.
- The order of the array becomes the order the agent reads the sections in.
A PUT that changes nothing changes nothing: no section is rewritten and no new configuration version is recorded. Only the sections that actually changed show up in the agent's history, so running the same PUT from every CI build is safe.
Because matching is by name, renaming a section through PUT deletes the old section and creates a new one with a new id. Use PATCH to rename a section and keep its id.
Adding, editing, and deleting one section#
POST adds one section at the end of the list:
curl -s -X POST https://api.runbear.io/v1/agents/$AGENT_ID/sections \
-H "Authorization: Bearer $RUNBEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Product vocabulary", "content": "\"Workspace\" means a Slack workspace." }'PATCH changes a section's name, its content, or both; send at least one, and no other fields. It does not move the section. To change the order, send the full list with PUT.
curl -s -X PATCH https://api.runbear.io/v1/agents/$AGENT_ID/sections/$SECTION_ID \
-H "Authorization: Bearer $RUNBEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "Answer in two sentences or fewer." }'DELETE removes one section; the others keep their order.
Order#
Sections are read in the order set by the last PUT, and position reports each section's index in that order. Sections added later, by POST or in the dashboard, go to the end, oldest first. The dashboard has no way to reorder sections; use PUT.
Limits and errors#
| Limit | Value |
|---|---|
Section name | 1 to 200 characters |
Section content | 1 to 100,000 characters |
Sections in one PUT | At most 100 |
| Request body | At most 10 MiB |
A request over the name, content, or section-count limits answers 400; a body over 10 MiB answers 413. Either way nothing changes.
| Status | error | When |
|---|---|---|
400 | duplicate_section_names | A PUT lists the same name more than once. The body's names field lists them, and nothing is changed |
400 | bad_request | The body failed validation: a value over one of the limits above, an empty name or content, or a PATCH with no fields or an unknown field. The body carries code: "FST_ERR_VALIDATION" and a message naming the field |
403 | forbidden | The API key lacks the manageAgents capability on a write (code: "forbidden_by_key_role"), or the agent is outside the key's allowlist (code: "forbidden_by_agent_allowlist") |
404 | agent_not_found, section_not_found | See Endpoints |
409 | existing_duplicate_section_names | A PUT on an agent that already has more than one section with the same name. The body's names field lists them |
409 | section_name_taken | A POST, or a PATCH that renames a section, uses a name another section on the agent already has |
The 100,000-character limit applies to every section in a PUT, including one that was saved longer in the dashboard: shorten it before syncing it through the API.
PUT matches sections by name, so it refuses to run while the agent has duplicate names. Rename or delete the extra sections, in the dashboard or with PATCH and DELETE, then retry.
Most errors use the shape { "error": "<code>", "message": "..." }; see Errors and limits.
Syncing sections from a repository#
Keep one Markdown file per section, for example agent-sections/01-tone.md, agent-sections/02-escalation.md. This GitHub Actions workflow publishes them on every push to main: the file's name, without its numeric prefix and extension, becomes the section name, and the file order becomes the prompt order. Store the API key and agent id as repository secrets.
name: Sync agent sections
on:
push:
branches: [main]
paths: ["agent-sections/**"]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build payload
run: |
for f in agent-sections/*.md; do
name=$(basename "$f" .md | sed -E 's/^[0-9]+-//')
jq -n --arg name "$name" --rawfile content "$f" \
'{name: $name, content: $content}'
done | jq -s '{sections: .}' > payload.json
- name: Replace sections
env:
RUNBEAR_API_KEY: ${{ secrets.RUNBEAR_API_KEY }}
AGENT_ID: ${{ secrets.RUNBEAR_AGENT_ID }}
run: |
curl -sS --fail-with-body -X PUT \
"https://api.runbear.io/v1/agents/$AGENT_ID/sections" \
-H "Authorization: Bearer $RUNBEAR_API_KEY" \
-H "Content-Type: application/json" \
--data @payload.jsonThe shell sorts agent-sections/*.md alphabetically, so the numeric prefixes control the order. Remember that PUT deletes any section not in the payload: once you sync from a repository, add and edit sections there rather than in the dashboard.
Related#
- Instructions - main instructions and sections in the dashboard
- Agents API - create and configure agents, including the main instructions
- API keys - create a key with the
manageAgentscapability - Errors and limits - error shapes and rate limits