curl --request POST \
--url https://odyssey.asteroid.ai/agents/v2/environments \
--header 'Content-Type: application/json' \
--header 'X-Asteroid-Agents-Api-Key: <api-key>' \
--data '
{
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": {
"kind": "workflow",
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
'import requests
url = "https://odyssey.asteroid.ai/agents/v2/environments"
payload = {
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": {
"kind": "workflow",
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
headers = {
"X-Asteroid-Agents-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Asteroid-Agents-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agentId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
agentProfileId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
source: {kind: 'workflow', workflowId: '3c90c3cc-0d44-4b50-8888-8dd25736052a'}
})
};
fetch('https://odyssey.asteroid.ai/agents/v2/environments', 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://odyssey.asteroid.ai/agents/v2/environments",
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([
'agentId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'agentProfileId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'source' => [
'kind' => 'workflow',
'workflowId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Asteroid-Agents-Api-Key: <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://odyssey.asteroid.ai/agents/v2/environments"
payload := strings.NewReader("{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Asteroid-Agents-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/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://odyssey.asteroid.ai/agents/v2/environments")
.header("X-Asteroid-Agents-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://odyssey.asteroid.ai/agents/v2/environments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Asteroid-Agents-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}"
response = http.request(request)
puts response.read_body{
"connection": {
"cdpUrl": "<string>",
"cua": {
"sessionId": "<string>",
"anchorBaseUrl": "<string>",
"daytonaToolboxBaseUrl": "<string>"
}
},
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"hasRecording": true,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"organizationId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner": {
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"executionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "execution"
},
"state": {
"environmentType": "browser",
"hasRecording": true,
"height": 123,
"width": 123,
"browserIp": "<string>",
"liveViewUrl": "<string>",
"providerConfig": {
"type": "anchor",
"sessionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sessionUrl": "<string>"
},
"recordingStartedAt": "2023-11-07T05:31:56Z",
"recordingUrl": "<string>"
},
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"readyAt": "2023-11-07T05:31:56Z",
"stoppedAt": "2023-11-07T05:31:56Z"
}{
"code": 400,
"message": "<string>"
}{
"code": 401,
"message": "<string>"
}{
"code": 403,
"message": "<string>"
}{
"code": 404,
"message": "<string>"
}{
"code": 500,
"message": "<string>"
}Start environment
Start an environment. Blocks until it is ready (or the provider fails) and returns the environment together with its connection details, so a caller boots in one round trip. The agent in the body gates access and supplies the organisation.
curl --request POST \
--url https://odyssey.asteroid.ai/agents/v2/environments \
--header 'Content-Type: application/json' \
--header 'X-Asteroid-Agents-Api-Key: <api-key>' \
--data '
{
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": {
"kind": "workflow",
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
'import requests
url = "https://odyssey.asteroid.ai/agents/v2/environments"
payload = {
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": {
"kind": "workflow",
"workflowId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
headers = {
"X-Asteroid-Agents-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Asteroid-Agents-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agentId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
agentProfileId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
source: {kind: 'workflow', workflowId: '3c90c3cc-0d44-4b50-8888-8dd25736052a'}
})
};
fetch('https://odyssey.asteroid.ai/agents/v2/environments', 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://odyssey.asteroid.ai/agents/v2/environments",
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([
'agentId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'agentProfileId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'source' => [
'kind' => 'workflow',
'workflowId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Asteroid-Agents-Api-Key: <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://odyssey.asteroid.ai/agents/v2/environments"
payload := strings.NewReader("{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Asteroid-Agents-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/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://odyssey.asteroid.ai/agents/v2/environments")
.header("X-Asteroid-Agents-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://odyssey.asteroid.ai/agents/v2/environments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Asteroid-Agents-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"agentId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"agentProfileId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"source\": {\n \"kind\": \"workflow\",\n \"workflowId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}"
response = http.request(request)
puts response.read_body{
"connection": {
"cdpUrl": "<string>",
"cua": {
"sessionId": "<string>",
"anchorBaseUrl": "<string>",
"daytonaToolboxBaseUrl": "<string>"
}
},
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"hasRecording": true,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"organizationId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner": {
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"executionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "execution"
},
"state": {
"environmentType": "browser",
"hasRecording": true,
"height": 123,
"width": 123,
"browserIp": "<string>",
"liveViewUrl": "<string>",
"providerConfig": {
"type": "anchor",
"sessionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sessionUrl": "<string>"
},
"recordingStartedAt": "2023-11-07T05:31:56Z",
"recordingUrl": "<string>"
},
"agentProfileId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"readyAt": "2023-11-07T05:31:56Z",
"stoppedAt": "2023-11-07T05:31:56Z"
}{
"code": 400,
"message": "<string>"
}{
"code": 401,
"message": "<string>"
}{
"code": 403,
"message": "<string>"
}{
"code": 404,
"message": "<string>"
}{
"code": 500,
"message": "<string>"
}Authorizations
Body
Request to start an environment. The agent is a binding carried in the body, not a path segment — an environment belongs to an organisation, and the agent tells provisioning which workflow, profile and organisation to boot against.
The agent to bind the environment to. Gates access, and supplies the organisation the environment is stamped with.
Optional agent profile to attach. The profile id is stamped onto the env row for the session's lifetime, so later reads resolve against the stamped profile rather than the agent's current one. Its decrypted credentials come back on the response's connection only for service-to-service callers — they are never returned to an API key or a browser.
Where the environment spec comes from. Omit for the server default (a browser env at the computer-use resolution).
- Option 1
- Option 2
Show child attributes
Show child attributes
Response
The request has succeeded.
A single environment: what it is, its provider state, and how to drive it. state is the same shape the execution endpoint returns, so the LiveView/OsLiveView components render either without branching.
How to connect to it.
Show child attributes
Show child attributes
When the environment row was created.
Browser or OS.
browser, os When the reaper will tear the environment down if no graceful Stop arrives first.
Whether a playable recording has been persisted (GCS object or provider URL). The playable URL itself is minted on the by-id read.
Environment identifier.
The organisation the environment belongs to.
Who the environment belongs to, and the identity that owner carries.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Environment state (browser or OS): live-view URL, viewport, provider config and a freshly-minted recording URL when one exists.
- Option 1
- Option 2
Show child attributes
Show child attributes
Current status, terminal states included. Lists exclude terminal environments unless includeTerminal is set.
requested, provisioning, ready, stopping, stopped, failed, dead Profile snapshot the environment was booted against, if any.
Operating system for OS environments. Absent for browser environments; linux when an OS environment predates explicit osType storage.
linux, windows When the environment first became ready, if it reached that state.
When the environment reached a terminal state. Set after Stop runs.

