# Steel Browser Steel Browser runs short-lived browser automation through Cohesivity. Every tenant may provision and use it; Steel Browser does not require an experimental access grant and ignores the internal `offering:browser` policy key if an operator lists that scope. Cohesivity manages the Steel credentials, project organization, and provider connection URLs. The production integration uses Steel.dev's **published Scale plan** without a custom SLA or DPA: **$250/month** with **$100 monthly usage credit**, **$0.08/hour** for browser sessions, **$5 per 1,000** Browser Tool calls, one-hour maximum sessions, and up to 14 days of provider-side data retention. Deployments fail closed with `503 browser_not_configured` unless the required server key and stable ephemeral-admission HMAC secret are present. The current surface includes only **standard datacenter** sessions controlled over CDP and one stateless Browser Tool: scrape. Steel credentials, identifiers, viewers, debug links, and connection URLs stay internal. Tenant responses contain only Cohesivity URLs and safe local session state. ## Prerequisites Edge calls require this resource to be provisioned first; unprovisioned calls return an error. ### Provision curl -s -X POST https://cohesivity.ai/api/resources/steel-browser \ -H "Authorization: Bearer " ### Delete curl -s -X DELETE https://cohesivity.ai/api/resources/steel-browser \ -H "Authorization: Bearer " Provisioning happens once, before the application runs; the running application does not provision its own resources. The canonical provisioning route is `POST https://cohesivity.ai/api/resources/steel-browser`. It returns Cohesivity-owned `edge_url`, `sessions_url`, `tools_url`, and `docs_url` fields under `/edge/steel-browser` and `/offerings/steel-browser`. It never returns a Steel key, project identifier, provider session identifier, viewer, debug URL, or raw provider WebSocket URL. The older `browser` resource name, `/api/resources/browser`, `/edge/browser/*`, and `/offerings/browser` remain compatibility aliases backed by the same internal resource, policy, usage, session, and cleanup state. ## Sessions > **Server-side only.** `coh_application_key` is a secret; browser JS, mobile bundles, and other client-side code cannot hold it safely. This call belongs in a Railway-hosted server, `cloudflare-workers`, or your own server tier. See the canonical key-secrecy directive in `.cohesivity` for details. ### Create curl -s -X POST https://cohesivity.ai/edge/steel-browser/sessions?key= \ -H "Content-Type: application/json" \ -H "Idempotency-Key: browser-session-job-42" \ -d '{"timeout_seconds":900,"inactivity_timeout_seconds":120}' Only `timeout_seconds` and `inactivity_timeout_seconds` are accepted. Both are optional and capped server-side by the tenant plan. `Idempotency-Key` is required and must contain 1–255 visible ASCII characters. Cohesivity stores only its SHA-256 hashed value plus the normalized timeout request; the raw key is never stored, queried, echoed, or logged. Reusing the key with the same request returns the existing safe local projection without another reservation or provider call, including while creation is in progress or after termination. Reusing it with changed fields returns `409`. The maximum requested duration is reserved in whole minutes before a session starts; terminal settlement keeps only actual provider-rounded minutes and returns unused reserved minutes plus the concurrency slot exactly once. ### List and inspect - `GET https://cohesivity.ai/edge/steel-browser/sessions?key=` lists safe local rows owned by the authenticated tenant. - `GET https://cohesivity.ai/edge/steel-browser/sessions/:id?key=` returns one safe local projection. - Neither route performs an organization-wide provider listing. Tenant ownership comes from Cohesivity auth and the local `tenant_id` mapping, never an upstream project or namespace. ### Connect over CDP 1. `POST https://cohesivity.ai/edge/steel-browser/sessions/:id/connect-token?key=`. 2. Connect to the returned Cohesivity URL: `wss://cohesivity.ai/edge/steel-browser/sessions/:id/cdp?token=`. The connect token is tenant-bound, session-bound, **60-second**, and **one-use**. Cohesivity retains at most one live connect token per session: minting another atomically replaces and invalidates the previous row. The WebSocket URL contains no application key. On upgrade Cohesivity consumes the token atomically, re-reads fresh tenant state and local ownership, opens CDP server-side, and relays opaque frames. A server-owned **8 MiB** default message ceiling applies independently in both directions; an oversized message closes both sockets with code `1009` and schedules exact-session release. Close, error, and hard timeout also release and settle the exact session. ### Release `DELETE https://cohesivity.ai/edge/steel-browser/sessions/:id?key=` explicitly releases that one session and is idempotent. Teardown and lifecycle maintenance also release sessions one by one; there is no account-wide release operation. ## Steel Browser scrape > **Server-side only.** `coh_application_key` is a secret; browser JS, mobile bundles, and other client-side code cannot hold it safely. This call belongs in a Railway-hosted server, `cloudflare-workers`, or your own server tier. See the canonical key-secrecy directive in `.cohesivity` for details. - `POST https://cohesivity.ai/edge/steel-browser/tools/scrape?key=` — body `{ "url":"https://example.com", "format":["markdown"], "delay":0 }`. Every scrape reserves one `tool_calls` unit before dispatch and revokes it if the operation or response validation fails. Cohesivity forces standard networking with proxies disabled and sends `screenshot:false` plus `pdf:false`. Syntactic checks reject obvious loopback, private, link-local, metadata, credential-bearing, non-HTTP(S), and IP-literal targets before dispatch. Request streams are read incrementally and canceled as soon as the byte ceiling is crossed, including when `Content-Length` is absent or understated; responses are also size-capped. Identifier/debug/viewer/WebSocket fields are removed from JSON responses. **Hosted artifacts are unavailable:** the upstream convenience screenshot and PDF tools return hosted objects documented as public and durable, while no supported exact-object deletion or retention contract has been verified for those outputs. Their Cohesivity routes return `404 browser_tool_not_found` before quota reservation or provider dispatch. Raw CDP sessions remain available: call `Page.captureScreenshot` or `Page.printToPDF` and receive the bytes directly through the private connection. Convenience screenshot/PDF endpoints remain a follow-up requiring private artifact delivery plus verified upstream deletion/retention semantics. Adding another operator grant around known-public artifacts is not an acceptable substitute. **Network security boundary:** those top-level URL checks are defense in depth, not complete gateway network isolation. Cohesivity does not resolve arbitrary DNS names to prove every destination remains public, detect DNS rebinding, inspect page subresources, or inspect navigation carried in opaque raw CDP frames, and the public provider documentation does not promise those controls. Cohesivity accepts that residual network risk. Tenants are prohibited from targeting private, link-local, or metadata destinations; Cohesivity also retains low fleet/provider-cost ceilings, exact-session cleanup, and an operator kill switch, but those controls do not turn opaque CDP into network enforcement. ## Explicitly unavailable Stateless screenshot/PDF convenience tools, profiles, persisted profiles, auth contexts, cookies supplied as credentials, managed proxies, bring-your-own proxies, CAPTCHA solving, extensions, custom executables, custom launch arguments, files, downloads, download persistence, raw viewers, and premium provider fields are not implemented. Passing an unsupported scrape field returns `400 unsupported_browser_fields`; unavailable tools return `404 browser_tool_not_found`. ## Fluid overflow Claimed accounts may buy overflow in the existing small-block model: **20 browser minutes for $0.05** ($0.15/hour) and **50 browser scrape calls for $0.50** ($0.01/call). Blocks remain under $1. Ephemeral tenants cannot buy overflow. These prices use the public Scale rate of $0.08/browser-hour and $5 per 1,000 scrape calls; the Launch plan's 15-minute maximum does not support the published Plus/Pro surface. ## Fleet guard Database-backed global guards default to 8 active sessions overall, at most 5 ephemeral sessions, 15 browser scrape calls per minute, and a durable **$5 per UTC day** provider-cost safety ceiling at the contracted assumptions above. Session timeout reservations and terminal provider durations are **rounded up to whole provider minutes** before applying the hourly rate, capped by the reserved minute cost; undispatched and confirmed create-not-found paths reconcile to zero. The cost counter reserves atomically before provider dispatch and reconciles failed pre-provider session paths plus terminal session duration; it is an operator kill switch, **not customer billing**. Capacity responses are `429` or `503` with `Retry-After`; Cohesivity never silently overbooks. Fresh ephemeral tenants also pass an atomic abuse admission derived from an opaque HMAC of the stored authoritative genesis IP prefix plus bounded network-origin signals. It allows **one distinct ephemeral Steel Browser tenant** per identity per rolling 24 hours and **three distinct tenants per rolling 30 days**; replay/current-tenant use remains available and claimed accounts are unaffected. Missing origin or HMAC configuration fails closed before usage/provider dispatch. The table stores no additional raw IP, User-Agent, key, or token; its opaque history deliberately **survives tenant and resource teardown** and bounded lifecycle cleanup removes rows after 30 days. ## Rate Limits Ephemeral tenants pause as a whole if any authoritative hard cap below is exceeded. Claimed tiers use account-scoped buckets shared across every project owned by the Cohesivity user; OpenAI, AI Gateway, Deepgram, and Exa are fluid-only after tier, rate, and concurrency checks; AI Gateway and Deepgram have no fixed monthly usage bucket for claimed tiers. **Ephemeral** - browser minutes: 10 per ephemeral tenant lifetime before claim or expiry - browser scrape calls: 3 per ephemeral tenant lifetime before claim or expiry - session starts: 3 per ephemeral tenant lifetime before claim or expiry - concurrent sessions: 1 max at once - session starts: 1 per minute - browser scrape calls: 1 per minute **Claimed Free** - concurrent sessions: 1 max at once - session starts: 2 per minute - browser scrape calls: 2 per minute - session starts: 20 per day - browser minutes: 60 per month - browser scrape calls: 20 per month **Claimed Plus** - concurrent sessions: 2 max at once - session starts: 5 per minute - browser scrape calls: 5 per minute - session starts: 100 per day - browser minutes: 600 per month - browser scrape calls: 200 per month **Claimed Pro** - concurrent sessions: 5 max at once - session starts: 10 per minute - browser scrape calls: 10 per minute - session starts: 500 per day - browser minutes: 3000 per month - browser scrape calls: 1000 per month ### Notes - Steel Browser is available to every tenant and does not require an experimental access grant. It uses Steel.dev's published Scale plan with no custom SLA or DPA; that plan advertises up to 14 days of provider-side data retention. - The provider does not publish an enforceable guarantee against private/link-local/metadata egress across DNS rebinding and subresources. Cohesivity accepts that residual network risk and bounds it with top-level target validation, low fleet and provider-cost ceilings, exact-session cleanup, and an operator kill switch. - The current surface is standard-datacenter CDP sessions plus one-shot scrape. Scrape always sends `screenshot:false` and `pdf:false`; every plan uses the same scrape-only tool surface. - Convenience screenshot/PDF endpoints remain unavailable because their upstream outputs are public and durable and exact deletion/retention semantics are not verified. Use `Page.captureScreenshot` or `Page.printToPDF` over the private CDP connection instead. - A durable provider-cost safety ceiling defaults to $5 per UTC day using Scale assumptions of $0.08/browser-hour, billed by each started minute rounded up, and $5 per 1,000 scrape calls. This is an operator kill switch, not customer billing. - Ephemeral Steel Browser admission allows one distinct tenant per abuse identity per rolling 24 hours and three per rolling 30 days. Only an opaque HMAC identity and tenant id are retained; enforcement history survives tenant/resource teardown for 30 days. Claimed accounts are unaffected. - Profiles, auth contexts, credentials, managed or bring-your-own proxies, CAPTCHA solving, extensions, custom executables or launch arguments, file/download persistence, raw viewers, and provider-specific fields are rejected.