import json
import os
import struct
import urllib.request
# Set E2B_SANDBOX_ID and E2B_ENVD_ACCESS_TOKEN from a secured sandbox's
# create/connect response. This token is not your project API key.
# E2B_PROCESS_PID must identify a running process in that sandbox.
messages = [{"process": {"pid": int(os.environ["E2B_PROCESS_PID"])}}]
body = b""
for message in messages:
payload = json.dumps(message).encode("utf-8")
body += struct.pack(">BI", 0, len(payload)) + payload
request = urllib.request.Request(
"https://sandbox.e2b.app/process.Process/Connect",
data=body,
headers={
"Content-Type": "application/connect+json",
"Connect-Protocol-Version": "1",
"Connect-Timeout-Ms": "5000",
"E2b-Sandbox-Id": os.environ["E2B_SANDBOX_ID"],
"E2b-Sandbox-Port": "49983",
"X-Access-Token": os.environ["E2B_ENVD_ACCESS_TOKEN"],
},
method="POST",
)
with urllib.request.urlopen(request, timeout=10) as response:
data = response.read()
# HTTP 200 can still contain a terminal error. Decode each envelope.
offset = 0
while offset < len(data):
if len(data) - offset < 5:
raise ValueError("Truncated Connect envelope")
flags, length = struct.unpack_from(">BI", data, offset)
offset += 5
if length > len(data) - offset:
raise ValueError("Truncated Connect message")
message = json.loads(data[offset:offset + length])
offset += length
if flags & 2:
if message.get("error"):
raise RuntimeError(message["error"])
break
print(message)
curl --request POST \
--url https://sandbox.e2b.app/process.Process/Connect \
--header 'Connect-Protocol-Version: <connect-protocol-version>' \
--header 'Content-Type: application/connect+json' \
--header 'E2b-Sandbox-Id: <e2b-sandbox-id>' \
--header 'E2b-Sandbox-Port: <e2b-sandbox-port>' \
--header 'X-Access-Token: <api-key>' \
--data '"<string>"'const options = {
method: 'POST',
headers: {
'Connect-Protocol-Version': '<connect-protocol-version>',
'E2b-Sandbox-Id': '<e2b-sandbox-id>',
'E2b-Sandbox-Port': '<e2b-sandbox-port>',
'X-Access-Token': '<api-key>',
'Content-Type': 'application/connect+json'
},
body: JSON.stringify('<string>')
};
fetch('https://sandbox.e2b.app/process.Process/Connect', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.e2b.app/process.Process/Connect",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode('<string>'),
CURLOPT_HTTPHEADER => [
"Connect-Protocol-Version: <connect-protocol-version>",
"Content-Type: application/connect+json",
"E2b-Sandbox-Id: <e2b-sandbox-id>",
"E2b-Sandbox-Port: <e2b-sandbox-port>",
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.e2b.app/process.Process/Connect"
payload := strings.NewReader("\"<string>\"")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Connect-Protocol-Version", "<connect-protocol-version>")
req.Header.Add("E2b-Sandbox-Id", "<e2b-sandbox-id>")
req.Header.Add("E2b-Sandbox-Port", "<e2b-sandbox-port>")
req.Header.Add("X-Access-Token", "<api-key>")
req.Header.Add("Content-Type", "application/connect+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.e2b.app/process.Process/Connect")
.header("Connect-Protocol-Version", "<connect-protocol-version>")
.header("E2b-Sandbox-Id", "<e2b-sandbox-id>")
.header("E2b-Sandbox-Port", "<e2b-sandbox-port>")
.header("X-Access-Token", "<api-key>")
.header("Content-Type", "application/connect+json")
.body("\"<string>\"")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.e2b.app/process.Process/Connect")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Connect-Protocol-Version"] = '<connect-protocol-version>'
request["E2b-Sandbox-Id"] = '<e2b-sandbox-id>'
request["E2b-Sandbox-Port"] = '<e2b-sandbox-port>'
request["X-Access-Token"] = '<api-key>'
request["Content-Type"] = 'application/connect+json'
request.body = "\"<string>\""
response = http.request(request)
puts response.read_body"<string>""missing header\n"{
"code": 401,
"message": "unauthorized access, please provide a valid access token or method signing if supported"
}"Unexpected error when routing request: invalid sandbox port\n"{
"sandboxId": "<string>",
"message": "<string>",
"code": 123
}Connect
Server-streaming RPC. Use the Connect protocol with streaming support.
import json
import os
import struct
import urllib.request
# Set E2B_SANDBOX_ID and E2B_ENVD_ACCESS_TOKEN from a secured sandbox's
# create/connect response. This token is not your project API key.
# E2B_PROCESS_PID must identify a running process in that sandbox.
messages = [{"process": {"pid": int(os.environ["E2B_PROCESS_PID"])}}]
body = b""
for message in messages:
payload = json.dumps(message).encode("utf-8")
body += struct.pack(">BI", 0, len(payload)) + payload
request = urllib.request.Request(
"https://sandbox.e2b.app/process.Process/Connect",
data=body,
headers={
"Content-Type": "application/connect+json",
"Connect-Protocol-Version": "1",
"Connect-Timeout-Ms": "5000",
"E2b-Sandbox-Id": os.environ["E2B_SANDBOX_ID"],
"E2b-Sandbox-Port": "49983",
"X-Access-Token": os.environ["E2B_ENVD_ACCESS_TOKEN"],
},
method="POST",
)
with urllib.request.urlopen(request, timeout=10) as response:
data = response.read()
# HTTP 200 can still contain a terminal error. Decode each envelope.
offset = 0
while offset < len(data):
if len(data) - offset < 5:
raise ValueError("Truncated Connect envelope")
flags, length = struct.unpack_from(">BI", data, offset)
offset += 5
if length > len(data) - offset:
raise ValueError("Truncated Connect message")
message = json.loads(data[offset:offset + length])
offset += length
if flags & 2:
if message.get("error"):
raise RuntimeError(message["error"])
break
print(message)
curl --request POST \
--url https://sandbox.e2b.app/process.Process/Connect \
--header 'Connect-Protocol-Version: <connect-protocol-version>' \
--header 'Content-Type: application/connect+json' \
--header 'E2b-Sandbox-Id: <e2b-sandbox-id>' \
--header 'E2b-Sandbox-Port: <e2b-sandbox-port>' \
--header 'X-Access-Token: <api-key>' \
--data '"<string>"'const options = {
method: 'POST',
headers: {
'Connect-Protocol-Version': '<connect-protocol-version>',
'E2b-Sandbox-Id': '<e2b-sandbox-id>',
'E2b-Sandbox-Port': '<e2b-sandbox-port>',
'X-Access-Token': '<api-key>',
'Content-Type': 'application/connect+json'
},
body: JSON.stringify('<string>')
};
fetch('https://sandbox.e2b.app/process.Process/Connect', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.e2b.app/process.Process/Connect",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode('<string>'),
CURLOPT_HTTPHEADER => [
"Connect-Protocol-Version: <connect-protocol-version>",
"Content-Type: application/connect+json",
"E2b-Sandbox-Id: <e2b-sandbox-id>",
"E2b-Sandbox-Port: <e2b-sandbox-port>",
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.e2b.app/process.Process/Connect"
payload := strings.NewReader("\"<string>\"")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Connect-Protocol-Version", "<connect-protocol-version>")
req.Header.Add("E2b-Sandbox-Id", "<e2b-sandbox-id>")
req.Header.Add("E2b-Sandbox-Port", "<e2b-sandbox-port>")
req.Header.Add("X-Access-Token", "<api-key>")
req.Header.Add("Content-Type", "application/connect+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.e2b.app/process.Process/Connect")
.header("Connect-Protocol-Version", "<connect-protocol-version>")
.header("E2b-Sandbox-Id", "<e2b-sandbox-id>")
.header("E2b-Sandbox-Port", "<e2b-sandbox-port>")
.header("X-Access-Token", "<api-key>")
.header("Content-Type", "application/connect+json")
.body("\"<string>\"")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.e2b.app/process.Process/Connect")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Connect-Protocol-Version"] = '<connect-protocol-version>'
request["E2b-Sandbox-Id"] = '<e2b-sandbox-id>'
request["E2b-Sandbox-Port"] = '<e2b-sandbox-port>'
request["X-Access-Token"] = '<api-key>'
request["Content-Type"] = 'application/connect+json'
request.body = "\"<string>\""
response = http.request(request)
puts response.read_body"<string>""missing header\n"{
"code": 401,
"message": "unauthorized access, please provide a valid access token or method signing if supported"
}"Unexpected error when routing request: invalid sandbox port\n"{
"sandboxId": "<string>",
"message": "<string>",
"code": 123
}Authorizations
Sandbox access token (envdAccessToken) for authenticating requests to a running sandbox. Returned by: POST /sandboxes (on create), POST /sandboxes/{sandboxID}/connect (on connect), POST /sandboxes/{sandboxID}/resume (on resume), and GET /sandboxes/{sandboxID} (for running or paused sandboxes).
Headers
1 Define the timeout, in ms
Identifier of the target sandbox. Routes the request to that sandbox's envd over the shared sandbox host.
Port envd listens on inside the sandbox (default 49983).
Body
Send Connect-framed bytes with Content-Type application/connect+json. Each uncompressed request frame begins with flags byte 0, then the JSON payload length as four big-endian bytes, then the UTF-8 JSON payload. The decoded payload follows #/components/schemas/process.ConnectRequest (x-connect-message-schema). Sending a bare JSON document does not encode a valid Connect request frame.
The body is of type file.
Response
Stream of ConnectResponse events Decoded terminal error example (the wire also includes the five-byte frame prefix): {"error":{"code":"not_found","message":"process with pid 2147483647 not found"}}. Connect-framed bytes, not an ordinary JSON document. Each frame has a one-byte flags field and a four-byte big-endian payload length. The decoded data payload follows x-connect-message-schema. The final frame has flags=2 and follows x-connect-end-stream-schema. RPC failures appear in its error object while the HTTP status remains 200. Authentication or routing failures before the stream can use the separate HTTP responses below.
The response is of type file.
Was this page helpful?