Developers

An actor is an address. A run is a thread.

Everything the Studio does with an agent, another client can do through the same doors: start a run as a named actor, follow it as it happens, answer what it asks, stop it, and read the record afterwards. Every event is a record on the run’s thread, so what you can see is what happened, and what you can do is what your key allows.

Doors are listed by the version they arrive in. On an instance behind that version the door answers 404 and the SDK refuses in words. The documentation carries the full reference; this page is the map.

the doors

sincedoorwhat it does
v0.189POST /v1/work/loopstart a run: goal, max_turns, budget_usd, source_thread; a member key is enough
v0.189GET /v1/threads/{thread}/watchthe run as it happens, one event per record (server-sent events)
v0.190POST /v1/actors/{did}/runsstart a run as a named actor; the run records which definition it ran under
v0.190GET /v1/runs/{thread}the run as one row: state, turns, spent_usd, ceiling_usd, the open question if any
v0.190GET /v1/runs/{thread}/eventsthe run’s events, named by what they are (turn, tool_call, ask, outcome); reconnects by cursor
v0.190POST /v1/runs/{thread}/eventssay something to the run, answer what it asked, or stop it: {kind: message | decision | stop}
v0.190GET /v1/actors, /v1/actors/{did}/runsthe actors this key may see, and each one’s runs
v0.191POST /v1/actors/definedefine an actor bounded by what you may do yourself: the tools you may use, the kinds you may write

the SDK, in TypeScript and Python

npm i @syncropel/sdk · pip install syncropel. One error class carries the door’s status, code and message; the Python names are the same words in snake_case.

sinceTypeScriptPythonwhat
v0.190client.actors.list() / .get(did)client.actors.list() / .get(did)who can work here
v0.190client.actors.run(did, { goal, maxTurns, budgetUsd })client.actors.run(did, goal=..., max_turns=..., budget_usd=...)start a run; returns the run row
v0.190client.runs.get(thread) / .list()client.runs.get(thread) / .list()the run as one row
v0.190for await (const e of client.runs.events(thread))for e in client.runs.events(thread):follow it; the iterator reconnects on its own
v0.190client.runs.message(thread, text)client.runs.message(thread, text)steer it
v0.190client.runs.answer(thread, decisionId, choice)client.runs.answer(thread, decision_id, choice)answer what it asked
v0.190client.runs.stop(thread)client.runs.stop(thread)stop it; the outcome is recorded
v0.191client.actors.define({...}) / .retire(did)client.actors.define(...) / .retire(did)define and retire an actor

what a run is made of