Experimental
Interact binds the complete process name from the path to the first Attach frame.
/v1/processes/{process}/interact Connection and access
API connection and authentication guidance
{endpoint}
endpoint: The sandbox API base URL from Sandbox.core.endpoint.uri; preserve its path prefix when appending /v1 routes. HTTP endpoints require a scoped endpoint bearer; direct Unix sockets use socket access control.
Use one of these alternatives. Requirements within an alternative apply together.
sandboxBearersandboxWebSocketBearer
WebSocket session
Subprotocol: sandboxes.v1
Use exactly one sandbox-scoped Authorization bearer credential or, when endpoint credentialTransports advertises webSocketSubprotocol, offer sandboxes.bearer.v1. followed by canonical unpadded base64url of that credential alongside sandboxes.v1. The decoded token is limited to 4096 bytes. The server echoes only sandboxes.v1; mixed or duplicate credentials, query credentials and cookie-only authentication are refused.
Open a WSS endpoint using its scoped credential. Browsers may send cookies; the server ignores them as authority and permits cross-origin explicit bearer authentication. Browser WebSocket errors do not expose pre-upgrade HTTP status or bodies; only post-upgrade Error frames are typed. No reconnect or input replay is automatic.
Acquire a fresh scoped credential, open a new connection, and send attach with attach.resumeFrom set to the last received chunk.streamSequence. Resume replays output only; never replay stdin or process creation.
The last text frame before a close carries the one error body, because a close reason holds at most 123 bytes.
Client frames
Schema:
InteractRequest
Server frames
Schema:
ProcessOutput
Error frames
Schema:
Error
Handshake, resume fields, and close codes
{
"authentication": "Use exactly one sandbox-scoped Authorization bearer credential or, when endpoint credentialTransports advertises webSocketSubprotocol, offer sandboxes.bearer.v1. followed by canonical unpadded base64url of that credential alongside sandboxes.v1. The decoded token is limited to 4096 bytes. The server echoes only sandboxes.v1; mixed or duplicate credentials, query credentials and cookie-only authentication are refused.",
"bearerSubprotocolPrefix": "sandboxes.bearer.v1.",
"browser": "Open a WSS endpoint using its scoped credential. Browsers may send cookies; the server ignores them as authority and permits cross-origin explicit bearer authentication. Browser WebSocket errors do not expose pre-upgrade HTTP status or bodies; only post-upgrade Error frames are typed. No reconnect or input replay is automatic.",
"closeCode": {
"1000": "The service ended the stream, or the caller cancelled it.",
"1002": "The handshake negotiated no subprotocol.",
"1003": "A frame arrived as binary; every frame is text.",
"1007": "A frame was not the public JSON request message.",
"1008": "The service refused with a 4xx error, or the endpoint credential expired.",
"1009": "A frame exceeded the route’s frame limit.",
"1011": "The service failed with a code the front door maps to a 5xx."
},
"errorFrame": {
"$ref": "#/components/schemas/Error"
},
"firstRequestField": "attach",
"maxBearerTokenBytes": 4096,
"preUpgradeStatus": {
"400": "The request has an invalid subprotocol offer, mixed or malformed credentials, an oversized credential, or a query parameter.",
"401": "The scoped credential is missing, invalid or expired.",
"403": "The scoped credential does not grant this endpoint permission.",
"404": "The scoped credential does not address this sandbox endpoint."
},
"reconnect": "Acquire a fresh scoped credential, open a new connection, and send attach with attach.resumeFrom set to the last received chunk.streamSequence. Resume replays output only; never replay stdin or process creation.",
"requestFrame": {
"$ref": "#/components/schemas/InteractRequest"
},
"responseFrame": {
"$ref": "#/components/schemas/ProcessOutput"
},
"resumeRequestField": "attach.resumeFrom",
"resumeResponseField": "chunk.streamSequence",
"subprotocol": "sandboxes.v1",
"terminalFrame": "The last text frame before a close carries the one error body, because a close reason holds at most 123 bytes."
}Parameters
process
path
Required
Type:
string
All schema constraints and annotations
{
"type": "string"
}Request and responses
Response
101
No response content is declared.
Response
default
application/json
Schema:
Error
Schema example
{
"code": "notFound",
"details": [],
"message": "sandbox not found"
}Referenced schemas
#/components/schemas/InteractRequest
#/components/schemas/ProcessOutput
Complete operation contract
{
"description": "Interact binds the complete process name from the path to the first Attach frame.\nA conflicting name is INVALID_ARGUMENT before any attach.",
"operationId": "interact",
"parameters": [
{
"description": "The process id.",
"in": "path",
"name": "process",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"101": {
"description": "The connection becomes a sandboxes.v1 session: one InteractRequest per inbound text frame and one ProcessOutput per outbound one. Path parameters identify the target; the first attach frame must agree. Refusals after upgrade carry an error frame followed by a close code."
},
"default": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "The structured Error body identifies the failure with a stable code and optional typed details."
}
},
"security": [
{
"sandboxBearer": []
},
{
"sandboxWebSocketBearer": []
}
],
"servers": [
{
"url": "{endpoint}",
"variables": {
"endpoint": {
"default": "https://sandbox.invalid",
"description": "The sandbox API base URL from Sandbox.core.endpoint.uri; preserve its path prefix when appending /v1 routes. HTTP endpoints require a scoped endpoint bearer; direct Unix sockets use socket access control."
}
}
}
],
"summary": "Interact binds the complete process name from the path to the first Attach frame.",
"tags": [
"Processes"
],
"x-sbx-authenticated-only": false,
"x-sbx-conditional-permissions": [],
"x-sbx-plane": "data",
"x-sbx-request-schema": {
"$ref": "#/components/schemas/InteractRequest"
},
"x-sbx-required-permissions": [
"sandboxesExec"
],
"x-sbx-response-schema": {
"$ref": "#/components/schemas/ProcessOutput"
},
"x-sbx-serving-surface": "sandboxEndpoint",
"x-websocket": {
"authentication": "Use exactly one sandbox-scoped Authorization bearer credential or, when endpoint credentialTransports advertises webSocketSubprotocol, offer sandboxes.bearer.v1. followed by canonical unpadded base64url of that credential alongside sandboxes.v1. The decoded token is limited to 4096 bytes. The server echoes only sandboxes.v1; mixed or duplicate credentials, query credentials and cookie-only authentication are refused.",
"bearerSubprotocolPrefix": "sandboxes.bearer.v1.",
"browser": "Open a WSS endpoint using its scoped credential. Browsers may send cookies; the server ignores them as authority and permits cross-origin explicit bearer authentication. Browser WebSocket errors do not expose pre-upgrade HTTP status or bodies; only post-upgrade Error frames are typed. No reconnect or input replay is automatic.",
"closeCode": {
"1000": "The service ended the stream, or the caller cancelled it.",
"1002": "The handshake negotiated no subprotocol.",
"1003": "A frame arrived as binary; every frame is text.",
"1007": "A frame was not the public JSON request message.",
"1008": "The service refused with a 4xx error, or the endpoint credential expired.",
"1009": "A frame exceeded the route’s frame limit.",
"1011": "The service failed with a code the front door maps to a 5xx."
},
"errorFrame": {
"$ref": "#/components/schemas/Error"
},
"firstRequestField": "attach",
"maxBearerTokenBytes": 4096,
"preUpgradeStatus": {
"400": "The request has an invalid subprotocol offer, mixed or malformed credentials, an oversized credential, or a query parameter.",
"401": "The scoped credential is missing, invalid or expired.",
"403": "The scoped credential does not grant this endpoint permission.",
"404": "The scoped credential does not address this sandbox endpoint."
},
"reconnect": "Acquire a fresh scoped credential, open a new connection, and send attach with attach.resumeFrom set to the last received chunk.streamSequence. Resume replays output only; never replay stdin or process creation.",
"requestFrame": {
"$ref": "#/components/schemas/InteractRequest"
},
"responseFrame": {
"$ref": "#/components/schemas/ProcessOutput"
},
"resumeRequestField": "attach.resumeFrom",
"resumeResponseField": "chunk.streamSequence",
"subprotocol": "sandboxes.v1",
"terminalFrame": "The last text frame before a close carries the one error body, because a close reason holds at most 123 bytes."
}
}