Web automation API
Automate any website.Even behind a login.
Sign-ins, forms, downloads, data. Build the task once: in the visual builder, with your coding agent, or as JSON. Kaabist runs it and keeps it working when the site changes.
claude mcp add --transport http kaab https://mcp.kaab.ist/mcpyou asked
Every Monday, sign in to our supplier portal and bring me the new invoices.
kaabist runs it
- open portal.example.com
- sign in as [email protected]
- 2FA code asked · link emailed to you
- you typed the code · run continues
- open Invoices · 3 new
you get
[
{ "invoice": "INV-1042", "total": "€1,240.00" },
{ "invoice": "INV-1043", "total": "€318.50" },
{ "invoice": "INV-1044", "total": "€2,075.00" }
]How it works
Build it once.Your way.
Click through the site in the builder, ask your coding agent, or write the JSON. Every way makes the same program: versioned, tested, ready to run.
- supplier-invoicessteps ⇄ jsondraft · v1
portal.example.com/login
EmailPasswordSign inInvoices
- INV-1042€1,240.00
- INV-1043€318.50
- INV-1044€2,075.00
select similar · 3 rows- gotoportal.example.com
- fillEmail ← inputs.email
- fillPassword ← secret input
- clickSign in
- await_inputone-time code
- extractinvoices[] · 3 fields
{ "goto": "https://portal…" },{ "fill": { "role": "textbox","name": "Email" },"value": "{{inputs.email}}" },{ "fill": "#password","value": "{{inputs.password}}" },{ "click": { "role": "button","name": "Sign in" } },{ "await_input": "otp" },{ "extract": { "invoices": {"selector": "tbody tr","many": true, … } } }✓ lint · 0 errors✓ dry run · 3 invoices✓ published supplier-invoices@1[{ "invoice": "INV-1042", "total": 1240, "currency": "EUR" }, { "invoice": "INV-1043", "total": 318.5, "currency": "EUR" }, …]Record the task in a live Kaabist browser, pick the data you want, and edit the steps and the JSON side by side. Test each step before you publish.
claude · ~/ops
› get the new invoices from our supplier portal every Mondaykaab · browser_open portal.example.comkaab · await_input otp → you get a linkkaab · try_extract → 3 rowskaab · test_program ✓ dry run✓ supplier-invoices@1Claude Code, Codex or Cursor drives a real Kaabist browser over MCP and saves what it did.
~/ops — zsh
$ kaab programs pull supplier-invoicesedit supplier-invoices.json$ kaab programs lint supplier-invoices.json✓ 0 errors$ kaab programs push supplier-invoices.json✓ supplier-invoices@1A program is a file. Keep it in git, lint and push it with the CLI, or send it to the API.
One program, whichever way you build it: supplier-invoices@1
01
Runs when you need it
On a schedule, from an API call, or as a batch of up to 1,000. Results reach your app as JSON or a signed webhook.
02
Waits for you when it must
A 2FA code pauses the run. You get a link, type the code, and it picks up where it stopped.
03
Keeps working
When the site changes, Kaabist finds the moved element and asks you to approve the fix.
Why it doesn’t break
Sites change.Your automation doesn’t.
- 01
Waits for your 2FA code
The site asks for a code? You get a link, type it, and the run picks up where it paused.
- 02
Fixes itself
A button moved? Kaabist finds it again and asks you to approve the fix.
- 03
Never submits twice
A crash halfway through a payment never pays twice. You decide what happens.
- 04
Built your way
In the visual builder, by your coding agent, or as JSON. The same program, the same guarantees.
- 05
Finds the hidden API
Spots the JSON behind the page and skips the browser next time. Faster, cheaper.
- 06
Stays signed in
Logs in once, runs on a schedule, and tells you only when something changed.
With your coding agent
One line to connect.Your agent does the rest.
$ claude mcp add --transport http kaab https://mcp.kaab.ist/mcpAdded HTTP MCP server kaab$ claude "renew my subscription on portal.example.test every month"› browser_open https://portal.example.test/login› browser_fill #email, #password› await_input otp you type the code from a link› browser_click Renew marked side_effect: true› test_program dry_run stops before the first side effect✓ program prg_4Rb · v1 saved · schedule: monthly
The portal redirects to /login; the form has email and password fields.
Sign in is a button with an accessible name, so I target it by role.
After sign in the site asks for a one-time code sent by e-mail.
I cannot read that inbox, so the step becomes await_input otp.
You get an emailed link to type the code; the job waits until you do.
I add a checkpoint after login, so a retry does not log in again.
Renew changes the subscription: side_effect true, never retried blindly.
A dry run stops before Renew; every locator resolved uniquely.
Done. The program logs in, waits for your one-time code on a hosted page, and renews exactly once.
Or call it yourself
Any URL in.Clean JSON out.
import { Kaab } from "@kaabist/sdk";
const kaab = new Kaab(); // KAAB_API_KEY
const job = await kaab.jobs.create({
url: "https://shop.example.test/p/1",
extract: { title: "h1", price: { selector: ".price", type: "money" } },
wait: 30,
});
console.log(job.data);from kaabist import Kaab
with Kaab() as kaab: # KAAB_API_KEY
job = kaab.jobs.create(
url="https://shop.example.test/p/1",
extract={"title": "h1", "price": {"selector": ".price", "type": "money"}},
wait=30,
)
print(job.data)c := kaab.New("") // KAAB_API_KEY
body, _ := kaab.Body[client.CreateJobJSONBody](map[string]any{
"url": "https://shop.example.test/p/1",
"extract": map[string]any{"title": "h1"},
})
job, _ := c.Jobs.Create(ctx, body, kaab.WithWait(30))
fmt.Println(*job.Data)curl https://api.kaab.ist/v1/jobs \
-H "Authorization: Bearer $KAAB_API_KEY" \
-H "Prefer: wait=30" \
-d '{"url":"https://shop.example.test/p/1","extract":{"title":"h1"}}'Also included
Everything elseyou would build yourself.
Signed webhooks
Every result reaches your server, retried until it lands.
Watch a run live and step in when you want.
Typed data
Prices, dates and links come back parsed and checked, with a warning when a value looks wrong.
Canary runs and fill rates notice a changed site before your own runs fail.
Popups out of the way
Cookie banners, modals and product tours are closed before they block a click.
Dry runs and test keys
Try a program up to its first submit, or with test keys on their own small daily quota.
Batches
Send up to 1,000 inputs in one call and follow them as one batch.
Bring your own
Use your own proxies, LLM or captcha solver, and that line leaves your bill.
TypeScript, Python, Go, REST, the CLI and MCP.
How it compares
Not anotherscraping API.
| Capability | Kaabist | Remote browser platforms | Scraping APIs |
|---|---|---|---|
| Waits for your 2FA code, then resumes | Yes | Partly | No |
| Never submits twice, even after a crash | Yes | No | No |
| Fixes itself, with your approval | Yes | Partly | No |
| Built by your coding agent | Yes | Partly | Partly |
Categories summarised from vendors' public documentation. Last verified 2026-10-10. Product by product: /vs.
Plans
Start free.Grow by credits.
Free$0 / mo
500
credits a month
Developer$49 / mo
10,000
credits a month
Team$249 / mo
60,000
credits a month
Scale$999 / mo
300,000
credits a month
Every plan has the builder, MCP, resumes, fences and webhooks.Compare plans and credit prices →
Questions