Bridge Environments
Bridge Environments
Bridge Environments let a worker process register itself, then receive and execute work items dispatched by AINative through a poll/acknowledge/heartbeat loop.
Authentication
All endpoints require the normal platform Bearer token in the Authorization header:
Authorization: Bearer <token>
Base URL
| Router | Prefix |
|---|---|
| Bridge Environments | /v1/environments (also reachable at /api/v1/environments) |
| Environment Providers | /api/v1/environment_providers |
Environment Lifecycle
register --> online --> heartbeat (keepalive loop)
|
+--> poll work --> ack/stop/heartbeat work (by work_id)
|
+--> reconnect (status returns to online)
|
+--> deregister (teardown)
- Register a worker via
POST /v1/environments/bridge. - The worker polls for work items on
GET /v1/environments/{env_id}/work/poll. - When a work item is received, the worker executes it and acknowledges completion via
POST /v1/environments/{env_id}/work/{work_id}/ack. - The worker sends periodic heartbeats per work item via
POST /v1/environments/{env_id}/work/{work_id}/heartbeatwhile it's in progress. - If a work item must be cancelled, the worker sends stop via
POST /v1/environments/{env_id}/work/{work_id}/stop. - If the connection drops, the worker reconnects via
POST /v1/environments/{env_id}/bridge/reconnect. - When the environment is no longer needed, deregister it to free resources.
Endpoints
POST /v1/environments/bridge
Register a new worker environment.
Request body:
{
"name": "my-worker-01",
"hostname": "worker-01.local",
"platform": "linux-x86_64",
"capabilities": ["code_execution", "gpu"],
"metadata": {}
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable environment name |
hostname | string | no | Worker hostname |
platform | string | no | Worker platform string |
capabilities | string[] | no | Capability tags this worker supports |
metadata | object | no | Arbitrary key-value metadata |
Response (201 Created):
{
"id": "a1b2c3d4-...",
"name": "my-worker-01",
"user_id": "f5e6d7c8-...",
"status": "online",
"hostname": "worker-01.local",
"platform": "linux-x86_64",
"capabilities": ["code_execution", "gpu"],
"last_heartbeat": null,
"created_at": "2026-10-08T12:00:00+00:00",
"updated_at": "2026-10-08T12:00:00+00:00"
}
status is one of online, offline, busy, error — there is no active status.
Errors: 400 inactive user, 401 not authenticated.
DELETE /v1/environments/bridge/{env_id}
Deregister (tear down) a worker environment.
Response (200 OK):
{
"id": "a1b2c3d4-...",
"status": "deregistered",
"message": "Environment successfully deregistered"
}
Errors: 400 inactive user, 401 not authenticated, 404 environment not found.
POST /v1/environments/{env_id}/bridge/reconnect
Reconnect a previously-registered environment.
Response (200 OK):
{
"id": "a1b2c3d4-...",
"status": "online",
"message": "Environment reconnected"
}
Errors: 400 inactive user, 401 not authenticated, 404 environment not found.
GET /v1/environments/{env_id}/work/poll
Long-poll for the next work item (up to timeout seconds, default 30, max 60).
Query params: timeout (int, optional, 1-60, default 30)
Response (200 OK), work available:
{
"work": {
"id": "w-123",
"environment_id": "a1b2c3d4-...",
"user_id": "f5e6d7c8-...",
"status": "dispatched",
"work_type": "code_task",
"payload": {"script": "print('hello')"},
"result": null,
"last_heartbeat": null,
"acknowledged_at": null,
"completed_at": null,
"created_at": "2026-10-08T12:01:00+00:00"
},
"message": "Work dispatched"
}
Response (200 OK), no work available:
{"work": null, "message": "No work available"}
status on a work item is one of queued, dispatched, acknowledged, in_progress,
completed, failed, stopped.
Errors: 400 inactive user, 401 not authenticated, 404 environment not found.
POST /v1/environments/{env_id}/work/{work_id}/ack
Acknowledge receipt of a work item. work_id is a path parameter, not a request body field.
Response (200 OK):
{
"id": "w-123",
"status": "acknowledged",
"acknowledged_at": "2026-10-08T12:01:05+00:00"
}
Errors: 400 inactive user, 401 not authenticated, 404 environment or work item not found,
409 work item cannot be acknowledged in its current status.
POST /v1/environments/{env_id}/work/{work_id}/heartbeat
Send a keepalive heartbeat for an in-progress work item. work_id is a path parameter.
Response (200 OK):
{
"id": "w-123",
"status": "heartbeat_received",
"last_heartbeat": "2026-10-08T12:02:00+00:00"
}
Errors: 400 inactive user, 401 not authenticated, 404 environment or work item not found,
409 cannot heartbeat work in a terminal status.
POST /v1/environments/{env_id}/work/{work_id}/stop
Stop a work item. work_id is a path parameter.
Response (200 OK):
{
"id": "w-123",
"status": "stopped",
"message": "Work item stopped"
}
Errors: 400 inactive user, 401 not authenticated, 404 environment or work item not found,
409 cannot stop work in a terminal status.
Environment Providers
GET /api/v1/environment_providers
List available cloud providers and their regions.
Response (200 OK):
{
"providers": [
{
"id": "ainative-cloud",
"name": "AINative Cloud",
"type": "cloud",
"status": "available",
"regions": [
{"id": "us-east-1", "name": "US East (Virginia)"},
{"id": "us-west-2", "name": "US West (Oregon)"},
{"id": "eu-west-1", "name": "EU West (Ireland)"}
]
}
]
}
Errors: 400 inactive user, 401 not authenticated, 503 auth temporarily unavailable.
POST /api/v1/environment_providers/cloud/create
Provision a cloud environment for the caller's organization.
Request body:
{
"provider": "ainative-cloud",
"region": "us-east-1"
}
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | Must be a providers[].id from the list endpoint above |
region | string | yes | Must be one of that provider's regions[].id |
Response (200 OK):
{
"id": "a1b2c3d4-...",
"status": "provisioning",
"provider": "ainative-cloud",
"region": "us-east-1"
}
Errors: 400 unknown provider, invalid region, or inactive user; 401 not authenticated;
503 auth temporarily unavailable.
Worker Loop Example (Python)
import time
import requests
BASE = "https://api.ainative.studio/api/v1"
TOKEN = "your-bearer-token"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
## 1. Register environment
resp = requests.post(f"{BASE}/environments/bridge",
json={"name": "my-worker-01", "capabilities": ["code_execution"]},
headers=HEADERS)
env_id = resp.json()["id"]
## 2. Poll-execute-ack loop
while True:
poll = requests.get(f"{BASE}/environments/{env_id}/work/poll",
params={"timeout": 30},
headers=HEADERS).json()
work = poll["work"]
if work:
work_id = work["id"]
result = execute(work["payload"]) # your execution logic
requests.post(f"{BASE}/environments/{env_id}/work/{work_id}/heartbeat", headers=HEADERS)
requests.post(f"{BASE}/environments/{env_id}/work/{work_id}/ack", headers=HEADERS)
else:
time.sleep(2)
Error Responses
All endpoints return standard HTTP error responses:
| Status | Meaning |
|---|---|
| 400 | Inactive user, or (environment_providers only) unknown provider/region |
| 401 | Missing or invalid bearer token |
| 404 | Environment or work item not found |
| 409 | Work item cannot transition from its current status (ack/heartbeat/stop only) |