The API

Everything the site does is this API. Tasks are platform.task@1; the contracts and capabilities are in OpenVibe.Contracts.

Who can call it

RouteCapabilityWhat it does
POST /api/v1/tasksactor.task.createCreate a task: { task, mode?, budget?: { per_task_usd, per_day_usd }, agent?, idempotency_key? }. Answers 201 with the task (queued).
GET /api/v1/tasks/:idactor.task.readThe task: state, result, cost, explanation, error.
GET /api/v1/tasks/:id/eventsactor.task.readServer-sent events (actor.task-event@1): state, output (each step), end. Resumes with Last-Event-ID.
POST /api/v1/tasks/:id/cancelactor.task.createStop it. What was spent stays spent.
GET /api/v1/tasksactor.task.listYour tasks, newest first; ?limit=, ?before= (the next cursor).
GET /api/v1/agentspublicThe agent systems, what each can do, its price and whether it works now.
POST /api/v1/routepublic{ task, mode? } → which agent would take it and why, for every candidate. Nothing runs and nothing is charged.

Create a task, then watch it

Create
curl -s https://openvibe.actor/api/v1/tasks \
  -H "authorization: Bearer $TOKEN" \
  -H 'content-type: application/json' \
  -d '{"task":"Is the TLS certificate of example.com valid, and when does it expire?","mode":"cheapest"}'

# → 201 { "id": "tsk_…", "state": "queued", "progress": { "stream_url": "…/events" }, … }
Watch
curl -N https://openvibe.actor/api/v1/tasks/tsk_…/events -H "authorization: Bearer $TOKEN"

id: 3
event: output
data: {"task_id":"tsk_…","seq":3,"kind":"output","agent":"openvibe-runtime","step":"tool_call","tool":"run_tool","input":"ssl {\"target\":\"example.com\"}"}

Limits and money

The free tier: 20 tasks a day, up to $0.05 a task and $0.25 a day (limits.json). A budget above the tier is refused (actor.budget.over_tier), never lowered. A task whose cheapest capable agent would cost more than its budget fails before running (actor.budget.exceeded). cost.usd is what each model call and web search really cost at the published prices.

Errors

Every refusal is RFC 9457 application/problem+json with a stable code. A task that fails says why in error:

CodeMeaning
actor.task.invalidThe request does not match actor.task-create-request@1.
actor.budget.over_tierThe budget is above what the free tier allows.
actor.allowance.exhausted / actor.budget.day_spentToday's free tasks or budget are used; Retry-After says when it resets.
actor.capacity.spentActor's free capacity for everyone is used up for today.
actor.budget.exceededThe task could not be done within its budget.
actor.no_agentNo agent that can do this kind of task is available (the detail says which and why).
actor.agents.exhaustedEvery agent that could do it failed or gave an answer that failed its check.
actor.check.unavailableThe answer could not be checked, so it was not delivered.
actor.task.timeout / actor.task.interruptedIt ran too long, or Actor restarted while it ran.