Skip to main content

Bridge Environments

Bridge Environments provide sandboxed remote compute for background agent execution using a Bring Your Own Compute (BYOC) model. An environment is a logical container that receives work items, executes them in isolation, and reports results back through a polling loop.

Two provider types are available:

ProviderIDDescription
AINative Agent CloudainativeManaged compute hosted by AINative (us-east-1)
Bring Your Own ComputebyocSelf-hosted compute on your own infrastructure

Authentication

All endpoints require a Bearer token in the Authorization header:

Authorization: Bearer <token>

An optional advisory header is accepted but not enforced:

anthropic-beta: ccr-byoc-2025-07-29

Base URLs

RouterPrefix
Bridge Environments/v1/environments
Environment Providers/v1/environment_providers

Environment Lifecycle

create  -->  active  -->  heartbeat (keepalive loop)
|
+--> poll work --> ack/stop work
|
+--> disconnect --> reconnect --> active
|
+--> delete (teardown)
  1. Create an environment via POST /v1/environments/bridge or POST /v1/environment_providers/cloud/create.
  2. The environment enters active status.
  3. A worker polls for work items on GET /v1/environments/{id}/work/poll.
  4. When a work item is received, the worker executes it and acknowledges completion via POST /v1/environments/{id}/work/ack.
  5. If a work item must be cancelled, the worker sends a stop signal via POST /v1/environments/{id}/work/stop.
  6. The worker sends periodic heartbeats to keep the environment alive.
  7. If the connection drops, the worker reconnects to resume.
  8. When the environment is no longer needed, delete it to free resources.

Endpoints

POST /v1/environments/bridge

Create a new bridge environment.

Request body:

{
"provider": "ainative",
"metadata": {}
}
FieldTypeDefaultDescription
providerstring"ainative"Environment provider ID
metadataobject{}Arbitrary key-value metadata

Response (201 Created):

{
"environment_id": "a1b2c3d4-...",
"provider": "ainative",
"status": "active",
"created_at": "2026-06-01T12:00:00+00:00",
"metadata": {}
}

GET /v1/environments/{environment_id}/work/poll

Long-poll for the next work item to execute. Returns the first pending item in the queue, or null if the queue is empty.

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"work": {
"work_id": "w-123",
"type": "code_execution",
"payload": { "script": "print('hello')" },
"created_at": "2026-06-01T12:01:00+00:00"
},
"poll_interval_ms": 5000
}

When no work is available, work is null. The client should wait poll_interval_ms milliseconds before polling again.

Errors:

StatusCondition
404Environment not found

POST /v1/environments/{environment_id}/work/ack

Acknowledge that a work item has been completed and remove it from the queue.

Request body:

{
"work_id": "w-123",
"result": { "exit_code": 0, "stdout": "hello\n" }
}

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"work_id": "w-123",
"status": "acknowledged"
}

POST /v1/environments/{environment_id}/work/stop

Signal that a work item should be stopped. Removes it from the queue.

Request body:

{
"work_id": "w-123",
"reason": "timeout exceeded"
}

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"work_id": "w-123",
"status": "stopped"
}

POST /v1/environments/{environment_id}/work/heartbeat

Keepalive heartbeat. Resets the environment's inactivity timer and confirms it is still alive.

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"status": "alive",
"next_heartbeat_ms": 30000
}

Send the next heartbeat within next_heartbeat_ms milliseconds. If no heartbeat is received within that window, the environment may be marked as disconnected.


POST /v1/environments/{environment_id}/bridge/reconnect

Reconnect an environment that was previously disconnected. Restores its status to active.

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"status": "active",
"reconnected_at": "2026-06-01T12:10:00+00:00"
}

DELETE /v1/environments/bridge/{environment_id}

Tear down and permanently clean up an environment. All pending work items in the queue are discarded.

Response (200 OK):

{
"environment_id": "a1b2c3d4-...",
"status": "deleted"
}

GET /v1/environment_providers

List available environment providers and their availability.

Response (200 OK):

{
"providers": [
{
"provider_id": "ainative",
"name": "AINative Agent Cloud",
"region": "us-east-1",
"available": true
},
{
"provider_id": "byoc",
"name": "Bring Your Own Compute",
"region": "self-hosted",
"available": true
}
]
}

POST /v1/environment_providers/cloud/create

Create a default AINative-hosted cloud environment. This is a convenience endpoint used by the CLI when no environment exists yet.

Request body (all fields optional):

{
"provider": "ainative",
"metadata": {}
}

Response (201 Created): Same shape as POST /v1/environments/bridge.


Worker Loop Example (Python)

import time
import requests

BASE = "https://api.ainative.studio:8000"
TOKEN = "your-bearer-token"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}

# 1. Create environment
resp = requests.post(f"{BASE}/v1/environments/bridge",
json={"provider": "ainative"},
headers=HEADERS)
env_id = resp.json()["environment_id"]

# 2. Poll-execute-ack loop
while True:
poll = requests.get(f"{BASE}/v1/environments/{env_id}/work/poll",
headers=HEADERS).json()
if poll["work"]:
work = poll["work"]
result = execute(work["payload"]) # your execution logic
requests.post(f"{BASE}/v1/environments/{env_id}/work/ack",
json={"work_id": work["work_id"], "result": result},
headers=HEADERS)
else:
time.sleep(poll["poll_interval_ms"] / 1000)

# 3. Heartbeat
requests.post(f"{BASE}/v1/environments/{env_id}/work/heartbeat",
headers=HEADERS)

Error Responses

All endpoints return standard HTTP error responses:

StatusMeaning
401Missing or invalid bearer token
404Environment not found