neout/agents API

The identity layer for AI agents. Provision a CDP-attached cloud browser identity in two seconds; drive it with Playwright, Puppeteer, or raw CDP. Or skip the wiring entirely and tell us what to do in plain English — the agent does the rest.

Two modes, one endpoint

  • Burner — ephemeral, 5 min–1 hour TTL, self-destructs, pay-per-call. Best for scrape jobs, one-off automations, and CI runs.
  • Persistent — durable, vault-synced profile (cookies, localStorage, fingerprint), monthly-billed, sessions opened on demand. Best for long-running agents that maintain logged-in state across runs.
Every endpoint lives under https://agents.neout.com. Authenticate with X-API-Key: agt_live_… — mint one in the dashboard.

Quickstart

Three lines to a cloud browser the agent can drive. No infrastructure, no fingerprint tuning, no proxies to wire.

# Provision a burner agent — returns CDP URL you can attach to.
curl https://agents.neout.com/v1/agents \
  -H "X-API-Key: agt_live_…" \
  -H "Content-Type: application/json" \
  -d '{"ttl":"10m","initial_url":"https://example.com"}'

That's it. The agent gets destroyed when the TTL hits zero (or when you DELETE it). You're only charged for the time it was actually running.

Authentication

Every request needs an API key in the X-API-Key header. Keys are minted in the dashboard and look like agt_live_ followed by 24 hex characters.

X-API-Key: agt_live_aabbccddeeff00112233445566778899

Bearer auth is supported too (same key shape) for clients that always set the Authorization header.

Keep keys secret. The raw secret is shown once when minted — we store only sha256(secret). If a key leaks, revoke it from the dashboard and mint a new one.

Agents

An agent is one cloud browser identity. Burner agents run for a short TTL and self-destruct; persistent agents stick around and you open sessions on them as needed.

Provision an agent

POST /v1/agents Returns 201 with CDP URL ready to attach

Mode is auto-detected: if you set persona or warmup_recipe without a TTL, the agent is provisioned persistent. Otherwise it's a burner. Override with explicit mode.

Request body

FieldTypeNotes
ttlstringDuration: "5m", "300s", "1h". Burner only, capped at 1h.
ttl_secondsintegerNumeric alternative to ttl.
modestringburner or persistent.
initial_urlstringURL the browser navigates to on boot.
countrystringISO-2, e.g. "us", "de". Picks the proxy region.
os_typestringOS_TYPE_MACOS, OS_TYPE_WINDOWS.
personastringPersistent mode — freeform label, e.g. "us-shopper-30s".
warmup_recipestringamazon, google, social, or empty.

Response

{
  "id": "agt_aabbccddeeff00112233",
  "status": "running",
  "mode": "burner",
  "cdp_url": "wss://agents.neout.com/api/v1/cdp/<profile>/devtools/browser/<id>",
  "cdp_http": "https://agents.neout.com/api/v1/cdp/<profile>/json",
  "expires_at": "2026-06-06T15:32:00Z",
  "trust_score": 920,
  "cost_credits": 1
}

Get an agent

GET /v1/agents/{id} Latest status + CDP URLs (if running)

Returns the same shape as the create response. status transitions queued → running → destroyed, or failed on a provisioning error.

Destroy an agent

DELETE /v1/agents/{id} Stops the browser, releases credits

Returns 204. Burner agents self-destruct on TTL expiry, so you only need this if you finish early and want to stop the meter.

Get CDP URLs

GET /v1/agents/{id}/cdp For reconnecting after a network blip

Returns cdp_url, cdp_http, profile_id, expires_at. 409 if the agent isn't currently running (destroyed, queued, or failed).

Open a session on a persistent identity

POST /v1/agents/{id}/sessions Persistent agents only

Opens a fresh cloud session against a persistent identity. The profile (cookies, localStorage, fingerprint) is restored from the vault; only the cloud session is new. Charges PersistentSessionCredits.

AI tasks

If you don't want to wire Playwright yourself, hand the task to us as natural language. We provision a burner, point a Claude or GPT agent at it, and return the structured result.

POST /v1/tasks Async — returns a job id
curl https://agents.neout.com/v1/tasks \
  -H "X-API-Key: agt_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "task": "On Amazon, search wireless earbuds under $50, return top 5 ASINs.",
    "llm": "anthropic:claude-haiku-4-5",
    "max_steps": 20,
    "initial_url": "https://www.amazon.com"
  }'

Response is a Job envelope (see Jobs) with kind: "task", plus framework, live_url (noVNC for the running burner), and step_count.

Quick scrape

POST /v1/quick/scrape Markdown + HTML + links in one call

One-call shape for "give me the content of this URL". Pass async=true for a job queue + webhook flow; otherwise the call blocks until the page is rendered (60s cap).

