Can an AI agent use Steel (steel.dev)?

As of 12 Oct 2026, an AI agent gets into Steel on its own and does 100% of the core work.

Level 4 · Runs on its ownAn agent does the core work and can stop paying on its own.
  • Find: Docs for agents: llms.txt, an OpenAPI and an MCP server; a docs page for each core task.
  • Access: Pay per call, sign-up in a browser.
  • Use: 100% of the work.
  • Pay: Pays per call for part of it: Paid $0.01 a call (x402), 12 Oct.
  • Leave: Nothing to cancel: Deletes its data, but the login stays.

Ways in: Pay per call, 1 of 8 core tasks · Sign-up in a browser, 8 of 8 core tasks

To reach L5 · Autonomous: let an agent buy credits or a plan without a person.

What the levels mean

Driven 12 Oct 2026Same level in 2 drives in a rowRules of 15 Oct 2026Claim this page

Written by our agents from this drive. How we write.

Who gets in

  • Agents on a serverGet in on their own.
  • Signed agentsThe sign-up page opens.
  • Agents in a person's browserNot measured yet.

Sign-up page checked 15 Oct 2026. Signed agents: the ones Cloudflare verifies. Where agents come from

What an agent can do in Steel (steel.dev).

On its own

  • Start a cloud browser session, click around and browse pages, then shut it down
  • Grab a page as a screenshot, a PDF, or clean text with one call
  • Save a login and have it auto-filled and submitted next time
5 more
  • Keep a browser's cookies and sign-in state saved for reuse later
  • Upload and manage files or browser extensions used during a session
  • Watch a session live or review a recording and action log afterward
  • Do all of the above through a command-line tool or the official AI-agent (MCP) connector
  • Pay a tiny per-use fee automatically with no account at all, for basic scraping/screenshots/PDFs

What it can't, and why

  • Sign up and get its first API key without a browsersign-up and key creation only happen in the web dashboard
  • Use CAPTCHA-solving or proxy features on the free trialthose require adding at least $10 of paid balance by card
  • Delete its account so the login itself stops workingdeleting the organization wipes its data but the login still gets a fresh empty one
1 more
  • Revoke its own API key or delete a saved browser profile by itselfboth actions are dashboard-only; no API exists for them
On its own, in a browser

Can an AI agent sign up for Steel on its own?

Yes, in a browser, without a human. Continue with Email on app.steel.dev (no password, a sign-up link by mail), then a 3-step questionnaire; no bot check seen. No sign-up API.

Every way in it offers, as our agent tried them

Ways in
Way inWhat happened
Pay per callGot in, under a minute
Stripe ProjectsNot tried: no account yet
CLI code loginNot reached
Company single sign‑onNot tried: needs a person's account
Official server · its calls worked

Does Steel (steel.dev) have an MCP server, and can an agent connect to it?

Yes. Steel has an official MCP server. The server runs on the agent's own machine, lists 16 tools and speaks the 28 Jul 2026 MCP spec.

A new agent can get in on its own: in the drive of 12 Oct 2026, our agent signed up, verified and got its key without a person. Through the MCP server, 7 of our agent's 7 attempts worked.

What the drive found

APIOpenAPIMCP · officialCLISDKllms.txt–Webhooks–Sandbox
On its own, in a browser

How does an AI agent get a Steel (steel.dev) API key?

In the drive of 12 Oct 2026, our agent got its Steel API key in a browser, without a person. API keys are made in the dashboard. POST /v1/api-keys mints project keys headless, but only with an organization key, which is itself dashboard-only; revoke is dashboard-only.

The login stays

Can an AI agent delete its Steel account?

Not all of it: it deletes its data, but the login stays. Delete organization (hold to delete) removed the org's sessions, profiles, credentials and keys: the project key and org key then answered 401. But the sign-in login (the agent's inbox / the GitHub-linked identity) kept working: it was dropped straight into a freshly created empty org ("Anon's Team"), and the GitHub grant had to be revoked separately on GitHub's side. There is no self-serve user-account delete (Settings > Security is "Page Not Found"); account termination is by request only per the privacy policy. Deleted: org data and keys. Stayed: the user's login.

Pays per call for part of it

Can an AI agent pay for Steel?

Pays per call for part of it: paid $0.01 a call (x402), 12 Oct.

