Overview
This guide walks you through migrating from OpenHands V0 APIs to the new V1 APIs. We’ll take you step-by-step through a typical migration, showing exactly what changes and why.What’s Different in V1?
The most important change: Conversations and Sandboxes are now decoupled. In V0, creating a conversation automatically created and managed the underlying sandbox (runtime environment). In V1, sandboxes are independent resources you can:- Pause and resume without losing state
- Reuse across multiple conversations
- Manage with explicit lifecycle controls
- App Server API (
app.all-hands.dev) - Manage conversations and sandboxes (this guide’s focus) - Agent Server API (per-sandbox URL) - Direct access to workspace and runtime operations
Why Migrate? Key Benefits
Why Migrate? Key Benefits
| Theme | Key Result |
|---|---|
| Reliability | 61% reduction in system failures — eliminated entire classes of infrastructure errors |
| Performance | Lighter-weight runtime with co-located execution — removes inter-pod communication overhead |
| Developer Experience | Modern API patterns — dedicated search, filtering, batch operations, webhooks, and flexible sandbox controls |
- 61% reduction in system-attributable failures (78.0 → 30.0 errors per 1k conversations)
- Eliminated infrastructure errors from inter-pod communication
- Event-sourced state enables replay-based recovery
- Lighter-weight agent server reduces resource overhead
- Independent sandbox lifecycle for better resource control
- Pause/resume sandboxes, explicit status tracking (
STARTING,RUNNING,PAUSED,ERROR) - Dedicated search and count endpoints
- Batch operations and enhanced filtering
- Webhook support for lifecycle events
- Stream conversation updates from creation
Migration Walkthrough
Follow along as we migrate a typical V0 integration to V1. Each step shows your existing V0 code and the V1 equivalent.Step 1: Create and Start a Conversation
V0 Approach In V0, you called a single endpoint and got a conversation ID immediately:Key Changes:
- Endpoint:
/api/conversations→/api/v1/app-conversations - Field:
initial_user_msg(string) →initial_message(object with content array) - Field:
repository→selected_repository - Response field:
conversation_id→app_conversation_id - The conversation ID isn’t immediately available—see Step 2
Step 2: Track Conversation Startup
In V0, your conversation was ready immediately. In V1, you need to wait for initialization to complete. You have two options: Option A: Poll for Readinessstatus field tells you where things stand:
WORKING→ Initial processingWAITING_FOR_SANDBOX→ Waiting for sandbox to be readyPREPARING_REPOSITORY→ Cloning/setting up the repositoryRUNNING_SETUP_SCRIPT→ Running initialization scriptsSETTING_UP_GIT_HOOKS→ Configuring git hooksSETTING_UP_SKILLS→ Loading skills and pluginsSTARTING_CONVERSATION→ Starting the conversationREADY→ Conversation is ready, useapp_conversation_idfor subsequent callsERROR→ Something went wrong, check thedetailfield
AppConversationStartTask object with updated status. Parse it as a JSON array; elements arrive as the conversation initializes:
Step 3: Work with Events and Messages
Once your conversation is ready, here’s how to send messages and retrieve events. Sending MessagesBig improvement in V1: In V0, sending messages to a running conversation typically requires establishing a WebSocket (Socket.IO) connection. V1 provides a simple REST endpoint on the Agent Server, making programmatic message sending much easier.
- V0 (Deprecated)
- V1 (Recommended)
V0 requires a WebSocket connection to send messages to a running conversation. While a REST endpoint exists, the standard approach uses Socket.IO:
- V0 (Deprecated)
- V1 (Recommended)
Step 4: Manage Sandbox Lifecycle
This is entirely new in V1. You now have explicit control over sandbox resources. Search for Your SandboxesSandbox Status Values:
STARTING- Sandbox is initializingRUNNING- Sandbox is active and readyPAUSED- Sandbox is suspended (no billing)ERROR- Something went wrongMISSING- Sandbox no longer exists
Step 5: Access the Agent Server (When Needed)
For direct workspace operations (file uploads, bash commands, git operations), you’ll use the Agent Server API. This runs on each sandbox and requires a different authentication method. Getting the Agent Server URL First, get your sandbox details:exposed_urls is an array of {name, url, port} objects. To find the Agent Server URL, filter for the entry where name == "AGENT_SERVER".session_api_key with the X-Session-API-Key header:
Step 6: Handle Files and Workspace
File operations have moved from the App Server to the Agent Server in V1.| V0 Operation | V1 Equivalent |
|---|---|
GET /api/conversations/{id}/list-files | Agent Server: POST /api/bash/execute_bash_command with ls |
GET /api/conversations/{id}/select-file | Agent Server: GET /api/file/download?path=... |
POST /api/conversations/{id}/upload-files | Agent Server: POST /api/file/upload?path=... |
GET /api/conversations/{id}/zip-directory | Agent Server: Download files individually via GET /api/file/download?path=... |
The Agent Server file routes use query parameters (
?path=...), not path-style URLs (/{path}). Path-style routes are deprecated.RemoteWorkspace class for Agent Server operations:
Step 7: Monitor Conversations and Fetch Events
If you’re building custom dashboards, CI/CD integrations, or alternative visualizations, you’ll need to fetch conversation events. V1 provides a much more flexible approach than V0. V0 Approach: Trajectory Download In V0, you fetched all events at once using the trajectory endpoint:limit- Max results per page (up to 100)sort_order-TIMESTAMP(oldest first) orTIMESTAMP_DESC(newest first)timestamp__gte- Events at or after this timetimestamp__lt- Events before this timekind__eq- Filter by event type (MessageEvent,ActionEvent,ObservationEvent, etc.)page_id- For pagination through large result sets
Why V1 is better for monitoring:
- Incremental fetches - Only get new events using
timestamp__gte, not the entire history - Flexible filtering - Filter by event type, time range, or paginate through results
- Lower latency - Smaller payloads mean faster responses
- Works without active sandbox - App Server events persist even when sandbox is paused
Quick Reference: Endpoint Mapping
Use this section to look up specific endpoint mappings when you need them.Conversation Lifecycle
| Operation | V0 Endpoint | V1 Endpoint |
|---|---|---|
| Create conversation | POST /api/conversations | POST /api/v1/app-conversations |
| Start (streaming) | POST /api/conversations/{id}/start | POST /api/v1/app-conversations/stream-start |
| Search conversations | GET /api/conversations | GET /api/v1/app-conversations/search |
| Get by ID | GET /api/conversations/{id} | GET /api/v1/app-conversations?id={id} |
| Get count | N/A | GET /api/v1/app-conversations/count |
| Update | PATCH /api/conversations/{id} | PATCH /api/v1/app-conversations/{id} |
| Delete | DELETE /api/conversations/{id} | DELETE /api/v1/app-conversations/{id} |
Events & Messages
| Operation | V0 Endpoint | V1 Endpoint |
|---|---|---|
| Send message | WebSocket (Socket.IO) required | Agent Server: POST /api/conversations/{id}/events |
| Get trajectory | GET /api/conversations/{id}/trajectory | GET /api/v1/conversation/{id}/events/search (paginated) |
| Search events | GET /api/conversations/{id}/events | GET /api/v1/conversation/{id}/events/search |
| Get event count | N/A | GET /api/v1/conversation/{id}/events/count |
| Batch get events | N/A | GET /api/v1/conversation/{id}/events |
Sandbox Management (New in V1)
| Operation | V1 Endpoint |
|---|---|
| Create sandbox | POST /api/v1/sandboxes |
| Search sandboxes | GET /api/v1/sandboxes/search |
| Get sandboxes | GET /api/v1/sandboxes |
| Pause | POST /api/v1/sandboxes/{id}/pause |
| Resume | POST /api/v1/sandboxes/{id}/resume |
| Delete | DELETE /api/v1/sandboxes/{id} |
Development Tools
| Operation | V0 Endpoint | V1 Equivalent |
|---|---|---|
| Get VSCode URL | GET /api/conversations/{id}/vscode-url | Get sandbox, find VSCODE in exposed_urls |
| Get web hosts | GET /api/conversations/{id}/web-hosts | Get sandbox, find AGENT_SERVER in exposed_urls |
Health & Status (Unchanged)
| Operation | Endpoint |
|---|---|
| Health check | GET /health |
| Alive check | GET /alive |
| Ready check | GET /ready |
Agent Server API Reference
The Agent Server runs on each sandbox and provides direct access to workspace operations.Authentication
Use thesession_api_key from your sandbox info with the X-Session-API-Key header.
Available Endpoints
File Operations
File Operations
| Endpoint | Description |
|---|---|
POST /api/file/upload?path=... | Upload files to workspace |
GET /api/file/download?path=... | Download individual files |
GET /api/file/download-trajectory/{conversation_id} | Download conversation trajectory |
Git Operations
Git Operations
| Endpoint | Description |
|---|---|
GET /api/git/changes/{path} | Get git changes |
GET /api/git/diff/{path} | Get git diff |
Bash Operations
Bash Operations
| Endpoint | Description |
|---|---|
POST /api/bash/execute_bash_command | Execute bash command (blocking) |
POST /api/bash/start_bash_command | Start bash command (async) |
GET /api/bash/bash_events/search | Search bash events |
Conversation Operations
Conversation Operations
| Endpoint | Description |
|---|---|
POST /api/conversations/{id}/events | Send user message |
GET /api/conversations/{id}/events/search | Search events |
GET /api/conversations/{id}/events/count | Count events |
POST /api/conversations/{id}/pause | Pause conversation |
POST /api/conversations/{id}/run | Resume/run conversation |
DELETE /api/conversations/{id} | Delete conversation |
Development Tools
Development Tools
| Endpoint | Description |
|---|---|
GET /api/vscode/url | Get VSCode URL |
GET /api/vscode/status | Check VSCode status |
GET /api/desktop/url | Get desktop URL |
GET /api/tools/ | List available tools |
The Agent Server requires an active (running) sandbox. For operations on paused or inactive sandboxes, use the App Server API.
Accessing Agent Server API Documentation
The Agent Server provides its own Swagger UI and OpenAPI specification, but you need a running sandbox to access them. Step 1: Get the Agent Server URL First, retrieve your sandbox info to get the Agent Server URL (see Step 5 above):AGENT_SERVER URL from exposed_urls.
Step 2: Access the Documentation
Once you have the Agent Server URL, you can access:
| Resource | URL |
|---|---|
| Swagger UI | {agent_server_url}/docs |
| OpenAPI JSON | {agent_server_url}/openapi.json |
https://sandbox-abc123.runtime.all-hands.dev:
Known Gaps and Workarounds
Some V0 capabilities don’t have direct V1 App Server equivalents yet:| Gap | V0 Endpoint | Workaround |
|---|---|---|
| Download workspace as zip | GET /api/conversations/{id}/zip-directory | Use Agent Server GET /api/file/download?path=... for individual files, or create a tar/zip via bash command |
| Get trajectory (inactive runtime) | GET /api/conversations/{id}/trajectory | Trajectory available while sandbox is active via Agent Server GET /api/file/download-trajectory/{conversation_id} |
| List workspace files | GET /api/conversations/{id}/list-files | Use Agent Server POST /api/bash/execute_bash_command with ls or find |
Authentication Summary
| API | Authentication |
|---|---|
| App Server (both V0 and V1) | API key via Authorization: Bearer YOUR_API_KEY header |
| Agent Server | Session API key via X-Session-API-Key: {session_api_key} header |
/api/keys endpoint and work for both V0 and V1 App Server APIs.
Additional Resources
- V1 REST API Overview
- Cloud API Guide
- OpenHands SDK — Python SDK with
RemoteWorkspacefor file operations, command execution, and git operations - V1 API Swagger Docs — Interactive API documentation
- V1 API OpenAPI Spec — OpenAPI JSON specification for the App Server

