Yolocode E2B Sandboxes API Documentation

šŸš€ The Magic Hack to Win Any Hackathon

Add Claude Code - the world's most powerful coding agent - to your React app with ONE API call.

# 1. Create a sandbox (takes ~10 seconds) curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"name": "my-agent"}'
// 2. Plug the URL into Vercel AI SDK (literally one line) const { messages, input, handleSubmit } = useChat({ api: 'https://9999-{sandboxId}.e2b.app/chat', });

That's it. You now have a full coding agent in your app that can:

  • šŸŽØ Image generation pipelines - Execute 20-30 complex steps automatically
  • šŸŽ›ļø Self-updating admin panels - Agent modifies your UI in real-time
  • šŸ“„ Document processing - Upload 50+ random files, ask agent to convert them
  • šŸŽ¬ Video editing - Crop, edit, convert with ffmpeg using natural language
  • šŸ“Š Data analysis - Upload massive CSVs and get instant insights

Quick Start

Step 1: Get Your Agent URL

# Create sandbox and get the chat URL RESPONSE=$(curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"name": "hackathon-agent"}') CHAT_URL=$(echo $RESPONSE | jq -r '"https://" + .claudeHost + "/chat"') echo $CHAT_URL # Output: https://9999-abc123xyz.e2b.app/chat

Step 2: Integrate with React

