Product · Side effects
A worker crashes on “Pay now”.Kaabist doesn’t press it again.
Mark the steps that change something (a submit, a payment, an order) as side effects. Kaabist writes each one down just before it runs and again once it has worked. If a server crashes in between, Kaabist never presses the button again on its own: it pauses and asks you to check.
- 01The program reaches the submitSteps run one after another. The click on Submit claim is marked as a side effect: it changes something in the world.
- 02The fence goes upBefore it clicks, Kaabist writes the step down as about to execute, outside the browser, where a crash cannot erase it.
- 03The click goes out, and the server diesThe request leaves. Before the confirmation loads, the machine running the job is gone. The portal received the claim; the run never saw it.
- 04Another server takes the jobIt replays from the last checkpoint and walks up to the same button.
- 05It finds the fence open, and stopsThe step was about to run and never confirmed. Clicking again could file the claim twice, so it does not guess: the run pauses and asks you.
- 06You decideYou check the portal: the claim arrived. You skip the step, and the job carries on after the submit. One claim, filed once.
How it works
01
Mark the step
A side-effect step can be neither retried nor optional, and the linter warns when no checkpoint follows it. That checkpoint is where everything after the submit resumes from.
example{ "click": "#order-form button[type=submit]", "side_effect": true, "expect": { "url": "**/orders/*" } }, { "checkpoint": "order-placed" }02
The fence
Before the click, Kaabist writes the step down as about to execute; once its expectation holds, as executed. A server that picks the job up and finds the fence still open does not click. It pauses the job as side_effect_ambiguous and notifies you, so you can check what happened.
03
Retries never go back past it
A retry can never restart from a checkpoint earlier than the last side effect that ran. Whatever goes wrong after the order is placed, the order is not placed again.
04
And no duplicate jobs either
Send an Idempotency-Key when you create a job. The same key with the same body within 24 hours returns the original job instead of starting a second one.
exampleconst idempotencyKey = `order-${orderId}`; const job = await kaab.jobs.create({ program: "place-order", inputs: { sku: "HP-1037", qty: 2 }, idempotencyKey, });05
Test up to the button
A dry run executes the whole flow and stops before the first side effect, so you can test a checkout without buying anything.
Questions
Askedbefore you ask.
More of Kaabist
Resumes where it stopped
Some steps only you can finish: a one-time code, a captcha, an approval. Kaabist pauses the run right there and emails a link to you, or to the teammate or customer you choose. Once they answer, the program continues from its last checkpoint. Nothing starts over.
Built by your coding agent
Connect Claude Code, Codex or Cursor to mcp.kaab.ist. Your agent opens a real Kaabist browser, works through the site with you, and what it does becomes a program: versioned, linted, and tested with a dry run before it ever submits anything.
Self-healing locators
Every target is recorded with several ranked locators and a fingerprint of the element it found. When the site changes and they stop matching, Kaabist finds the element again, writes the fix down as a proposal, and lets you promote it to a new version.