Reached the card form and stopped: Scale, $250 a month.

Checkout: a Stripe card formAn invisible bot check loaded at checkoutWallets: Google Pay, another wallet

Paid on its own: $0.01 in USDC through x402 on Base, 12 Oct 2026. 0xdd2f191a…b03b20

  • Stripe Projects on its own domain
  • x402 on its own domain · Base, Solana

It has a free plan.

What would let agents pay on their own
  1. Sell the plan or credits over the rail, not only side endpoints. Let the paid call buy what the product sells, so the rail covers the whole product.

We paid one x402 v2 call ($0.01 USDC on Base, tx 0xdd2f191a...4b03b20, confirmed, 200 with content): pay-per-call works with no account, but only for scrape, screenshot and PDF. Plans (Scale $250/month) and credit top-ups (from $10) go through a Stripe card form in the dashboard; Stripe Projects is documented but not tried.

Ways to pay checked 12 Oct 2026.

For the team behind Steel.

Where agents stop in Steel (steel.dev) today, and the fixes that get them further, highest impact first.

Wall at delete

The fixes, highest impact first

  1. Let an agent sign up and get a key headlessStep-by-step guide
  2. Let x402 or Stripe Projects fund the wallet
  3. Add DELETE for profiles and API keys
4 more fixes
  1. Let users delete their own account
  2. Make the auth-context round trip lossless
  3. Return 409 on duplicate creates, not 5xx
  4. Update the x402 and forge docs
  • Claim it free and reply next to the result.
  • A Drive, $49: your private report, with where agents stop, the evidence and the fixes that move your level.
  • Fixed something? Order a Drive ($49) any time, or the Monthly drive ($29/month).
See the example report
Details

Your API, MCP server or CLI is the product? An Audit ($299) also checks every documented route, MCP tool and CLI command against your docs. Compare plans.

Already claimed it? Open it in your dashboard.

Rather not be driven? Block AgentDrivesAgent in robots.txt or write to us. We stop driving it ourselves; this page stays, with its date.

Embed the badge on your site

Driven · L4 · Runs on its own badge

Behind the level.

The part scores and the measures behind them.

Part scores and the measures · the docs · level history · paid plans

Part scores

  • Holds up: 84 of 100, fair

Agent-ready setup

  • llms.txt: found
  • OpenAPI: found
  • MCP server: found
  • CLI: found

Not measured in this drive: Docs match (part of an Audit).

The measures

  1. Work done100
  2. Reliability79
  3. Crash test89

The docs

211 of 218 pages read. Complete.

  • A getting-started page
  • An auth page
  • Errors listed with their codes
  • Code examples on most pages
  • Newest page updated 12 Oct 2026
  • A page for 10 of 10 core tasks

Read on 12 Oct 2026.

Tried as documented

15 of 19 documented ways to do the core work worked when tried.

Tried as documented
What happenedWays
Worked when tried15
Documented, didn't work0
Ran, but not read back1
Not tried (a paid plan, or no way to reach it)3
Worked, but not in the docs2

Level history

  1. 5 Oct 2026L4Runs on its own
  2. 12 Oct 2026new driveL5Autonomous
  3. 13 Oct 2026new rulesL4Runs on its own

Needs a paid plan

Not counted in the level. Our drive used free plan (Launch, $30 one-time credits).

Needs a paid plan
CapabilityPlan
Auto-solve CAPTCHAsLaunch with $10+ paid balance, or Scale
Residential proxies with geo targetingLaunch with $10+ paid balance, or Scale
Dedicated static IPScale ($5/IP)
How Steel handles an agent's mistakes · 10 probes · core run 3×

Malformed requests, a retry, a wrong key and a short burst of reads on our agent's own account, and how Steel answered.

  1. Clear errors79
  2. Recovery89
  3. Safe retries100

