Share feedback
Answers are generated based on the documentation.

Experimental

Interact binds the complete process name from the path to the first Attach frame.

GET/v1/processes/{process}/interact
Interact binds the complete process name from the path to the first Attach frame. A conflicting name is INVALID_ARGUMENT before any attach.

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.

  • sandboxBearer
  • sandboxWebSocketBearer

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

The process id.

Type: string

All schema constraints and annotations
{
  "type": "string"
}

Request and responses

Response 101

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.

No response content is declared.

Response default

The structured Error body identifies the failure with a stable code and optional typed details.

application/json

Schema: Error

Schema example

{
  "code": "notFound",
  "details": [],
  "message": "sandbox not found"
}

Referenced schemas

#/components/schemas/Error

#/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."
  }
}