Skip to main content
A run is one browser-agent job against a third-party app. There are three run types:
  • register — create a new account under the identity’s email (Register)
  • login — re-authenticate an existing registration
  • connect — log in to an account you already own with the credentials you supplied (Connect)
Runs are asynchronous and persisted. You start one (usually indirectly, via POST /v1/registrations or POST /v1/connections), then observe it by polling GET /v1/runs/:id or through webhooks.

Lifecycle

blocked is a stop state, not a failure: the run keeps its browser session alive and waits for a human.

What blocks a run

Sente does not attempt to defeat these gates. Hitting one stops the run and hands it to a person — that is deliberate. The blocking gate is the site’s decision to require a human, and Sente honors it. Two connected-account MFA cases stay autonomous: if a TOTP seed was supplied at connect time, the server computes the 30-second code and submits it (the seed never reaches any model); and if the account’s notification email has been repointed to the Sente identity, an email code lands in the identity’s own inbox and is applied like any other verification email. Everything else — SMS codes, email codes sent to your inbox — needs a human.

What happens when a run blocks

  1. The run’s status becomes blocked, with error.code, and liveViewUrl — an interactive live browser view. Whoever opens it sees the exact page the agent stopped on and can click and type.
  2. You get paged, three ways:
    • The run.blocked webhook fires, carrying code, liveViewUrl, actionUrl (a dashboard deep link), and holdExpiresAt.
    • The org’s operators get an email with the dashboard link (per-user opt-in in the dashboard).
    • sente watch, if running, fires a desktop notification.
  3. A human opens the live view (or the run page at app.sente.run), does the one thing needed — solves the CAPTCHA, enters the MFA code, fills the missing field, clicks submit — then resumes:
  1. The run picks up from where it stopped — same browser, same page — and continues toward completed.
A blocked run holds for about 10 minutes. If nobody resumes it, it fails with BLOCKED_TIMEOUT and releases the browser. Wire up the run.blocked webhook or run sente watch so a block reaches a human while the hold is still open.
You can also abort a non-terminal run at any point: sente run abort <runId> / runs.abort(id).

Confirm-before-submit

For registrations, pass confirmBeforeSubmit: true (Python: confirm_before_submit=True) and the agent fills the entire signup form but deliberately stops before the final submit. The run blocks with SUBMIT_CONFIRMATION_REQUIRED; a person reviews the filled form in the live view, clicks submit themselves — so a human, not an agent, forms the agreement with the site — and then resumes the run. Use this whenever you want a human in the loop at the moment of account creation. Registration runs should only target apps whose terms permit them; see Acceptable use.

Observing runs

run.completed and run.failed webhooks fire on terminal states, so a server can react without polling. Payloads and delivery semantics: Webhooks and the runs API reference. Runs are also rate-limited per org (429 RUN_LIMIT_EXCEEDED past the cap) — see Limits.

Identities and registrations

The objects a run creates and maintains.

Register

Creating a new account at an app, including confirm-before-submit.

Connect

Owner-authorized access to an account you already have.

Webhooks

run.blocked, run.completed, run.failed payloads.