Scripts and skills as documents
Read, propose, apply and publish an agent's script and its skills from any harness, with base versions so nobody's edits are lost.
An agent's script and the skills it runs are documents. The API gives a harness the four primitives it needs to work on them, and no loop of its own: your Claude, Cursor or pipeline decides what to call next.
| Step | Call | Writes |
|---|---|---|
| Read | GET /v1/agents/{id}/script?include=context, GET /v1/skills/{slug} | nothing |
| Check | POST …/script/propose, POST /v1/skills/{slug}/propose | nothing; returns a diff and lint problems |
| Apply | PUT …/script, PUT /v1/skills/{slug} with baseVersion | the document; 409 stale if it moved |
| Ship | POST /v1/agents/{id}/publish | a new revision visitors get |
The script document
script is the agent's authored text: instructions, persona, behavior, welcomeMessage, chatPlaceholder, tone, and skills, the slugs it runs. On write, only the fields you send change.
include=context adds what an author needs before drafting: the agent's name, title and company, whether meetings are on, every skill the agent can resolve (the org's library over the built-ins), knowledge bases, forms, offers and tours by name, and the active script's prompts and modules, read-only here.
Base versions
Every read returns a version (the script's last-changed time, or a skill's integer version). An apply carries it back. If a colleague in the dashboard or another harness changed the document in between, the apply is refused with 409 stale and currentVersion; re-read, re-diff, apply again. A tour quietly losing a person's edits is worse than a refused call.
Lint
Propose and apply run the same small, deterministic lint:
- an empty document,
- the vocabulary laws in visitor-facing text (the words the product never uses for a tour or a hub),
- a body over 20,000 characters,
- a skill slug the agent cannot resolve,
- a script that promises to book a meeting when meetings are off for the agent (a warning).
Errors refuse an apply with 400 lint-failed and the problems; warnings come back with the write.
Skills
GET /v1/skills lists the org's library over the built-ins. A built-in the org has not touched reads as source: builtin, version 0; the first PUT against it forks it into the org (201), after which it has its own version. A slug nobody has is created the same way. Skill bodies are live: the agent runs the new text on its next turn, so propose first.
A run through a harness
GETthe script with context.- Draft the change.
POSTpropose; read the diff and the problems; fix and propose again.PUTapply with theversionfrom step 1.- Preview in the dashboard, then
POSTpublish.
Nothing on this page needs an operator to leave their harness, and every step returns something the harness can act on without a person reading prose. Reads need agents:read; apply and publish need agents:write.
Applying a script or skill and publishing an agent each take an Idempotency-Key header, so a harness can retry a write without publishing twice. Propose writes nothing and needs none. See Errors.
What your assistant can see
Conversations carry what a visitor asked. By default the API masks who they were, and reading them verbatim is a separate scope nobody gets by accident.
Tours as documents
Read a tour as an authoring document, propose an edit and see the diff and lint, apply it against a version, publish.