Skip to main content
A browser profile captures a browser’s saved state (cookies, local storage, and session data) as a reusable, organization-scoped bundle. Upload one once, then set browser_profile_id so the agent starts a session already authenticated instead of signing in from scratch every run. Where a vault injects individual secrets at the moment the agent fills a login form, a profile restores the entire logged-in state up front. Reach for a vault when the agent should sign in with credentials; reach for a profile to carry an existing, already-authenticated session forward. Profiles belong to your organization: any agent in the org can load one, and they persist across sessions until you delete them.

Uploading a profile

The archive is a .zip of a browser’s user-data directory — for Chrome, ~/Library/Application Support/Google/Chrome (macOS) or ~/.config/google-chrome (Linux). It can hold cookies and saved logins, so treat it as a secret. A profile archive can be large, so the bytes are uploaded directly to object storage through a presigned URL and never pass through the Agent API. The flow is three steps:
1

Initiate the upload

Call POST /initiate-upload. It returns a profile_id, a presigned upload_url, and the upload_fields you must include with the upload.
INIT=$(curl -s -X POST https://agp.eu.hcompany.ai/api/v2/browser-profiles/initiate-upload \
  -H "Authorization: Bearer $HAI_API_KEY")
PROFILE_ID=$(echo "$INIT" | jq -r .profile_id)
UPLOAD_URL=$(echo "$INIT" | jq -r .upload_url)
2

Upload the archive to storage

POST your profile .zip to upload_url as multipart/form-data, including every entry from upload_fields. This request goes to object storage, not to the Agent API. The archive must be application/zip and at most 1 GB; storage rejects anything else.
# Forward every upload_fields entry. Build one --form-string per field
# (not -F): some values, like `tagging`, start with "<".
args=()
while IFS= read -r line; do
  args+=(--form-string "$line")
done < <(echo "$INIT" | jq -r '.upload_fields | to_entries[] | "\(.key)=\(.value)"')

curl -s -X POST "$UPLOAD_URL" "${args[@]}" -F "file=@profile.zip"
The presigned upload_url and upload_fields are passed through to object storage exactly as returned, so do not modify them. They expire after upload_expires_in seconds, so upload promptly after initiating.
3

Complete the upload

Call POST /{profile_id}/complete-upload with the profile metadata (name, browser_name, browser_version) within 1 day of uploading. The platform verifies the uploaded archive and creates the profile record. Until you complete it, the upload is held as pending and is deleted automatically after 1 day.
curl -X POST "https://agp.eu.hcompany.ai/api/v2/browser-profiles/$PROFILE_ID/complete-upload" \
  -H "Authorization: Bearer $HAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "acme-prod-login", "browser_name": "chromium", "browser_version": "131"}'
Once created, manage your profiles with the browser profile endpoints: list, retrieve, and delete them.