Skip to main content
All endpoints live under /v0. Bodies are JSON. Errors use a {code, message, details} envelope.

Authentication

  • Client and admin routes use a bearer token: Authorization: Bearer <token>. Set it with --bearer-token / REBUNO_BEARER_TOKEN (required in server mode). The dev kernel disables auth.
  • Agent routes use HMAC. The agent sends Rebuno-Agent-Id and Rebuno-Signature: sha256=<HMAC-SHA256(secret, body)>, computed over the raw request body with the agent’s registered secret.
  • Agent routes that write also send Rebuno-Dispatch-Id and Rebuno-Dispatch-Attempt, copied from the webhook that delivered the run. A call from an attempt the kernel has already re-delivered gets 409 lease_superseded.
  • A few routes (fetching execution input and steps) take either one: bearer for clients, HMAC for the agent.
  • /v0/health, /v0/ready, and /metrics are unauthenticated.

Client API

Create an execution

POST /v0/executions · bearer
Returns 201 with the created execution. The kernel records execution.created and enqueues a dispatch.

Get an execution

GET /v0/executions/{id} · bearer or HMAC

List executions

GET /v0/executions?agent_id=&status=&cursor=&limit= · bearer Newest first. Keyset paging: pass the returned next_cursor back as cursor.

Get the event log

GET /v0/executions/{id}/events?after_seq=&limit= · bearer Returns an ordered array of events. limit defaults to 100, max 1000. Poll with after_seq set to the last event_seq you saw.

Stream live output

GET /v0/executions/{id}/stream · bearer Server-Sent Events carrying the deltas an agent publishes while a step is still running. Best-effort, never persisted, and separate from the event log. See Live streaming.

Cancel an execution

POST /v0/executions/{id}/cancel · bearer → 204 Records execution.cancelled, moves the execution to a terminal state, and stops further dispatch.

Agent API

The kernel dispatches a webhook carrying {execution_id, dispatch_id, dispatch_attempt, lease_timeout_seconds}. The agent acks 200 OK, then pulls what it needs and drives its effects. These routes are HMAC-verified, except the reads, which also take a bearer token.

Read execution input and steps

GET /v0/executions/{id} returns the original input and the current status. GET /v0/executions/{id}/steps?status=terminal returns the execution’s steps in one read, for inspection and auditing. status=terminal trims the list to succeeded, failed, and denied. GET /v0/executions/{id}/steps/{step_id} looks up one step, and returns 404 if it is not there.

Submit a step

POST /v0/executions/{id}/steps · HMAC · dispatch headers
kind is tool_call, llm_call, or local. The dispatch headers are required, and the kernel rejects the request if either is missing, or if they name a dispatch that is not this execution’s or an attempt that no longer owns it. The dispatch scopes the kernel’s occurrence counter. The kernel derives the step ID, runs the replay short-circuit and policy, and returns a decision. The step_id that comes back is what addresses the step’s complete and fail routes:

Report a step outcome

POST /v0/executions/{id}/steps/{step_id}/complete takes { "result": {...} } and records step.succeeded. POST /v0/executions/{id}/steps/{step_id}/fail takes { "error": {...} } and records step.failed.

Publish a stream delta

POST /v0/executions/{id}/steps/{step_id}/stream · HMAC → 204 Body { "seq": <int64>, "data": "<chunk>" }. Live output while a step runs, delivered best-effort. data is opaque to the kernel and capped per batch. See Live streaming.

Send a heartbeat

POST /v0/executions/{id}/heartbeat · HMAC → 204 Touches the dispatch lease so a long-running dispatch is not reclaimed as stalled.

Report execution outcome

POST /v0/executions/{id}/complete takes { "output": {...} }204. Records execution.completed. POST /v0/executions/{id}/fail takes { "error": "..." }204. Records execution.failed.

Admin API

Agents

POST /v0/agents · bearer registers or upserts an agent. Body { "id", "webhook_url", "secret", "lease_timeout_seconds?" }. Returns 201 and the stored agent. GET /v0/agents · bearer lists agents. GET /v0/agents/{id} · bearer fetches one. DELETE /v0/agents/{id} · bearer → 204. An agent reads { "id", "webhook_url", "policy_bundle?", "registered_at", "lease_timeout_seconds?" }. The secret is never returned.

Policy

POST /v0/policies/{agent_id} · bearer loads or replaces the agent’s bundle. Body { "bundle": "<raw YAML>" }204. See Policy. POST /v0/policies/{agent_id}/test · bearer evaluates a bundle without storing it. Body { "bundle?", "cases?", "execution_id?" }. Omit bundle to test the agent’s stored one; give cases to evaluate inputs, or execution_id to replay a past execution’s steps. Returns each case’s decision and a count of those that did not match. See Testing a bundle.

Approvals

GET /v0/approvals · bearer lists pending approvals. GET /v0/approvals/{id} · bearer fetches one. POST /v0/approvals/{id}/grant · bearer takes { "decided_by", "rationale?" }204. Resumes the execution, and the gated step proceeds. POST /v0/approvals/{id}/deny · bearer takes { "decided_by", "rationale?" }204. The resumed loop sees a policy error at that step. Both return 403 forbidden when the approval lists approvers and decided_by is not one of them. The kernel takes decided_by at face value, because the bearer token carries no identity. The check stops someone off the list from deciding. It cannot stop someone who types another person’s name into the field. See Approvals.

Operational endpoints

GET /v0/health is a liveness check, returning {"status":"ok"}. GET /v0/ready is a readiness check, returning 503 if a dependency check fails. GET /metrics serves Prometheus metrics.