2 · Register your agent
Register your ported agent on the platform — from the dashboard or the SDK — then publish it draft→active so checks can run it.
You've ported your agent and it runs locally. Now you register it on the platform as an umbrella agent — the platform object a connected repo maps to, and the thing that supplies the CI execution recipe (run command, timeout, tools, ledger, credential refs). Registration is two moves: create the agent (it starts as a draft), then publish it to active so checks can run it.
There's no config file to author. You register from the web dashboard or the SDK; both build the same payload and POST /api/agents. A thin dystopic agents push path exists too — it's covered at the end.
Registration returns a numeric agent id. That id is how every later step addresses this agent — suites, the gate, and the CI suite binding all hang off /api/agents/{id}. The gate and CI-suite binding are not set here; they're separate calls, described in create-suite.
Register from the dashboard
Open the platform at https://platform.pipelines.tech, go to Agents → New agent, and register a sandbox (repo-backed) agent: give it a name, point it at your entrypoint and source, and declare its tools_schema / ledger_schema. Save creates the agent as a draft; Publish flips it to active. This is the same object the SDK and API create — pick whichever surface fits your workflow.
Agents are sandbox (formerly "code") mode: the platform runs your repo in a sandbox.
Register from a script (SDK)
To register programmatically, use create_code_agent. It builds the payload, POSTs it to /api/agents, and returns the created agent row (including its numeric id):
from dystopic.odyssey import agents
row = agents.create_code_agent(
api_key="pk_live_...", # org key from Settings → API Keys
name="researcher",
entrypoint="run", # a single Python identifier
entrypoint_file="main.py", # defaults to main.py
source_dir="./agent_src",
tools_schema=my_tools_schema, # per-tool execution modes live here
ledger_schema=my_ledger_schema,
requirements=["httpx>=0.27", "trafilatura"],
python_version="3.12",
)
agent_id = row["id"]
print(f"created agent #{agent_id} '{row['name']}' ({row['status']})")A "code" agent ships as mode: "sandbox" on the wire — that normalization happens inside the payload builder, so you never spell sandbox yourself. create_code_agent returns a draft. To change an already-registered agent before publishing, call update_code_agent(agent_id, ...) (it PUTs /api/agents/{id}) — same keyword arguments as create.
Publishing draft→active is a POST /api/agents/{id}/publish, exposed as publish_agent(id) on the raw client:
from dystopic import Client
Client(api_key="pk_live_...").publish_agent(agent_id)create_code_agent / update_code_agent set the agent's execution recipe only. They do not touch the gate or the CI suite binding — those are the separate PUT /api/agents/{id}/gate and PUT /api/agents/{id}/ci-suite calls covered in create-suite.
If you'd rather build the payload yourself, the raw client mirrors the endpoints:
from dystopic import Client
client = Client(api_key="pk_live_...")
row = client.create_agent(payload) # POST /api/agents → draft
client.update_agent(agent_id, payload) # PUT /api/agents/{id}
client.publish_agent(agent_id) # POST /api/agents/{id}/publish → activeRaw API
The three endpoints, if you're not using the SDK at all:
| Call | Endpoint | Result |
|---|---|---|
| Create | POST /api/agents | Agent created as draft; response body includes the numeric id. |
| Update | PUT /api/agents/{id} | Replaces the agent's config (still draft until published). |
| Publish | POST /api/agents/{id}/publish | Flips draft → active so checks can run it. |
All three are under the API base https://api.pipelines.tech (see Setup for how your key resolves). The create body carries the agent's name, mode (sandbox), entrypoint/source, and optional tools_schema, ledger_schema, requirements, python_version, description, concurrency_cap, and run_timeout_s. The exhaustive field-by-field payload — every source shape and credential-ref grammar — lives in the register-agent reference. Each tools_schema entry carries the tool's whole behavioral surface — input/output schemas, its execution mode (Simulated / Executed / Live), ledger write policy, and human-approval gating — documented field-by-field in the tools reference.
Draft → active lifecycle
A freshly created agent is a draft: it has an id, but can't run checks until it's active. Publishing is the one-way flip:
Create — POST /api/agents (or create_code_agent) returns the agent as draft with its numeric id.
Iterate — PUT /api/agents/{id} (or update_code_agent) to adjust the config while still a draft. Re-publishing isn't needed to keep editing.
Publish — POST /api/agents/{id}/publish flips it to active. Now it can be bound to suites and run checks.
Secondary: push from a manifest
If you'd rather register from the CLI than call the API, dystopic agents push (aliased odyssey push) reads a minimal agent manifest — just the agent's name, mode, and entrypoint/source — and POSTs it to /api/agents. This is the one place a dystopic.yaml appears, and it holds only the agent block. Suites, scenarios, and the gate are never in this file; they're authored on the dashboard or via REST (see create-suite).
agents:
researcher:
mode: code # ships as "sandbox" on the wire
entrypoint: run
entrypoint_file: main.py
source:
dir: ./agent_srcdystopic agents push # POST /api/agents → draft; stamps the assigned id back into the file
dystopic agents publish # POST /api/agents/{id}/publish → activeOn create the platform returns a numeric id, and the CLI writes it back under the agent so a later push updates (PUT /api/agents/{id}) instead of creating a duplicate. push and publish need the [odyssey] extra — pip install 'dystopic[odyssey]' if you installed the bare CLI. The manifest is agent-registration only; it is not a suite, seed, or CI-boot surface.
Verify it registered
Confirm the agent exists and check its status:
dystopic agents list
dystopic agents show 4217Or open the agent on the dashboard at https://platform.pipelines.tech.
Next
Your agent is registered and active. Next, declare the world it runs against — the simulated tools and, if it's multi-agent, its topology.
1 · Port your agent
Wrap your existing agent as a sandbox/code agent, route its tool calls through the Odyssey proxy, and run it locally before you register it on the platform.
3 · Declare the world
Define the simulated environment your agent is tested against — the (optional) multi-agent topology and the (optional) ledger schema — and know when a single-agent system needs neither.