curl https://agents.neout.com/v1/quick/scrape \
  -H "X-API-Key: agt_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://news.ycombinator.com",
    "async": true
  }'

Jobs

Every async call (/v1/tasks, /v1/quick/scrape with async=true, batch, crawl) creates a job that runs in the background. Poll it, or subscribe to job.completed / job.failed webhooks.

Get a job

GET /v1/jobs/{id} Full envelope incl. result

Returns the full Job envelope. statusqueued | running | completed | failed. On completed, the result object is populated with the kind-specific payload. On failed, error_code + error_message describe the failure.

Poll lightweight status

GET /v1/jobs/{id}/status Cheap shape for polling loops

Returns { id, status, kind, progress_done, progress_total } only — no result body. Use when you're polling in a tight loop and don't want to pull the full result every tick.

Cancel a job

POST /v1/jobs/{id}/cancel Cooperative — finishes the current step then stops

The agent stops between steps once it sees the cancel flag. You're billed only for steps actually taken. Returns 409 if the job is already terminal.

Webhooks

Register a callback URL and we'll POST signed JSON every time a job hits a terminal state — no polling required.

POST /v1/webhooks Register a subscription
curl https://agents.neout.com/v1/webhooks \
  -H "X-API-Key: agt_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/hooks/neout",
    "events": ["job.completed", "job.failed"]
  }'

Verify the signature

Every delivery carries an X-Agents-Signature header: an HMAC-SHA256 over the raw request body, keyed by your workspace's signing secret. Fetch the secret with GET /v1/webhooks/signing-secret (or copy it from the dashboard).

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
At-least-once delivery. The same event id may arrive twice (network blips, our retries). Dedupe by storing the id field of each event payload.

Event types

  • agent.provisioned — an agent finished booting and is ready to drive
  • agent.destroyed — TTL expired or DELETE called
  • agent.failed — provisioning failed
  • agent.session.started / agent.session.ended — persistent-mode lifecycle
  • agent.renewed / agent.renewal_failed — monthly billing on persistent agents
  • job.completed / job.failed — async job reached terminal state

Test a delivery

POST /v1/webhooks/{id}/test fires a synthetic agent.provisioned event at the URL so you can verify your handler before relying on it in production.

Credits

GET /v1/credits Current balance + per-unit prices

Returns your current balance in credits, plus the price table for each agent kind (burner, persistent session, task step). Fresh accounts get 100 credits on signup, no card required.

Ledger

GET /v1/credits/ledger Last 100 debits and credits

Returns the recent ledger entries with running balance — what was spent, when, and why. Mirrors the Credits tab.

API keys

Mint, list, and revoke from the dashboard or programmatically.

GET/v1/keysList active keys (no secrets)
POST/v1/keysMint — returns the secret once
DELETE/v1/keys/{id}Revoke immediately
The raw secret is shown exactly once. We store only sha256(secret). If you lose it, revoke + mint a new one.

SDKs

Thin wrappers around the REST API with typed responses, automatic retries on 502/503, and helper methods for the common "connect Playwright over CDP" path.

Python

pip install neout-agents

Source on GitHub: sdks/python-agents

TypeScript / Node

npm i @neout/agents

Source on GitHub: sdks/ts-agents

MCP server

If you're driving the API from an MCP-compatible assistant (Claude Desktop, Cursor, etc.), use the @neout/mcp-agents server — exposes the create/destroy/CDP tools as MCP calls.

Examples

Working scripts on GitHub: services/agents/examples — Amazon SERP, persistent identity with warm-up, webhook receiver.

Errors

All error responses share a single envelope:

{
  "error": "insufficient credit",
  "code": "INSUFFICIENT_CREDIT",
  "request_id": "req_01HQ8Z…"
}
HTTPCodeWhat it means
400BAD_REQUESTValidation failed — check the error field
401UNAUTHORIZED / INVALID_API_KEYKey missing, revoked, or malformed
403FORBIDDENKey exists but lacks permission for this workspace
404NOT_FOUNDResource not in this workspace
402INSUFFICIENT_CREDITTop up at /dashboard/credits
409AGENT_NOT_RUNNINGYou called /cdp on a destroyed agent
429TOO_MANY_REQUESTSPer-key rate limit — respect Retry-After
502UPSTREAM_UNAVAILABLECloud runner unreachable — safe to retry
504UPSTREAM_TIMEOUTProvisioning took too long — retry with longer client timeout
500INTERNAL_ERROROur bug — quote request_id to support

Rate limits

Per API key. Default: 60 requests/min on read endpoints, 20 provisions/min on POST /v1/agents. Need more? Email support@neout.com with your workspace id — lifts are free for production accounts.