Skip to main content
POST
Error

Authorizations

Authorization
string
header
required

The control surface credential. Send Authorization: Bearer <token>.

Two kinds of token are accepted and they are told apart by shape, not by a separate header. A token beginning pbk_ is an org scoped API key, whose public half and secret half are generated together and of which only a hash of the secret is ever stored; anything else is treated as an OAuth 2.1 access token and verified against the authorization server's keys.

Both resolve to the same context: an org, a principal and a set of scopes. Nothing downstream branches on which channel you used, with one deliberate exception, key management, which requires a signed-in person so that a key can never mint another key.

Scopes are enforced when MCP tools are REGISTERED rather than when they are called, so a tool your credential cannot use is absent from tools/list rather than refused mid gesture.

Body

application/json

The device, the goal, and optional budget ceilings.

deviceId
string
required

The device to drive.

goal
string
required

What the run should accomplish, in plain language.

leaseId
string

Optional, and not compared: the run starts under the lease your ORGANISATION holds on that device, whoever inside it took that lease. Your organisation holding none is 409 lease_required; unlike a gesture, this route never takes one for you.

maxSteps
integer

Ceiling on metered steps. A value above the deployment's own limit is capped to that limit, not refused: the limit is deployment configuration rather than a published number, so it cannot be asked for exactly. Read the run's maxSteps for the effective ceiling. A value of the wrong type is refused.

Required range: x >= 1
deadlineMs
integer

Wall clock budget in milliseconds, at least 1000 (a smaller window would be born expired). Capped by the deployment's limit and by the lease's own expiry, whichever comes first.

Required range: x >= 1000
executor
enum<string>

Who drives the run. Optional: left out, it is self_hosted for an API key and phonebase for a signed-in person. Any other value is refused.

Available options:
phonebase,
self_hosted

Response

The run started.

runId
string
required

The run. Use it on every later call about this run.

agentRunId
string
required

The run's shareable id: what every receipt the run produces carries, and what a permalink is built on. GET /v1/runs/{runId} accepts it in place of the runId.

state
enum<string>
required

The run's state at the moment it was created.

Available options:
queued,
running,
needs_user_control,
paused,
succeeded,
failed,
canceled
maxSteps
integer
required

The EFFECTIVE step ceiling: your maxSteps, capped by the deployment's limit. Read this rather than assuming your ask was honoured; a request above the limit is accepted and capped, not refused.

deadlineAt
string
required

The effective wall-clock deadline, ISO 8601: your deadlineMs, capped by the deployment's limit and by the lease's own expiry, whichever comes first.

executor
enum<string>
required

Who drives the run, as decided: what you asked for, or the default for your credential. phonebase runs it for you; self_hosted means your own worker drives it.

Available options:
phonebase,
self_hosted
vrxBaseUrl
string

The run scoped device surface base url, present ONLY when executor is self_hosted. It CARRIES THE RUN TOKEN, so it is a credential: hand it to exactly one worker and to nothing else. It is returned here and never again.