A valid request URL is required to generate request examples{
"runId": "<string>",
"agentRunId": "<string>",
"deviceId": "<string>",
"goal": "<string>",
"executor": "phonebase",
"state": "queued",
"stepSeq": 123,
"maxSteps": 123,
"deadlineAt": "2023-11-07T05:31:56Z",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"workerFirstContactAt": "2023-11-07T05:31:56Z",
"initiator": {
"kind": "api_key",
"viaCopilot": true,
"userId": "<string>",
"apiKeyId": "<string>",
"onBehalfOf": {
"kind": "schedule",
"scheduleId": "<string>",
"userId": "<string>",
"apiKeyId": "<string>"
}
},
"scheduleId": "<string>",
"pausedAt": "2023-11-07T05:31:56Z",
"manualControlUntil": "2023-11-07T05:31:56Z",
"lastFrame": {
"frameId": "<string>",
"viewport": {
"width": 123,
"height": 123
}
},
"recovery": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"since": "2023-11-07T05:31:56Z",
"remainingMs": 4503599627370495,
"blockedReason": null
},
"reason": "worker_reported_failure",
"detail": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "payload_too_large",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Lift a stop and let the run carry on
Lifts either kind of stop, and only a person can lift either.
From needs_user_control: the agent asked a person to do the next step on the same screen, and this is the person saying it is done (the console’s Done). The worker cannot lift its own request. If recovery is non-null, this is instead an interrupted hosted run: send its exact id as expectedRecoveryId and currently own the device lease. Missing or stale recovery IDs leave the run unchanged. The call does not acquire a lease, clear unresolved actions, or grant extra steps. A successful continuation uses the saved time budget capped by the current lease and starts with a fresh observation.
From paused: a person put the agent on hold, and this lets it continue. The run continues from the CURRENT screen, so nothing already done is repeated and whatever a person did meanwhile is what it sees, and its frozen deadline slides forward by however long the hold lasted, capped by the lease’s own expiry.
A terminal run stays terminal, and a run in any other state comes back unchanged.
A valid request URL is required to generate request examples{
"runId": "<string>",
"agentRunId": "<string>",
"deviceId": "<string>",
"goal": "<string>",
"executor": "phonebase",
"state": "queued",
"stepSeq": 123,
"maxSteps": 123,
"deadlineAt": "2023-11-07T05:31:56Z",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"workerFirstContactAt": "2023-11-07T05:31:56Z",
"initiator": {
"kind": "api_key",
"viaCopilot": true,
"userId": "<string>",
"apiKeyId": "<string>",
"onBehalfOf": {
"kind": "schedule",
"scheduleId": "<string>",
"userId": "<string>",
"apiKeyId": "<string>"
}
},
"scheduleId": "<string>",
"pausedAt": "2023-11-07T05:31:56Z",
"manualControlUntil": "2023-11-07T05:31:56Z",
"lastFrame": {
"frameId": "<string>",
"viewport": {
"width": 123,
"height": 123
}
},
"recovery": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"since": "2023-11-07T05:31:56Z",
"remainingMs": 4503599627370495,
"blockedReason": null
},
"reason": "worker_reported_failure",
"detail": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "payload_too_large",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Authorizations
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.
Path Parameters
The stopped run. A runId: an agentRunId here answers 404.
Body
Required precondition for a recovery wait; ordinary pause/handoff requests may omit the body.
Response
The run as it is after the call.
The public projection of a run, and who started it. The run token is deliberately absent: it is returned once, when the run is started, and never again.
What the run was asked to accomplish, in the words it was started with.
Who drives this run: phonebase (we do) or self_hosted (your worker does).
phonebase, self_hosted Where the run is now. succeeded, failed and canceled are terminal. paused means a person put the agent on hold: the worker's channels are shut until Resume. It is not needs_user_control, which can mean the agent is asking for help or an interrupted hosted run is waiting for explicit continuation. A non-null recovery distinguishes the latter.
queued, running, needs_user_control, paused, succeeded, failed, canceled Metered steps issued so far. One step is one frame served.
The run's step ceiling.
Absolute wall clock deadline, or null when the stored deadline is not a renderable instant. FROZEN while the run is paused: the time the agent spends on hold is not charged to the run, and resuming slides this forward by however long the hold lasted. It is null during recovery waiting; recovery.remainingMs reports the saved time budget.
When a self-hosted worker first reached this run, or null when none ever did. On a self_hosted run you supply the worker, and one that stays queued with null here is waiting for it. A phonebase run is driven in process and never sets this.
WHO. The same shape answers three questions: who took an action (Receipt.actor), who is holding a device (Lease.holder), and who started a run (RunView.initiator). One shape on purpose, so the three can never disagree about what a given credential is called.
Show child attributes
Show child attributes
The schedule that started this run, or null when a person or a key did. Present and null rather than absent, so you can tell those apart from an older server that does not say.
When a person put the run on hold, or null when it is not on hold. Present and null rather than absent, so a consumer can tell "not on hold" from an older server that does not report it.
When the hold ends, or null when the run is not paused. This is the clock that runs while the run is on hold, not deadlineAt. Past it, a run nobody resumed is canceled with an explanation in detail; no new failure reason is used. The name is kept from when a hold was a person's manual control window; a person needs no window to act on the device now.
The last frame this run was served, or null when it has been served none. On a finished run this is the frame the model's report was written from, because finish_run ends the turn and nothing is captured after it, so a reader can put what the model said next to the screen it read that off. viewport is the frame's own pixel geometry, which is the coordinate basis it was captured in and not necessarily the device's current size.
Show child attributes
Show child attributes
An interrupted hosted run waiting for explicit continuation, or null. Older servers may omit this field. Progress and remaining budget are preserved; no action is replayed automatically.
Show child attributes
Show child attributes
Why the run ended, when it did not simply succeed.
worker_reported_failure, budget_exhausted, deadline_exceeded, canceled_by_caller, lease_lost, interrupted_by_restart Free text about how the run ended. A worker's own report, or, when the run hit its deadline, the control plane's explanation of which kind of timeout it was.