> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sempera.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Scenarios

> An agent's situations in its draft (simple, complex, authentication): create, archive, restore, copy, version history; and the test scenarios list.

A scenario is one situation an agent knows how to handle: when it applies, what to do, and when the agent may move on. "The caller wants to move an appointment; find the booking, offer two new times; keep going until the new time is confirmed." A scenario is a block inside the agent's own words (the "Anything else" part of its instructions), so a scenario is part of the draft, compiles into the agent when it is published and has no store of its own.

These are `/v2` compatibility routes ([API overview](https://docs.sempera.org/api-overview.md)). `{agent_id}` is the Sempera agent id and `{id}` a scenario id. A scenario keeps its id across versions; a copy in another agent has its own. Reads need `agents:read`. Writes change the agent's working draft, so they need `agents:write` and the `operator` or `owner` role, and nothing reaches callers until the draft is published ([Agents](https://docs.sempera.org/agents.md)).

| Route | Scope | Notes |
| - | - | - |
| `GET /v2/agents/{agent_id}/scenarios` | `agents:read` | `{"agent_id", "revision", "current", "archived"}`: the scenarios in the draft, and the ones taken out of it |
| `POST /v2/agents/{agent_id}/scenarios` | `agents:write` | Add one to the draft. `201` |
| `GET /v2/agents/{agent_id}/scenarios/{id}` | `agents:read` | One scenario, current or archived |
| `POST /v2/agents/{agent_id}/scenarios/{id}` | `agents:write` | Replace one current scenario with the fields below plus `expect_revision`, the draft `revision` as last read. A renamed scenario answers with its new id. `409` when the draft changed since that read or the new name is taken |
| `POST /v2/agents/{agent_id}/scenarios/{id}/archive` | `agents:write` | Take it out of the draft and keep it, restorable. It is not part of the agent once published |
| `POST /v2/agents/{agent_id}/scenarios/{id}/restore` | `agents:write` | Put an archived scenario back into the draft |
| `DELETE /v2/agents/{agent_id}/scenarios/{id}` | `agents:write` | Remove it for good, from the draft or from the archive. Answers the scenario with `"deleted": true` |
| `POST /v2/agents/{agent_id}/scenarios/{id}/copy` | `agents:write` | `{"agent_id": "<the other agent>"}`. Adds a copy to that agent's draft. `201` |
| `GET /v2/scenarios` | `agents:read` | Every readable agent's current scenarios: `{"scenarios", "agents"}`, each scenario with its `agent_name`, and `agents` every agent the credential can read (the choices for a copy). `agent_id` narrows `scenarios` to one agent |
| `GET /v2/agents/{agent_id}/scenarios/{id}/history` | `agents:read` | One scenario per published version |
| `GET /v2/agents/{agent_id}/scenarios/agent/history` | `agents:read` | The agent's own words as a whole per published version |

## Pathway folders

`GET /v2/scenarios` also returns `organization`, keyed by readable agent id. Each value has `revision`, `folders` (`id`, `name`), `placements` (pathway id to folder id or null), and `order` (saved pathway ids).

`POST /v2/agents/{agent_id}/pathway-organization` needs `agents:write` and the same operator/owner capability, workspace and agent checks as pathway edits. Send `expect_revision` from that agent's organization value and one action:

* `{"action":"create_folder","name":"Bookings","expect_revision":"..."}`
* `{"action":"move","scenario_id":"...","folder_id":"...","expect_revision":"..."}`. A null folder moves to the root. Both the pathway and folder must belong to this agent.
* `{"action":"reorder","order":["..."],"expect_revision":"..."}`. List every current pathway exactly once.

The response is the saved organization value. Stale revisions and duplicate names are `409`; foreign or missing resources are `404`; invalid actions are `400`. Folder changes persist immediately and are audited, but do not change runtime content or publish an agent. Folder names are single lines, 1 to 120 characters, unique per agent ignoring case, with at most 100 folders. No provider request is made.

### Create a pathway

```http theme={null}
POST /v2/agents/northwind-barbers/scenarios
{"name": "Reschedule a booking", "type": "complex",
 "when": "the caller wants to move an appointment",
 "until": "the new time is confirmed",
 "steps": ["find the booking", "offer two new times"]}
```

| Field | Rule |
| - | - |
| `name` | Required, up to 120 characters |
| `when` | Required: when the scenario applies |
| `until` | Required: the point at which the agent may move on |
| `type` | `simple` (default), `complex` or `authentication` |
| `steps` | 1 to 12 lines. Needed by `complex`, allowed by `authentication`, refused by `simple` |
| `verification` | The check that must pass before the agent goes on. Needed by `authentication`, refused by `simple` and `complex` |

`when`, `until`, each step and `verification` are single lines of up to 500 characters and may not begin with `Situation:`, `When:`, `Keep going until:`, `Only after:` or `Step:`. Any other field is refused. The type is read back from the shape, never stored: a scenario with a `verification` is `authentication`, one with steps is `complex`, and one with neither is `simple`.

A scenario reads `id`, `agent_id`, `name`, `named`, `when`, `until`, `verification`, `steps`, `text` (the block as it sits in the instructions), `type`, `type_label`, `state` (`current` or `archived`), `archived_at` and `archived_by`. An agent has at most 50 current scenarios, and a name is unique among its current and archived ones, ignoring case.

## History

`.../history` answers `{"versions", "next_cursor", "environments"}`. `versions` is newest first; each entry has `id`, `name` (`Version 4`), `version_number`, `created_at`, `author`, `added` and `removed` (lines changed against the version before) and `node`, the scenario as that version had it, or null once it was taken out. `environments` names the version the staging and production environments run, with the same `node`. A version whose specs were not kept cannot be read and is left out. `next_cursor` is always null.

## Refusals

Answers use the compatibility envelope `{"data": ..., "errors": null}`; a refusal about the thing named is `{"data": null, "errors": [{"error", "message"}]}`. A missing credential, scope or role gets the standard error envelope ([Errors and limits](https://docs.sempera.org/errors-and-limits.md)).

A stale pathway save adds `reason: stale_scenario` and `revision` to the first `CONFLICT` error. Nothing is written or audited as a successful save. Ask the owner before retrying their held fields with that revision; a further save by someone else is refused again. To discard local edits, read the scenario and revision together from the agent's scenario list, without writing. A duplicate name or other conflict does not carry this reason or revision and must not be treated as permission to overwrite. A missing or foreign pathway remains a `404` and discloses no revision.

| Status | `error` | When |
| - | - | - |
| `400` | `BAD_REQUEST` | A field breaks a rule above, or the copy names the agent itself |
| `404` | `NOT_FOUND` | No such agent (or one the credential cannot reach), or no such scenario |
| `409` | `CONFLICT` | The name is taken, the agent is at its 50, the scenario is already archived (or, for a restore, not archived), or the draft changed while the write was made and it should be repeated |

## Test scenarios

Test scenarios are a separate thing: scripted caller cases the test battery plays against an agent ([Tests and evals](https://docs.sempera.org/tests-and-evals.md)). `GET /v1/agent-testing/scenarios` (`agents:read`) lists them with `agent_id` (one agent, default every readable agent), `category` and `enabled` (`true` or `false`, anything else is `400 validation_failed`) as filters, in the compatibility envelope. Each row carries `id`, `name`, `tester_persona_prompt`, `max_turns`, `start_node_id`, `request_data`, `tags`, `created_at`, `updated_at` and `agent_id`; the remaining fields are fixed. `GET /v1/agent-testing/scenarios/{id}/eval-agents` (`agents:read`) lists the judges that score a test scenario's calls: this workspace's enabled evals that apply to the scenario's agent, in name order, each weighted `1` and aimed at the pass level (`target_level_keys: ["P"]`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.