Create an environment
curl --request POST \
--url https://agp.eu.hcompany.ai/api/v2/environments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"kind": "<string>",
"host": "<string>",
"start_url": "<string>",
"headless": true,
"session_id": {},
"lazy": true,
"settle_s": 123,
"mode": {},
"vault_id": {},
"browser_profile_id": {},
"use_default_browser_profile": true,
"persist_browser_profile": true,
"network": {}
}
'import requests
url = "https://agp.eu.hcompany.ai/api/v2/environments"
payload = {
"id": "<string>",
"kind": "<string>",
"host": "<string>",
"start_url": "<string>",
"headless": True,
"session_id": {},
"lazy": True,
"settle_s": 123,
"mode": {},
"vault_id": {},
"browser_profile_id": {},
"use_default_browser_profile": True,
"persist_browser_profile": True,
"network": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
kind: '<string>',
host: '<string>',
start_url: '<string>',
headless: true,
session_id: {},
lazy: true,
settle_s: 123,
mode: {},
vault_id: {},
browser_profile_id: {},
use_default_browser_profile: true,
persist_browser_profile: true,
network: {}
})
};
fetch('https://agp.eu.hcompany.ai/api/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://agp.eu.hcompany.ai/api/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([
'id' => '<string>',
'kind' => '<string>',
'host' => '<string>',
'start_url' => '<string>',
'headless' => true,
'session_id' => [
],
'lazy' => true,
'settle_s' => 123,
'mode' => [
],
'vault_id' => [
],
'browser_profile_id' => [
],
'use_default_browser_profile' => true,
'persist_browser_profile' => true,
'network' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://agp.eu.hcompany.ai/api/v2/environments"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://agp.eu.hcompany.ai/api/v2/environments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://agp.eu.hcompany.ai/api/v2/environments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}"
response = http.request(request)
puts response.read_bodyEnvironments
Create an environment
Create a reusable environment in your catalog: a cloud browser, your own browser, or your own desktop, with its settings.
POST
/
api
/
v2
/
environments
Create an environment
curl --request POST \
--url https://agp.eu.hcompany.ai/api/v2/environments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"kind": "<string>",
"host": "<string>",
"start_url": "<string>",
"headless": true,
"session_id": {},
"lazy": true,
"settle_s": 123,
"mode": {},
"vault_id": {},
"browser_profile_id": {},
"use_default_browser_profile": true,
"persist_browser_profile": true,
"network": {}
}
'import requests
url = "https://agp.eu.hcompany.ai/api/v2/environments"
payload = {
"id": "<string>",
"kind": "<string>",
"host": "<string>",
"start_url": "<string>",
"headless": True,
"session_id": {},
"lazy": True,
"settle_s": 123,
"mode": {},
"vault_id": {},
"browser_profile_id": {},
"use_default_browser_profile": True,
"persist_browser_profile": True,
"network": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
kind: '<string>',
host: '<string>',
start_url: '<string>',
headless: true,
session_id: {},
lazy: true,
settle_s: 123,
mode: {},
vault_id: {},
browser_profile_id: {},
use_default_browser_profile: true,
persist_browser_profile: true,
network: {}
})
};
fetch('https://agp.eu.hcompany.ai/api/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://agp.eu.hcompany.ai/api/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([
'id' => '<string>',
'kind' => '<string>',
'host' => '<string>',
'start_url' => '<string>',
'headless' => true,
'session_id' => [
],
'lazy' => true,
'settle_s' => 123,
'mode' => [
],
'vault_id' => [
],
'browser_profile_id' => [
],
'use_default_browser_profile' => true,
'persist_browser_profile' => true,
'network' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://agp.eu.hcompany.ai/api/v2/environments"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://agp.eu.hcompany.ai/api/v2/environments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://agp.eu.hcompany.ai/api/v2/environments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"kind\": \"<string>\",\n \"host\": \"<string>\",\n \"start_url\": \"<string>\",\n \"headless\": true,\n \"session_id\": {},\n \"lazy\": true,\n \"settle_s\": 123,\n \"mode\": {},\n \"vault_id\": {},\n \"browser_profile_id\": {},\n \"use_default_browser_profile\": true,\n \"persist_browser_profile\": true,\n \"network\": {}\n}"
response = http.request(request)
puts response.read_bodyCreates a custom environment in your catalog. Reference it by
id (e.g. "environments": ["wide-browser"]) from any agent. Most agents define environments inline. Register one here to reuse it across agents.
Returns 201 with the created environment object.
Request body
The body is a Browser spec (kind: "web", the default), documented below. A desktop on your own machine (kind: "desktop", see Local control) takes only id, host (required), session_id, lazy, settle_s (default 0.5), and screenshot_max_width (up to 1920 pixels, null keeps the host default; screenshots are only shrunk, never enlarged).
string
required
Catalog identifier, kebab-case with an optional single
org/ namespace prefix. The h/ prefix is reserved for H’s catalog (rejected with 403). Immutable after creation.string
default:"web"
Environment type:
web for a browser, desktop for a desktop.string
default:"cloud"
Where the browser runs:
cloud on H infrastructure, or user_device for Chrome on your own machine. See Local control.string
default:"https://www.bing.com"
Initial URL to open.
boolean
default:"false"
Run the browser without a visible window.
string | null
Attach to an existing browser session by id instead of starting a new one. For a
user_device browser, the Python SDK sets it for you, so set it yourself only to attach to one served with hai local browser.boolean
default:"false"
Start the browser on the agent’s first browser action instead of when the session starts. Skips the initial observation. See Configuration.
number
default:"1.0"
Seconds the agent waits after each action, so the next observation shows the settled page.
0 to 10.object
default:"{\"type\": \"visual\"}"
How the agent perceives and drives the browser. An object keyed by
type:visual(default):{"type": "visual", "width": 1200, "height": 1200, "markdown": false}. Setmarkdown: trueto include the page’s text alongside the screenshot.text:{"type": "text", "chunk_size": 20000}. Read-only paginated markdown, no screenshots.
string | null
Id of a vault to bind, letting the agent sign in to sites with secrets resolved from it. Must belong to your organization. Cloud browsers only. Omit to run without secret access.
string | null
Id of a browser profile to load, restoring saved cookies and storage so the agent starts already signed in. Must belong to your organization. Cloud browsers only. Omit to start with a fresh profile.
boolean
default:"false"
Load your default browser profile instead of naming one, auto-creating an empty one on first use. Sessions save their final state back automatically (best-effort). Mutually exclusive with
browser_profile_id.boolean
default:"false"
Save the session’s final browser state back into the loaded profile when it ends. Requires
browser_profile_id or use_default_browser_profile. Best-effort: if another session is already persisting the profile, the session starts read-only instead of failing.object | null
Network settings for a newly provisioned browser (ignored when
session_id attaches to an existing one). Set only one of:managed_proxy: H provisions a proxy for browser egress. An object withpool(residential, default, ordatacenter),country(two-letter ISO code, optional), andsticky(keep one exit IP for the session, defaulttrue). Credentials are resolved server-side and never appear in your requests.proxy_url: a bring-your-own HTTP/HTTPS/SOCKS proxy URL, with any credentials inline (e.g.http://user:pass@host:port).
Examples
curl -X POST https://agp.eu.hcompany.ai/api/v2/environments \
-H "Authorization: Bearer $HAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "wide-browser",
"kind": "web",
"start_url": "https://www.google.com",
"mode": {"type": "visual", "width": 1920, "height": 1080}
}'
from hai_agents import Client
client = Client()
environment = client.environments.create_environment(
id="wide-browser",
start_url="https://www.google.com",
mode={"type": "visual", "width": 1920, "height": 1080},
)
print(environment.id)
import { HaiAgentsClient } from "hai-agents";
const client = new HaiAgentsClient();
const environment = await client.environments.createEnvironment({
kind: "web",
id: "wide-browser",
startUrl: "https://www.google.com",
mode: { type: "visual", width: 1920, height: 1080 },
});
console.log(environment.id);
Response
{
"id": "wide-browser",
"kind": "web",
"host": "cloud",
"start_url": "https://www.google.com",
"headless": false,
"session_id": null,
"mode": {"type": "visual", "width": 1920, "height": 1080, "markdown": false},
"lazy": false,
"settle_s": 1.0,
"vault_id": null,
"browser_profile_id": null,
"use_default_browser_profile": false,
"persist_browser_profile": false,
"network": null
}
Errors
| Status | Cause |
|---|---|
403 | Attempted to use the reserved h/ namespace. |
409 | An environment with this id already exists in your catalog. |
422 | Body failed validation. Common cases: invalid id shape, missing required field. |
Was this page helpful?