import { useChat } from '@ai-sdk/react'; export default function MyApp() { const { messages, input, handleInputChange, handleSubmit } = useChat({ api: 'https://9999-abc123xyz.e2b.app/chat', // Your agent URL }); return ( <div> {messages.map(m => ( <div key={m.id}> {m.role}: {m.content} </div> ))} <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} /> <button type="submit">Send</button> </form> </div> ); }

Step 3: Test via cURL

# Send a message to your agent curl -X POST "https://9999-abc123xyz.e2b.app/chat" \ -H "Content-Type: application/json" \ -d '{ "messages": [{ "role": "user", "content": "Create a data visualization from sales.csv" }] }' \ --no-buffer

Real-World Examples

Image Processing Pipeline

// User uploads images, agent processes them automatically const { sendMessage } = useChat({ api: 'https://9999-xyz.e2b.app/chat', }); sendMessage({ content: 'Resize all images in /uploads to 800x600, convert to WebP, optimize for web', }); // Agent executes: find, convert, imagemagick, optimization - all automatically

Self-Updating Dashboard

// Agent modifies your React components live sendMessage({ content: 'Add a new chart showing revenue by region to Dashboard.tsx', }); // Agent reads your code, adds the component, installs dependencies if needed

Document Converter

// Process dozens of files with natural language sendMessage({ content: 'Convert all PDFs in /docs to markdown, extract tables to CSV', }); // Agent uses pdftotext, pandoc, custom scripts - figures it out

Overview

The Yolocode API provides cloud-based development environments (sandboxes) powered by E2B infrastructure, with:

  • Claude Code integration - Full coding agent with filesystem access
  • GitHub repository support - Auto-clone and setup your repos (tested with private repos)
  • WebSSH terminal - Direct shell access
  • Real-time code execution - Run commands, edit files, install packages

Repository Cloning

When you provide githubRepo and githubToken, the sandbox automatically:

  1. Clones the repository to /home/user/workspace
  2. Configures git with your GitHub credentials
  3. Installs dependencies (detects bun, npm, yarn, pnpm)
  4. Runs any setup defined in yolocode.yaml

Example startup log showing successful clone:

šŸ“‚ Cloning repository: makedora/dora-telegram āœ… Repository setup complete! Repository: /home/user/workspace (cloned from makedora/dora-telegram)

Authentication

GitHub Authentication (Required)

All API endpoints require GitHub OAuth authentication. Include your GitHub token in the Authorization header:

Authorization: Bearer YOUR_GITHUB_TOKEN

To obtain a GitHub token:

gh auth token

Claude Authentication (Optional - Use Your Own Credits)

Claude AI is always enabled in your sandbox. You have two options for how it's authenticated:

Option 1: No Claude Credentials (Uses yolocode API credits - Default)

If you don't provide claudeCredentials, the sandbox will use yolocode's Claude API key. This means:

  • āœ… Claude AI works immediately, no setup needed
  • āœ… Perfect for testing and hackathons
  • āš ļø Uses yolocode's API credits (limited free usage)
  • āš ļø May be rate-limited during high usage
# Create sandbox using yolocode's Claude API credits curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"name": "my-sandbox"}'

Option 2: Bring Your Own Claude Credentials (Unlimited usage on your account)

For unlimited usage without rate limits, bring your own Claude OAuth credentials. Here's how:

Step 1: Get Claude Account

  • Sign up at claude.ai
  • Get a Pro or Max subscription (required for API access)

Step 2: Extract Credentials from Claude Desktop/Web

The easiest way is to inspect your browser's network requests:

  1. Open claude.ai in Chrome/Firefox
  2. Open Developer Tools (F12) → Network tab
  3. Filter for "oauth" or "token"
  4. Make a request (start a chat)
  5. Look for requests to api.anthropic.com or console.anthropic.com
  6. Find the Authorization header - it contains your access token

Alternative: Use the yolocode mobile app

  • Download yolocode mobile app
  • Connect Claude account via OAuth
  • Credentials are stored and automatically used

Step 3: Pass Credentials to API

curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{ "name": "my-ai-sandbox", "claudeCredentials": { "accessToken": "your_access_token_here", "refreshToken": "your_refresh_token_here", "expiresAt": "2025-12-31T23:59:59Z" } }'

Note: Claude credentials format:

{ "accessToken": string, // OAuth access token "refreshToken": string, // OAuth refresh token "expiresAt": string, // ISO 8601 timestamp "account": { // Optional "id": string, "name": string }, "subscriptionInfo": { // Optional "hasAvailableMaxSubscription": boolean, "hasAvailableSubscription": boolean } }

Security Warning: Never commit credentials to git. Use environment variables or secure credential management.

Base URL

https://staging.yolocode.ai/api/e2b-sandboxes

API Endpoints

Create Sandbox (The Only Endpoint You Need)

POST /api/e2b-sandboxes

Creates a new E2B sandbox with optional GitHub repository setup and Claude credentials.

What happens during sandbox creation:

The API automatically sets up a fully configured development environment:

  1. Creates E2B sandbox with specified template and metadata
  2. Starts background startup script (/home/user/start.sh) for repository cloning and setup
  3. Configures Claude authentication:
    • OAuth mode: Writes .claude/.credentials.json and .claude.json files
    • JWT mode: Adds ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN to environment
    • No auth mode: Creates minimal .claude.json to skip onboarding
  4. Sets up workspace at /home/user/workspace and makes it the default directory
  5. Starts WebSSH server via systemd on port 8888 (/usr/local/bin/wssh)
  6. Starts Claude SSE server via systemd on port 9999 (/home/user/claude-sse-server.ts)
  7. Configures environment variables in both systemd services and .bashrc for terminal sessions

The sandbox is immediately ready to use - no additional API calls needed to start services.

Minimal Request

# Simplest possible request - just a name curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"name": "my-sandbox"}'

Request Body

All fields except name are optional. The API will automatically:

  • Generate an AI-based display name from taskDescription (or use name as fallback)
  • Add userId, userLogin, and displayName to metadata
  • Select appropriate template based on hosting (cloud or self-hosted)
  • Convert claudeCredentials to internal authentication format
{ "name": "my-dev-sandbox", "template": "yhviqh0tk1bo8z7uu1qf", "taskDescription": "Build a React application with TypeScript", "githubToken": "ghp_xxxxx", "githubRepo": "username/repository", "repositorySetup": { "environmentVariables": { "NODE_ENV": "development", "API_KEY": "secret123" } }, "claudeCredentials": { "accessToken": "claude_access_token", "refreshToken": "claude_refresh_token", "expiresAt": "2025-01-12T10:00:00Z", "account": { "id": "user_123", "name": "John Doe" }, "selectedModel": "claude-3-5-sonnet-20241022", "subscriptionInfo": { "hasAvailableMaxSubscription": true, "hasAvailableSubscription": false } }, "envVars": { "CUSTOM_VAR": "value" }, "timeout": 3600, "autoPause": true }

Field Notes:

  • name (required): Unique identifier for the sandbox
  • template (optional): E2B template ID - defaults to yhviqh0tk1bo8z7uu1qf (cloud) or rki5dems9wqfm4r03t7g (self-hosted)
  • taskDescription (optional): Used to generate human-readable display name via AI
  • githubToken (optional): GitHub personal access token for repository operations
  • githubRepo (optional): Repository to clone in format "owner/repo"
  • repositorySetup (optional): Configuration for repository environment
    • environmentVariables (optional): Environment variables to set in the sandbox
    • Note: Setup commands and dev server config are now handled via yolocode.yaml in the repository
  • claudeCredentials (optional): Claude OAuth credentials for AI assistance
    • If not provided, a JWT token will be generated for gateway authentication
    • account, selectedModel, subscriptionInfo are optional but recommended for full Claude integration
  • envVars (optional): Additional environment variables
  • timeout (optional): Sandbox timeout in seconds - defaults to 3600 (1 hour) for cloud, 86400 (24 hours) for self-hosted
  • autoPause (optional): Enable auto-pause when idle - defaults to true

Response Example

{ "id": "sb_abc123xyz", "name": "react-dev-env", "template": "yhviqh0tk1bo8z7uu1qf", "status": "running", "createdAt": "2025-01-11T11:00:00Z", "metadata": { "userId": "12345", "userLogin": "johndoe", "displayName": "react typescript application builder", "name": "react-dev-env", "actualSandboxName": "react-dev-env", "githubRepo": "myuser/my-react-app", "autoPause": "true" }, "githubRepo": "myuser/my-react-app", "host": "https://8888-sb_abc123xyz.e2b.app", "websshHost": "https://8888-sb_abc123xyz.e2b.app", "claudeHost": "https://9999-sb_abc123xyz.e2b.app" }

Response Field Notes:

  • id: E2B sandbox ID (format: sb_<random>)
  • displayName: AI-generated human-readable name based on taskDescription
  • metadata: Automatically includes userId, userLogin, displayName, and request fields
  • host, websshHost, claudeHost: Full URLs with ports embedded (format: https://<port>-<sandboxId>.e2b.app)
  • Use claudeHost + /chat for your Vercel AI SDK integration

List All Sandboxes

GET /api/e2b-sandboxes

Lists all E2B sandboxes for the authenticated user.

cURL Example

curl -X GET https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)"

Response Example

[ { "id": "sandbox_abc123", "name": "my-dev-sandbox", "template": "4mc4d3ts8akgu5790i35", "status": "running", "createdAt": "2025-01-11T10:00:00Z", "metadata": { "userId": "12345", "userLogin": "johndoe", "displayName": "Build React App" }, "githubRepo": "johndoe/my-project", "region": "us-east-1", "host": "sandbox-abc123.e2b.dev" } ]

Get Sandbox Details

GET /api/e2b-sandboxes/{id}

Retrieves details of a specific sandbox.

cURL Example

curl -X GET https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789 \ -H "Authorization: Bearer $(gh auth token)"

Execute Command

POST /api/e2b-sandboxes/{id}/exec

Executes a command inside the sandbox and returns the output.

Request Body

{ "command": "ls -la" }

cURL Example

curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "npm run test"}'

Response Example

{ "output": "Test Results:\nāœ“ All tests passed (42 tests, 0 failures)" }

Start Sandbox

POST /api/e2b-sandboxes/{id}/start

Starts a stopped sandbox.

cURL Example

curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789/start \ -H "Authorization: Bearer $(gh auth token)"

Stop Sandbox

POST /api/e2b-sandboxes/{id}/stop

Stops a running sandbox (Note: E2B may only support killing, not graceful stop).

cURL Example

curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789/stop \ -H "Authorization: Bearer $(gh auth token)"

Delete Sandbox

DELETE /api/e2b-sandboxes/{id}

Permanently deletes a sandbox.

cURL Example

curl -X DELETE https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789 \ -H "Authorization: Bearer $(gh auth token)"

Write File to Sandbox

POST /api/e2b/{sandboxId}/files/write

Writes a file to the sandbox filesystem. Supports both binary file uploads (via FormData) and text content (via JSON).

FormData Upload (for binary files)

curl -X POST https://staging.yolocode.ai/api/e2b/sandbox_xyz789/files/write \ -H "Authorization: Bearer $(gh auth token)" \ -F "file=@/path/to/local/image.png" \ -F "path=/home/user/workspace/uploads/image.png"

JSON Upload (for text content)

curl -X POST https://staging.yolocode.ai/api/e2b/sandbox_xyz789/files/write \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{ "path": "/home/user/workspace/config.json", "content": "{\"key\": \"value\"}" }'

Request Body (JSON)

{ "path": "/home/user/workspace/file.txt", "content": "file content as string" }

Request Body (FormData)

FieldTypeDescription
fileFileThe file to upload
pathstringDestination path in the sandbox

Response Example

{ "success": true }

Use Cases

  • Upload images, PDFs, or other binary files for processing
  • Write configuration files
  • Deploy static assets to the sandbox
  • Upload data files for analysis

Configure Claude Credentials

POST /api/e2b-sandboxes/{id}/claude-credentials

Updates Claude AI credentials for a sandbox after creation.

Request Body

{ "claudeCredentials": { "accessToken": "claude_access_token", "refreshToken": "claude_refresh_token", "expiresAt": "2025-01-12T10:00:00Z", "subscriptionInfo": { "hasAvailableMaxSubscription": true } } }

cURL Example

curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/sandbox_xyz789/claude-credentials \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{ "claudeCredentials": { "accessToken": "xxx", "refreshToken": "yyy", "expiresAt": "2025-01-12T10:00:00Z" } }'

Integrating with Your App

React with Vercel AI SDK

After creating a sandbox, you can immediately interact with Claude AI using the claudeHost URL returned in the response. The Claude SSE server is automatically started during sandbox creation and provides an SSE (Server-Sent Events) endpoint compatible with Vercel AI SDK's useChat hook.

No additional setup required - the server is running and ready to accept requests as soon as the sandbox creation completes.

React Native Example

import { useChat } from '@ai-sdk/react'; import { DefaultChatTransport } from '@ai-sdk/ui-utils'; // After creating sandbox, you get claudeHost in response // Example: "9999-sandbox-xyz789.e2b.app" const sandboxResponse = await createSandbox(/* ... */); const { claudeHost } = sandboxResponse; // Build SSE URL for E2B Claude server const sseUrl = claudeHost.startsWith('http') ? `${claudeHost}/chat` : `https://${claudeHost}/chat`; // Use Vercel AI SDK's useChat hook with custom API endpoint const { messages, sendMessage, error, status, stop } = useChat({ transport: new DefaultChatTransport({ fetch: expoFetch as unknown as typeof globalThis.fetch, api: sseUrl, }), onFinish: ({ message }) => { console.log('Chat finished, new message:', message); }, onError: error => { // Check if this is a cancellation error from the stop button const errorMessage = error?.message || error?.toString() || ''; if ( errorMessage.includes('FetchRequestCanceledException') || errorMessage.includes('AbortError') || errorMessage.includes('canceled') ) { console.log('Request cancelled by user'); return; // Don't show error for intentional cancellation } console.error('Chat error:', error); showErrorToast('Connection Error', 'Failed to connect to Claude'); }, }); // Send a message programmatically await sendMessage({ text: 'Help me build a React component', });

Node.js/TypeScript Example

import { streamText } from 'ai'; // Build SSE URL from claudeHost const claudeHost = '9999-sandbox-xyz789.e2b.app'; const sseUrl = `https://${claudeHost}/chat`; // Send a message and stream the response const response = await fetch(sseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ messages: [ { role: 'user', content: 'Explain the code in package.json', }, ], }), }); // Handle streaming response const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); console.log('Received:', chunk); }

cURL Example

# Get claudeHost from sandbox creation response CLAUDE_HOST="9999-sandbox-xyz789.e2b.app" # Send a message to Claude via SSE endpoint curl -X POST "https://${CLAUDE_HOST}/chat" \ -H "Content-Type: application/json" \ -d '{ "messages": [ { "role": "user", "content": "List all files in the workspace" } ] }' \ --no-buffer

Available Claude Commands

Claude in the E2B sandbox can execute various commands and file operations:

// Ask Claude to read files await sendMessage({ role: 'user', content: 'Read the package.json file and explain the dependencies', }); // Ask Claude to write code await sendMessage({ role: 'user', content: 'Create a new React component called UserProfile', }); // Ask Claude to run commands await sendMessage({ role: 'user', content: 'Run the test suite and explain any failures', }); // Ask Claude to debug await sendMessage({ role: 'user', content: 'Debug why the server is not starting on port 3000', });

Handling Streaming Responses

The Claude SSE endpoint streams responses in real-time:

// React Native component example function ChatInterface({ claudeHost }) { const sseUrl = `https://${claudeHost}/chat`; const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat({ api: sseUrl, }); return ( <View> {/* Display messages */} {messages.map((message, i) => ( <Text key={i}> {message.role}: {message.content} </Text> ))} {/* Input form */} <TextInput value={input} onChangeText={handleInputChange} placeholder="Ask Claude..." /> {/* Submit/Stop button */} <Button title={isLoading ? "Stop" : "Send"} onPress={isLoading ? stop : handleSubmit} /> </View> ); }

Error Handling

Handle connection and authentication errors:

const { error, clearError } = useChat({ api: sseUrl, onError: error => { if (error.message.includes('401')) { // Claude credentials may be invalid or expired console.error('Authentication failed - update Claude credentials'); // Update credentials via API: // POST /api/e2b-sandboxes/{id}/claude-credentials } else if (error.message.includes('timeout')) { console.error('Request timed out'); } else if (error.message.includes('canceled')) { // User cancelled the request return; } }, });

References

Complete Flow Example: Creating VM and Giving Tasks

Step 1: Create a Sandbox with Repository

# Create sandbox with GitHub repository # Note: Setup commands are now defined in yolocode.yaml in the repository SANDBOX_RESPONSE=$(curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{ "name": "task-runner", "taskDescription": "Implement user authentication with JWT", "githubRepo": "myuser/auth-project", "repositorySetup": { "environmentVariables": { "DATABASE_URL": "postgresql://localhost:5432/mydb", "JWT_SECRET": "your-secret-key" } } }') # Extract sandbox ID SANDBOX_ID=$(echo $SANDBOX_RESPONSE | jq -r '.id') echo "Created sandbox: $SANDBOX_ID"

Step 2: Execute Setup Commands

# Install dependencies curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "cd /home/user/workspace && npm install"}' # Run tests curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "cd /home/user/workspace && npm test"}'

Step 3: Configure Claude for AI Assistance

# Add Claude credentials for AI pair programming curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/claude-credentials \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{ "claudeCredentials": { "accessToken": "your_claude_token", "refreshToken": "your_refresh_token", "expiresAt": "2025-01-12T10:00:00Z" } }'

Step 4: Execute Development Tasks

# Create a new feature file curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "cat > /home/user/workspace/src/auth.js << EOF\nconst jwt = require(\"jsonwebtoken\");\n// Authentication logic here\nEOF"}' # Start development server curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "cd /home/user/workspace && npm run dev &"}'

Step 5: Monitor and Interact

# Check running processes curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "ps aux | grep node"}' # View logs curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "tail -n 50 /home/user/workspace/logs/dev.log"}'

Step 6: Clean Up

# Stop the sandbox when done curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/stop \ -H "Authorization: Bearer $(gh auth token)" # Or delete it permanently curl -X DELETE https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID \ -H "Authorization: Bearer $(gh auth token)"

Error Handling

All endpoints return appropriate HTTP status codes:

  • 200 - Success
  • 201 - Created (for POST /api/e2b-sandboxes)
  • 400 - Bad Request (invalid input)
  • 401 - Unauthorized (missing or invalid GitHub token)
  • 403 - Forbidden (accessing sandbox not owned by user)
  • 404 - Not Found (sandbox doesn't exist)
  • 500 - Internal Server Error

Error Response Format:

{ "error": "Error message description", "details": { "_tag": "ErrorType", "message": "Detailed error message" } }

Template IDs

The API automatically selects the appropriate E2B template based on hosting configuration:

  • Cloud Template: yhviqh0tk1bo8z7uu1qf (default when E2B_DOMAIN is not set)
  • Self-hosted Template: rki5dems9wqfm4r03t7g (when E2B_DOMAIN environment variable is configured)

You can override the template by providing a template field in your request.

Sandbox Lifecycle

  1. Creation: Sandbox starts automatically when created with all services running
    • WebSSH server (port 8888) starts via systemd
    • Claude SSE server (port 9999) starts via systemd
    • Background startup script begins repository setup
    • All environment variables configured in services and shell
  2. Running: Sandbox is active and executing commands
    • Both services are accessible and auto-restart on failure
    • Terminal sessions use configured environment variables
  3. Paused: Sandbox can be paused to save resources (auto-pause supported)
    • Services stop but state is preserved
    • Resume with POST /api/e2b-sandboxes/{id}/resume
  4. Stopped: E2B doesn't support graceful stop - only kill (permanent deletion)
    • Stop operation is equivalent to delete
    • Cannot be restarted after stopping
  5. Deleted: Sandbox is permanently removed

Security Considerations

  1. Authentication: All requests require valid GitHub OAuth tokens
  2. Ownership: Users can only access their own sandboxes
  3. Isolation: Each sandbox runs in an isolated environment
  4. Credentials: Claude credentials are stored securely and never exposed in responses
  5. JWT Tokens: Sandbox-specific JWT tokens are generated for Claude gateway authentication

Rate Limits

  • Maximum request duration: 300 seconds (5 minutes)
  • Sandbox timeout: 1 hour (cloud) or 24 hours (self-hosted)
  • Concurrent sandboxes: Depends on E2B plan

Service Endpoints

Each sandbox automatically starts two services via systemd:

WebSSH Terminal (Port 8888)

  • URL format: https://8888-{sandboxId}.e2b.app (cloud) or https://8888-{sandboxId}.{E2B_DOMAIN} (self-hosted)
  • Service: webssh.service running /usr/local/bin/wssh
  • Auto-started: Yes, during sandbox creation
  • Environment: Includes GITHUB_TOKEN, GITHUB_REPO, and custom env vars from repositorySetup
  • Working directory: /home/user (shells start in /home/user/workspace via .bashrc)

Claude SSE Server (Port 9999)

  • URL format: https://9999-{sandboxId}.e2b.app (cloud) or https://9999-{sandboxId}.{E2B_DOMAIN} (self-hosted)
  • Service: claude-sse-server.service running /usr/local/bin/bun /home/user/claude-sse-server.ts --continue
  • Auto-started: Yes, during sandbox creation
  • Environment: Includes Claude auth tokens, GitHub credentials, and custom env vars
  • Endpoints:
    • POST /chat - SSE endpoint for Claude AI conversations (Vercel AI SDK compatible)
    • POST /stop - Optional endpoint to signal task cancellation
    • GET /history - Retrieve chat history (optional, may not be implemented in all versions)

Both services are managed by systemd and will:

  • Auto-restart on failure (Restart=always, RestartSec=5)
  • Start automatically on sandbox boot
  • Log to systemd journal (journalctl -u webssh or journalctl -u claude-sse-server)

Debugging Sandbox Services

If you need to check the status of services or debug issues, use the /exec endpoint:

Check Service Status

# Check WebSSH service status curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo systemctl status webssh"}' # Check Claude SSE server status curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo systemctl status claude-sse-server"}'

View Service Logs

# View WebSSH logs (last 50 lines) curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo journalctl -u webssh -n 50 --no-pager"}' # View Claude SSE server logs curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo journalctl -u claude-sse-server -n 50 --no-pager"}'

Check Network Ports

# Verify services are listening on correct ports curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "ss -tlnp | grep -E \":(8888|9999)\""}'

Restart Services

# Restart WebSSH curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo systemctl restart webssh"}' # Restart Claude SSE server curl -X POST https://staging.yolocode.ai/api/e2b-sandboxes/$SANDBOX_ID/exec \ -H "Authorization: Bearer $(gh auth token)" \ -H "Content-Type: application/json" \ -d '{"command": "sudo systemctl restart claude-sse-server"}'

Best Practices

  1. Always clean up sandboxes when done to avoid unnecessary charges
  2. Use autoPause for sandboxes that may be idle
  3. Store sensitive environment variables in repositorySetup.environmentVariables
  4. Use descriptive task descriptions for better AI-generated display names
  5. Monitor sandbox resource usage through the E2B dashboard