API reference
Agents API
Run a coding agent (Claude Code, Codex, or Pi) inside a running machine: prompt it, follow its events, steer or interrupt a running turn, and resume conversations.
- Prompt an agent:
POST /v1/machines/{machine_id}/agents/prompt - Follow an agent's events:
GET /v1/machines/{machine_id}/agents/events - List agent conversations:
GET /v1/machines/{machine_id}/agents/conversations - Steer a running agent:
POST /v1/machines/{machine_id}/agents/steer - Interrupt a running agent:
POST /v1/machines/{machine_id}/agents/interrupt - List agent models:
GET /v1/provider-models
Prompt an agent
POST /v1/machines/{machine_id}/agents/prompt
Starts a turn of a coding agent in the machine, in a new conversation or one you resume. The agent's provider keys are the machine's environment variables, so a machine created without an environment gives it none. Follow the turn with GET /v1/machines/{machine_id}/agents/events.
- API key:
Authorization: Bearer vmy_…with presetuse_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie and thex-csrf-tokenheader. - Who: Owner, Admin, or Operator.
- Idempotency: send a unique
Idempotency-Key; replaying the same key and body returns the same operation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
machine_id | path | string (uuid) | Yes | |
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
Request body (application/json, AgentPromptRequest)
| Field | Type | Required | Description |
|---|---|---|---|
attachments | AgentAttachmentRequest[] | No | At most 16 files, 16 MiB together, written to the machine for the agent to read. |
conversation_id | string (uuid) | null | No | Continue this conversation; omit to start a new one. |
model | string | null | No | A model the agent accepts (see GET /v1/provider-models); the agent's default when omitted. Pi takes provider/model. |
provider | null | AgentProviderDto | No | Required for a new conversation; a conversation keeps its provider. |
reasoning_effort | null | ReasoningEffortDto | No | |
text | string | No | The prompt, at most 256 KiB. A prompt needs text or an attachment. |
Responses
| Status | Description | Body |
|---|---|---|
202 | The turn runs in the machine; follow events_url | AgentTurnDto |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
403 | forbidden, insufficient_scope, or organization_suspended | ProblemDetails |
404 | Unknown machine, or conversation_not_found | ProblemDetails |
409 | agent_turn_running, provider_mismatch, idempotency_conflict, machine_not_running, machine_not_created, or machine_deleted | ProblemDetails |
413 | The request body is too large (body_too_large). | ProblemDetails |
422 | Invalid request (invalid_request); field_errors names the fields. | ProblemDetails |
502 | guest_action_failed: the machine could not start the turn (the turn is failed) | ProblemDetails |
503 | agents_unavailable, or runtime_unavailable (retry with the same key) | ProblemDetails |
curl -X POST "$VMYARD_API_URL/v1/machines/$MACHINE_ID/agents/prompt" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'{
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"created_at": "2026-10-12T05:51:01Z",
"error_code": "string",
"events_url": "string",
"exit_code": 0,
"finished_at": "2026-10-12T05:51:01Z",
"interrupt_requested": false,
"machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"model": "string",
"provider": "claude",
"reasoning_effort": "minimal",
"resume": false,
"started_at": "2026-10-12T05:51:01Z",
"status": "starting",
"turn_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}Follow an agent's events
GET /v1/machines/{machine_id}/agents/events
JSON by cursor (with wait_seconds to long-poll), or server-sent events with Accept: text/event-stream. Each SSE event's id is the cursor after it: reconnect with Last-Event-ID to resume without repeats. The stream ends with an idle event once no turn is running.
- API key:
Authorization: Bearer vmy_…with presetuse_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie. - Who: Owner, Admin, or Operator.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
machine_id | path | string (uuid) | Yes | |
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
Last-Event-ID | header | integer | null | No | SSE: resume after this event's cursor (overrides cursor) |
conversation_id | query | string (uuid) | Yes | |
cursor | query | integer | No | The cursor of an earlier answer (or an SSE event's id); events after it are returned. Default 0, the conversation's first event. |
wait_seconds | query | integer | No | JSON only: wait up to this many seconds (0-30, default 0) for an event when none is ready. |
Responses
| Status | Description | Body |
|---|---|---|
200 | With Accept: text/event-stream: an SSE stream of agent events (id is the cursor after the event), ending with an idle event once no turn is running and every event was sent. Otherwise JSON: the events after cursor, waiting up to wait_seconds for one. | AgentEventsDto |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
403 | Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required). | ProblemDetails |
404 | Unknown machine, or conversation_not_found | ProblemDetails |
409 | machine_not_running, machine_not_created, or machine_deleted | ProblemDetails |
422 | Invalid request (invalid_request); field_errors names the fields. | ProblemDetails |
502 | The machine's host or a provider failed to answer. | ProblemDetails |
503 | Not available on this server. | ProblemDetails |
curl "$VMYARD_API_URL/v1/machines/$MACHINE_ID/agents/events?conversation_id=conversation_id" \
-H "Authorization: Bearer $VMYARD_API_KEY"{
"active": false,
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"cursor": 0,
"events": [
{
"code": "string",
"id": "string",
"input": "string",
"input_id": "string",
"is_error": false,
"kind": "prompt",
"message": "string",
"model": "string",
"name": "dev",
"outcome": "completed",
"output": "string",
"provider": "claude",
"reasoning_effort": "minimal",
"restarted": false,
"result": "string",
"resumed": false,
"seq": 0,
"session_id": "string",
"text": "string",
"time_ms": 0,
"turn_id": "string",
"type": "turn_started",
"usage": {
"cached_input_tokens": 0,
"cost_micro_usd": 0,
"input_tokens": 0,
"output_tokens": 0
}
}
],
"latest_turn": {
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"created_at": "2026-10-12T05:51:01Z",
"error_code": "string",
"events_url": "string",
"exit_code": 0,
"finished_at": "2026-10-12T05:51:01Z",
"interrupt_requested": false,
"machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"model": "string",
"provider": "claude",
"reasoning_effort": "minimal",
"resume": false,
"started_at": "2026-10-12T05:51:01Z",
"status": "starting",
"turn_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}
}List agent conversations
GET /v1/machines/{machine_id}/agents/conversations
- API key:
Authorization: Bearer vmy_…with presetuse_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie. - Who: Owner, Admin, or Operator.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
machine_id | path | string (uuid) | Yes | |
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
limit | query | integer | No | 1-100 (default 50). |
cursor | query | string (uuid) | No | The next_cursor of the previous page. |
Responses
| Status | Description | Body |
|---|---|---|
200 | — | AgentConversationListDto |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
403 | Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required). | ProblemDetails |
404 | Not found in this organization (resource_not_found). | ProblemDetails |
422 | Invalid request (invalid_request); field_errors names the fields. | ProblemDetails |
curl "$VMYARD_API_URL/v1/machines/$MACHINE_ID/agents/conversations" \
-H "Authorization: Bearer $VMYARD_API_KEY"{
"conversations": [
{
"created_at": "2026-10-12T05:51:01Z",
"events_url": "string",
"id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"latest_turn": {
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"created_at": "2026-10-12T05:51:01Z",
"error_code": "string",
"events_url": "string",
"exit_code": 0,
"finished_at": "2026-10-12T05:51:01Z",
"interrupt_requested": false,
"machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"model": "string",
"provider": "claude",
"reasoning_effort": "minimal",
"resume": false,
"started_at": "2026-10-12T05:51:01Z",
"status": "starting",
"turn_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
},
"machine_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"provider": "claude",
"status": "idle",
"turn_count": 0,
"updated_at": "2026-10-12T05:51:01Z"
}
],
"next_cursor": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}Steer a running agent
POST /v1/machines/{machine_id}/agents/steer
Adds instructions to the running turn. The agent confirms when it takes them with an input_accepted event carrying the answer's input_id.
- API key:
Authorization: Bearer vmy_…with presetuse_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie and thex-csrf-tokenheader. - Who: Owner, Admin, or Operator.
- Idempotency: send a unique
Idempotency-Key; replaying the same key and body returns the same operation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
machine_id | path | string (uuid) | Yes | |
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
Request body (application/json, AgentSteerRequest)
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string (uuid) | Yes | |
text | string | Yes | More instructions for the running turn, at most 256 KiB. |
Responses
| Status | Description | Body |
|---|---|---|
202 | Written to the running turn's inbox; the agent confirms it with an input_accepted event | AgentInputAccepted |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
403 | Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required). | ProblemDetails |
404 | Unknown machine, or conversation_not_found | ProblemDetails |
409 | no_active_turn, idempotency_conflict, or the machine is not running | ProblemDetails |
422 | Invalid request (invalid_request); field_errors names the fields. | ProblemDetails |
502 | The machine's host or a provider failed to answer. | ProblemDetails |
503 | Not available on this server. | ProblemDetails |
curl -X POST "$VMYARD_API_URL/v1/machines/$MACHINE_ID/agents/steer" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"text": "string"
}'{
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"input_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"kind": "steer",
"stopped": false,
"turn_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}Interrupt a running agent
POST /v1/machines/{machine_id}/agents/interrupt
Asks the running turn to stop; with force the agent is killed at once. The turn ends with outcome interrupted.
- API key:
Authorization: Bearer vmy_…with presetuse_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie and thex-csrf-tokenheader. - Who: Owner, Admin, or Operator.
- Idempotency: send a unique
Idempotency-Key; replaying the same key and body returns the same operation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
machine_id | path | string (uuid) | Yes | |
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
Request body (application/json, AgentInterruptRequest)
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string (uuid) | Yes | |
force | boolean | No | Also kill the runner and the agent at once instead of letting the agent stop on its own (it gets 10 s, then SIGTERM, then SIGKILL). |
Responses
| Status | Description | Body |
|---|---|---|
202 | The running turn is asked to stop (or, with force, killed); it ends with outcome interrupted | AgentInputAccepted |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
403 | Refused for this caller: role, key preset, CSRF token, or organization (forbidden, insufficient_scope, csrf_invalid, organization_mismatch, session_required). | ProblemDetails |
404 | Unknown machine, or conversation_not_found | ProblemDetails |
409 | no_active_turn, idempotency_conflict, or the machine is not running | ProblemDetails |
422 | Invalid request (invalid_request); field_errors names the fields. | ProblemDetails |
502 | The machine's host or a provider failed to answer. | ProblemDetails |
503 | Not available on this server. | ProblemDetails |
curl -X POST "$VMYARD_API_URL/v1/machines/$MACHINE_ID/agents/interrupt" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}'{
"conversation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"input_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
"kind": "steer",
"stopped": false,
"turn_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}List agent models
GET /v1/provider-models
- API key:
Authorization: Bearer vmy_…with presetread_only,use_existing,create_and_use,full_access. - Browser session: the
vmyard_sessioncookie. - Who: Any member.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Organization-ID | header | string (uuid) | No | Required with a browser session. Optional with an API key, which fixes the organization; when sent it must match. |
Responses
| Status | Description | Body |
|---|---|---|
200 | — | ProviderModelsDto |
401 | Not signed in, or the API key is malformed, expired, or revoked (unauthenticated, invalid_api_key). | ProblemDetails |
404 | Not found in this organization (resource_not_found). | ProblemDetails |
curl "$VMYARD_API_URL/v1/provider-models" \
-H "Authorization: Bearer $VMYARD_API_KEY"{
"providers": [
{
"models": [
{
"attachments": false,
"context_tokens": 0,
"id": "string",
"name": "dev",
"provider": "anthropic",
"reasoning": false,
"release_date": "string"
}
],
"provider": "claude",
"reasoning_efforts": [
"minimal"
]
}
],
"source": "live"
}