400/401/404 answers name the fix and link the docs; duplicate creates answer 500 or 504 instead of 409 (no duplicates made), and a missing route answers 421 text/plain. 15 quick reads all passed (limit 60/min).

  • Vaguerepeat a createStore and auto-inject login credentials (incl. TOTP) into a session201 then 500 {"message": "Steel hit an unexpected server error while processing this request. Retry shortly; if it persists, contact support with the request details.", "error": "Internal Server Error
  • Vaguerepeat create with the same custom sessionIdCreate a cloud browser session201, then 504 "error code: 504" (text/plain, after a long wait); the session itself was not duplicated
  • Clearmissing required urlScrape a page to HTML/markdown without managing a session400 {"message": "url must be a valid URL including the scheme, e.g. https://example.com.", "error": "Bad Request"}
  • Clearbad enum valueCreate a cloud browser session400 {"message": "device is not one of the supported values. Use one of the documented values and retry.", "error": "Bad Request"}
  • Clearunknown id in own namespaceCreate a cloud browser session404 {"message": "Session not found. It may have ended, expired, or belong to a different organization. Check the session id, or list your sessions to confirm it exists.", "error": "Not Found", "linkTo
  • Clearrelease unknown sessionRelease/stop a browser session404 {"message": "Session not found"}
  • Clearwrong API keyCreate a cloud browser session401 {"error": "Unauthorized", "message": "Invalid Steel API key. The key sent in the 'steel-api-key' header does not match any account. Create or rotate a key at https://app.steel.dev/settings/api-key
  • Clearburst of 15 GET /v1/sessionsCreate a cloud browser session15 x 200; no rate-limit headers on GET (X-RateLimit-Limit 60 / Remaining / Reset seen earlier on a POST /v1/sessions 403); plan limit 60 requests per minute
  • Clearinterrupt a persistProfile session right after createPersist and reuse a browser profile (cookies, auth, extensions, settings) across sessionssession released; its profile ec9e9236 still reaches READY (consistent, no half state)
  • Clearrevoked keyCreate a cloud browser session401 {"error": "Unauthorized", "message": "Invalid Steel API key. The key sent in the 'steel-api-key' header does not match any account. Create or rotate a key at https://app.steel.dev/settings/api-key

For agents and builders.

The drive as data, every checkpoint and all 110 attempts.

How an agent connects · 7 tips
  • Send the key in the steel-api-key header, not Authorization: Bearer
  • Retry GET /v1/sessions/{id} once if it 404s right after create
  • Use --json on every CLI command; forge templates are playwright-ts, playwright-py, ...
  • Profile PATCH must be multipart/form-data
  • When reusing GET /context, rewrite localStorage keys to https://origin
  • The MCP server refuses a fresh session when saved profiles exist: pass guest=true or a profile_id
  • The dashboard shows a new key once; copy it in the same step
Every checkpoint, in detail · 9 checkpoints
  1. DocsHeadlessllms.txt with agent instructions, every page as .md and via Accept: text/markdown, OpenAPI 3.0.3 found through /.well-known/api-catalog.
  2. Sign upIn a browserContinue with Email on app.steel.dev (no password, a sign-up link by mail), then a 3-step questionnaire; no bot check seen. No sign-up API.
  3. VerifyIn a browserThe sign-up link arrived in under a minute and was opened in the browser; it lasts 10 minutes.
  4. KeyIn a browserAPI keys are made in the dashboard. POST /v1/api-keys mints project keys headless, but only with an organization key, which is itself dashboard-only; revoke is dashboard-only.
  5. First callHeadlessGET /v1/sessions with the steel-api-key header -> 200.
  6. First actionHeadlessCreated a cloud browser session with the Node SDK, drove it over CDP with Playwright and released it.
  7. PayHeadlessWe paid one x402 v2 call ($0.01 USDC on Base, tx 0xdd2f191a...4b03b20, confirmed, 200 with content): pay-per-call works with no account, but only for scrape, screenshot and PDF. Plans (Scale $250/month) and credit top-ups (from $10) go through a Stripe card form in the dashboard; Stripe Projects is documented but not tried.
  8. CancelNot neededNothing to cancel: our agent used it pay-per-call.
  9. DeleteBlockedDelete organization (hold to delete) removed the org's sessions, profiles, credentials and keys: the project key and org key then answered 401. But the sign-in login (the agent's inbox / the GitHub-linked identity) kept working: it was dropped straight into a freshly created empty org ("Anon's Team"), and the GitHub grant had to be revoked separately on GitHub's side. There is no self-serve user-account delete (Settings > Security is "Page Not Found"); account termination is by request only per the privacy policy. Deleted: org data and keys. Stayed: the user's login.
The attempt log · 110 attempts
Attempt log
CapabilityRouteResultEvidence
Docs: Read llms.txt, auth, CLI, x402 docsapidone ✓docs.steel.dev/llms.txt 200 (29 KB, Agent Instructions section); /overview/authentication.md, /integrations/x402.md, /overview/steel-cli.md all 200 text/markdown
OpenAPI: Find OpenAPI via api-catalogapidone ✓docs.steel.dev/.well-known/api-catalog (RFC 9727 linkset) -> https://api.steel.dev/sdk-openapi.json, openapi 3.0.3, 75 operations incl. POST /v1/api-keys
Markdown docs: Accept: text/markdown and .md URLapidone ✓GET docs page with Accept: text/markdown -> 200 text/markdown, Vary lacks Accept (rsc, next-router-*); .md URL -> 200 text/markdown
Well-known cards: ai-catalog, agent-card, agent.json, mcp server-card, oauth PRM/AS, ucp, auth.md, SKILL.md on steel.dev and docs.steel.devapidone ✓all 404 text/html on steel.dev and docs.steel.dev; api.steel.dev answers 421 for those paths
robots/aipref: robots.txt Content-Usage and Content-Usage headerapidone ✓steel.dev/robots.txt: "User-Agent: * / Allow: /" + Sitemap; no Content-Usage or Content-signal lines; no Content-Usage response header
MCP: Find MCP serverapidone ✓github.com/steel-dev/steel-mcp-server v3.0.0 (official, stdio via npx github:steel-dev/steel-mcp-server; README: "mcp.steel.dev is not live yet"); mcp.steel.dev no answer (000)
API auth error: Unauthenticated GET /v1/sessionsapidone ✓401 application/json {"error":"Unauthorized","message":"Missing API key. Authenticate by sending your Steel API key in the 'steel-api-key' header (Steel does not use 'Authorization: Bearer'). Create or rotate a key at https://app.steel.dev/settings/api-keys."}
Sign up: Sign up at app.steel.dev with Continue with Emailbrowserdone ✓app.steel.dev/sign-up -> sign-in page with GitHub/Google/Email; email the agent's inbox accepted, "Email Sent. Check your Inbox"; no CAPTCHA seen (Clerk at clerk.steel.dev)
Verify email: Open the sign-up link from the mailbrowserdone ✓mail "Your sign up link" from notifications@steel.dev arrived in <1 min; link (clerk.steel.dev/v1/verify, 10 min expiry) opened in browser -> /questionnaire -> /quickstart, wallet shows $30.00
API key: Create API key in dashboardbrowserdone ✓quickstart "Generate API Key" made an Onboarding key; Settings > API Keys > Create API key (project key "agentdrives-main") shown once
First API call: GET /v1/sessions with the keyapidone ✓200 {"sessions":[],"nextCursor":null}
Create a cloud browser session: client.sessions.create then retrievesdkdone ✓session 26630c5f-... created (SDK 0.18.0); GET /v1/sessions lists it status live
Create a cloud browser session: retrieve right after createsdkfailedGET /v1/sessions/26630c5f-... immediately after create -> 404 "Session not found. It may have ended, expired, or belong to a different organization..."; the list a minute later shows it live
Drive the session over CDP: Playwright connectOverCDP, goto example.com, click linkapifailednot reached: the script stopped on the 404 read before connecting (first attempt)
Release a session: release the session left live by the failed runapidone ✓POST /v1/sessions/26630c5f-.../release -> 200; GET -> status released
Create a cloud browser session: SDK create, retrieve, Playwright CDP drive, releasesdkdone ✓retry after the failed first run: session 81a95273 created in 840 ms, status live, websocketUrl set
Create a cloud browser session: SDK create, retrieve, Playwright CDP drive, releasesdkdone ✓GET right after create: status live, websocketUrl present
Drive the session over CDP: SDK create, retrieve, Playwright CDP drive, releasesdkdone ✓page.goto example.com -> url https://example.com/ title "Example Domain"; clicked link -> https://www.iana.org/help/example-domains "Example Domains"
Release a session: SDK create, retrieve, Playwright CDP drive, releasesdkdone ✓sessions.release -> success true; GET -> status released
First action: Create a browser session and drive itsdkdone ✓session 81a95273 created live, driven to example.com and released (see ..03)
: SDK session chainsdkdone ✓session a85d34cb live in 984 ms
: SDK session chainsdkdone ✓GET right after create: live
: SDK session chainsdkdone ✓goto example.com, click -> iana.org/help/example-domains
: SDK session chainsdkdone ✓release success; GET status released
Create a cloud browser session: update a sessionapiskippedOpenAPI has no update operation for sessions (create, get, list, release, release-all only)
Scrape a page: POST /v1/scrape example.com markdown+htmlapidone ✓200; content.html has <title>Example Domain</title>; content.markdown starts "This domain is for use in documentation examples..."; metadata.statusCode 200
Screenshot: POST /v1/screenshot example.com fullPageapidone ✓200 {"url":"https://images.steel.dev/v1/static/....png"}; download 200 image/png, 125 KB, 1911x988, shows the example.com text
PDF: POST /v1/pdf example.comapidone ✓200 {"url":"https://files.steel.dev/v1/static/....pdf"}; download 200 application/pdf, %PDF-1.4, 101 KB
Scrape a page: scrape https://www.iana.org/help/example-domainsapidone ✓200; markdown 851 chars; title Example Domains
Screenshot: screenshot https://www.iana.org/help/example-domainsapidone ✓200; download 200 196693
PDF: pdf https://www.iana.org/help/example-domainsapidone ✓200; download 200 124748 application/pdf
Scrape a page: scrape https://example.orgapidone ✓200; markdown 957 chars; title Example Domain
Screenshot: screenshot https://example.orgapidone ✓200; download 200 125077
PDF: pdf https://example.orgapidone ✓200; download 200 101231 application/pdf
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓POST /v1/credentials 201 {namespace ad-t1, origin https://agentdrives.com, label ...} (value not echoed)
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓GET /v1/credentials?namespace=ad-t1 200 lists it, no secret values returned
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓PUT /v1/credentials label -> "AgentDrives test login v2", 200, updatedAt changed; list shows v2
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓session namespace ad-t1 credentials {autoSubmit:true}: goto https://agentdrives.com/login -> form filled and submitted by Steel, our route got POST with email+password, page ended on /dashboard "Signed in"
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓DELETE /v1/credentials {origin, namespace} -> 200; list -> {'credentials': []}
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapidone ✓trial 2: create 201; session ended on https://agentdrives.com/dashboard dash=True; delete 200; list after {'credentials': []}
Store and auto-inject credentials: store a login for https://agentdrives.com (our own origin, page served by our script), inject into a sessionapifailedtrial 3: create 500; session ended on https://agentdrives.com/dashboard dash=True; delete 200; list after {'credentials': []}
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapidone ✓session persistProfile:true -> profileId e6282f95; cookie ad_session + localStorage set on https://agentdrives.com; after release profile status READY
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapidone ✓GET /v1/profiles/{id} 200 status READY, sourceSessionId, userAgent; GET /v1/profiles lists it
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapidone ✓PATCH /v1/profiles/{id} JSON {userAgent} -> 400 "Profile updates must be sent as multipart/form-data..."; same field as multipart -> 200, GET shows the new userAgent
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapidone ✓new session with profileId e6282f95: cookie ad_session=v1be694a1 and localStorage ad_ls=v1be694a1 present without setting them again
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapifailedDELETE /v1/profiles/{id} -> 421 "No route defined for DELETE /v1/profiles/..."; OpenAPI has no profile delete; docs: "If a profile is not used after 30 days, it will be automatically deleted"; profile still listed
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapidone ✓trial 2: profile 0fc4941e status READY; new session saw cookies ['ad_session=v483c45cd'] ls v483c45cd
Persist and reuse a browser profile: persist a profile with a cookie+localStorage on our own origin, reuse it in a new sessionapifailedtrial 3: profile 94c4028f status READY; new session saw cookies [] ls vcbfd2eb7
Auto-solve CAPTCHAs: POST /v1/sessions {solveCaptcha:true}apiplan_gated403 {"message":"Launch requires at least $10 in paid balance to use CAPTCHA solving or Steel proxies. Add credits, bring your own proxy via 'proxyUrl', or upgrade to Scale.","error":"Forbidden","linkToDocs":"https://docs.steel.dev/overview/pricinglimits"}
Residential proxies with geo targeting: session useProxy {geolocation:{country:'US'}}, check egress IPsdkplan_gated403 {"message":"Launch requires at least $10 in paid balance to use CAPTCHA solving or Steel proxies. Add credits, bring your own proxy via 'proxyUrl', or upgrade to Scale.","error":"Forbidden","linkToDocs":"https://docs.steel.dev/overview/pricinglimits"}; baseline session without proxy egress IP 216.246.40.62 (api.ipify.org)
Stealth mode: POST /v1/sessions {stealthConfig:{humanizeInteractions:true}}apipartial201 session 942e55c7 live; released 200
Scoped key headless: POST /v1/api-keys with the project key, then with an organization keyapidone ✓project key -> 403 {"message":"API keys cannot manage API keys"}; organization key (made once in the dashboard) + projectId -> 201 {id, key ste-••••, scopeType project, projectId}
Scoped key headless: GET /v1/sessions with the new project keyapidone ✓200
Docs claim: Scrape a page to HTML/markdown without managing a session: steel scrape <url>clidone ✓steel 0.4.4 --json: data.content.markdown has the example.com text
Docs claim: Capture a screenshot of a page: steel screenshot <url> --full-pageclidone ✓success true, data.url images.steel.dev/...png
Docs claim: Generate a PDF of a page: steel pdf <url>clidone ✓success true, data.url files.steel.dev/...pdf
Docs claim: Create a cloud browser session: steel browser startclidone ✓session 54f0d6bb live, named ad-cli; steel browser sessions lists it
Docs claim: Drive the session with Playwright/Puppeteer/Selenium over CDP: steel browser open/click/fill/typeclidone ✓open https://example.com -> title Example Domain; snapshot -i -> link "Learn more" [ref=e1]
Docs claim: Release/stop a browser session: steel browser stopclidone ✓stoppedSessions ["ad-cli"]
Docs claim: Persist and reuse a browser profile (cookies, auth, extensions, settings) across sessions: steel profile import/sync/list/deleteclipartialprofile list returns [] while GET /v1/profiles lists 3 API profiles; the CLI manages named profiles imported from a local browser, and delete takes a name, so API profiles cannot be deleted from the CLI
Docs claim: Store and auto-inject login credentials (incl. TOTP) into a session: steel credentials create/list/update/deleteclidone ✓credentials list --json -> {"data":[],"success":true} (matches API after our deletes)
Docs claim: Auto-solve CAPTCHAs encountered during a session: steel browser captcha solvecliplan_gatedsolving needs $10 paid balance (API 403 on solveCaptcha)
Docs claim: Create a cloud browser session: POST /v1/sessionsapidone ✓201 live
Docs claim: Drive the session with Playwright/Puppeteer/Selenium over CDP: wss://connect.steel.dev?apiKey=&sessionId=apidone ✓Playwright connectOverCDP drove example.com
Docs claim: Release/stop a browser session: POST /v1/sessions/{id}/releaseapidone ✓status released
Docs claim: Scrape a page to HTML/markdown without managing a session: POST /v1/scrapeapidone ✓200 html+markdown
Docs claim: Capture a screenshot of a page: POST /v1/screenshotapidone ✓200 url to image (JPEG bytes served as image/png)
Docs claim: Generate a PDF of a page: POST /v1/pdfapidone ✓200 url to %PDF-1.4
Docs claim: Auto-solve CAPTCHAs encountered during a session: POST /v1/sessions {solveCaptcha: true}; GET captchas/status; POST captchas/solveapiplan_gated403 needs $10 paid balance
Docs claim: Route session traffic through residential or custom proxies with geo targeting: POST /v1/sessions {useProxy: {...}}apiplan_gated403 needs $10 paid balance
Docs claim: Persist and reuse a browser profile (cookies, auth, extensions, settings) across sessions: POST /v1/sessions {persistProfile}; POST/PATCH /v1/profilesapidone ✓persist+reuse works; PATCH only multipart; no DELETE
Docs claim: Store and auto-inject login credentials (incl. TOTP) into a session: POST /v1/credentials; POST /v1/sessions {credentials: {}}apidone ✓injected and auto-submitted on our own origin
Scaffold a project from a template: steel forge playwright --name ad-botclidone ✓"steel forge playwright" -> {"error":"Template not found: playwright"}; forge --list shows slug playwright-ts; "steel forge playwright-ts --name ad-bot" made ad-bot/ with index.ts, package.json, tsconfig.json, README.md
Install coding-agent skills: steel skills listclidone ✓skills list --json: steel-browser, steel-developer, ... (ga, 0.1.0, installed false); install goes through npx skills into agent client dirs: not installed (would write outside the run dir)
Self-host the browser runtime: steel dev install / Docker imagenoneskippeddocs: /overview/self-hosting/docker, railway, clustering; CLI steel dev install/start
Session files: upload, list, download, delete a file in a live sessionapidone ✓POST /v1/sessions/{id}/files multipart -> 201 /files/ad-test.txt 30 B; GET list shows it; download returns our text; DELETE 204; list -> []
Global files: upload, list, download, delete an org fileapidone ✓POST /v1/files -> 201 agentdrives/ad-test.txt; list shows it; download matches; DELETE /v1/files/agentdrives%2Fad-test.txt 204; list -> []
Extensions: upload our own MV3 zip, start a session with it, check its content script ran, deleteapidone ✓POST /v1/extensions 201 id ibeilnpl...; GET lists it; session extensionIds -> example.com has data-agentdrives="loaded"; DELETE 200 "Extension deleted successfully"; list count 0
Agent traces: GET agent-traces, agent-logs, logs of a finished sessionapidone ✓GET /v1/sessions/76a0d344/agent-traces 200 events navigate about:blank -> example.com ...; agent-logs 200; logs 200; cost 200 totalCost 0.001667 usd
Replay a past session: GET /v1/sessions/{id}/hls of a released sessionapidone ✓200 #EXTM3U playlist with init.mp4 on fly.storage.tigris.dev (signed URLs); GET /events returned [] for the same session
Mobile mode: session deviceConfig {device:'mobile'}, read navigator on example.comapipartial ✓session dimensions 508x1074; UA "Mozilla/5.0 (Linux; Android 16; CPH2801) ... Mobile Safari"; innerWidth 500; but navigator.maxTouchPoints 0, userAgentData.mobile false, screen 1920x1080
Fullscreen 1920x1080: session fullscreen:trueapidone ✓innerWidth x innerHeight 1920x1080 = screen 1920x1080 (no browser chrome)
Reuse auth context: GET /v1/sessions/{id}/context from a live session, pass it as sessionContext to a new oneapipartial ✓context 200 {cookies:[], localStorage:{"example.com":{"ad_ctx":...}}}; passed back as-is -> new session localStorage null; same value keyed "https://example.com" -> restored
Dedicated static IP: check docs/plannoneplan_gatedllms.txt pricing: "dedicated IPs at $5 each" on paid plans; map plan paid; free Launch plan has no paid balance
Watch a session live: open the session page of a live session in the dashboardbrowserdone ✓app.steel.dev/sessions/02f6726c: "Live" badge, live frame of example.com, event list (Navigation about:blank -> https://example.com/), cost 0.0016; CLI steel browser live returned the same URL
Human takes control: open the debugUrl player, click to interact, send keysbrowserdone ✓api.steel.dev/v1/sessions/{id}/player: "Click to interact"; our click+Tab+Enter reached the remote Chrome (its screen shows "Bookmark added" on example.com)
Walk to the last click: Plans > Upgrade to Scale ($250/month + usage)browserdone ✓Settings > Plans: Launch $0 + usage (current, $30 one-time credits), Scale $250 + usage, Enterprise Contact Sales; Upgrade to Scale opens "Add payment method" (Stripe Payment Element in-page: Card, Cash App Pay, US bank account; Google Pay frame); Card form: number, MM/YY, CVC, Country (Germany preset), no phone field; invisible hCaptcha frame from Stripe (HCaptchaInvisible); last button "Save payment method"; stopped there, no card typed
Agent rail: read pay_probe.json and pay_tx.jsonapidone ✓x402.steel.dev/v1/scrape 402 PAYMENT-REQUIRED x402 v2, exact, Base eip155:8453 + Solana, 10000 USDC units ($0.01), resource api.paysponge.com/v1/scrape; we paid once: tx 0xdd2f191a...b20 on Base, confirmed block 52525353, 200 with example.com html (entitled)
View usage and balance: Settings > Usage and Walletbrowserdone ✓Usage: last 24h spend $0.04, sessions 36, browser minutes 10, proxy 0.00 GB, captcha solves 0, scrapes 4, hourly table, Export as CSV; header balance $29.96 of $30
Top up credits: Wallet > Buy creditsbrowserskippedBuy credits dialog: $50 / $250 / $1,000 / Other, "Minimum purchase is $10. Usage purchases expire 1 year after purchase.", button "Continue to pay $50.00"; not clicked (no paying in a drive); auto top-up under "Configure"
MCP version: stdio server/discover with MCP-Protocol-Version 2026-07-28, then initializemcpdone ✓server/discover -> result.supportedVersions ["2026-07-28"], capabilities tools/resources, extension io.modelcontextprotocol/ui; initialize offering 2026-07-28 -> protocolVersion "2025-11-25", serverInfo steel / Steel Browser 3.0.0; tools/list 16 tools
Scrape a page: MCP steel_scrape example.commcpdone ✓tools/call steel_scrape -> "Read https://example.com/ (HTTP 200)" with the page text wrapped in <untrusted-page-content>
Create a cloud browser session: MCP steel_session_create, navigate, releasemcpdone ✓first call refused: "Saved profiles are available, so a fresh guest browser was not created. Choose one READY profile_id and retry, or pass guest=true"; with guest:true -> session_id sess_CVUH..., viewer 62ce5886; steel_navigate final_url https://example.com/ navigated true; steel_session_release released true; GET /v1/sessions/62ce5886 -> released
Docs claim: Scrape a page to HTML/markdown without managing a session: steel_scrapemcpdone ✓HTTP 200 read of example.com
Docs claim: Create a cloud browser session: steel_session_createmcpdone ✓needs guest=true when the org has saved profiles
Docs claim: Drive the session with Playwright/Puppeteer/Selenium over CDP: steel_navigate / steel_actmcpdone ✓steel_navigate final_url example.com
Docs claim: Release/stop a browser session: steel_session_releasemcpdone ✓released true; API shows released
First API call: GET /v1/sessions with the GitHub account keyapidone ✓200 {'sessions': [], 'nextCursor': None}
First action: POST /v1/scrape example.comapidone ✓200 title Example Domain
Keyless x402: pay one scrape call on x402.steel.devapidone ✓pay_tx.json: POST https://x402.steel.dev/v1/scrape, x402 v2 exact on Base, $0.01 USDC, tx 0xdd2f191a...4b03b20 confirmed block 52525353, HTTP 200 with example.com html
Stripe Projects: stripe projects add steel/browsercliskippeddocumented at docs.steel.dev/overview/stripe-projects; listed in the projects.dev catalog
Enterprise SSOnoneskippedllms.txt: Enterprise "SSO + HIPAA-ready BAA" (Contact Sales)
CLI login: steel login (CLI 0.4.4) with the magic-link accountcliskippedsteel login prints https://app.steel.dev/sign-in?cli_redirect=true&port=<random>&state=•••• and waits on a localhost callback; opened in our logged-in browser, the redirect to localhost:<port> got ERR_CONNECTION_REFUSED
: SDK session chainsdkdone ✓session 6f6352e2 live in 1023 ms
: SDK session chainsdkdone ✓GET right after create: {'status': 'live', 'websocketUrl': True} read_errors None
: SDK session chainsdkdone ✓goto example.com -> {'url': 'https://example.com/', 'title': 'Example Domain'}; click -> {'url': 'https://www.iana.org/help/example-domains', 'title': 'Example Domains'}
: SDK session chainsdkdone ✓release {'success': True}; GET {'status': 'released', 'duration': 0}
Cancel plan: cancel/downgradenoneskippedno plan or trial started (Launch is $0 + usage; Scale $250/month needs a payment method). Docs (llms-full.txt) have no page on cancelling or downgrading; the dashboard has Plans and a "Manage billing" button (Stripe portal, not opened)
Scoped key headless: revoke the API-made keybrowserdone ✓Settings > API Keys > Delete agentdrives-headless key > "This permanently revokes agentdrives-headless" > Yes, delete; the key then -> 401 {'error': 'Unauthorized', 'message': "Invalid Steel API key. The key sent in the 'steel-api-key' hea
Revoke GitHub grant: GitHub Settings > Applications > Steel.dev > Revoke accessbrowserdone ✓"Steel.dev has been revoked from your account."; Authorized OAuth Apps: "No authorized OAuth Apps"

Also in Browser infrastructure.