created (Sente registered the account) and connected (you own the account and connected it — see Connections). Creating or logging in queues a run: a browser agent drives the app’s own signup/login forms and completes email verification from the identity’s own inbox.
Register only at apps whose terms permit automated account creation. If you want a human to approve the final step, pass
confirmBeforeSubmit: true — the agent fills the form, then the run blocks with a live view so a person clicks submit. CAPTCHAs and SMS verification are not automated: they block the run for human takeover. See Acceptable use and Limits.The registration object
One registration exists per (identity, app origin):
https://app.example.com/signup and https://app.example.com/ are the same registration; example.com and app.example.com are different ones.
Register at an app
POST /v1/registrations
Returns the registration plus the run driving it. The call is idempotent and converging: re-posting the same (identity, app) returns the existing registration — joining an in-flight run if one exists, and never re-driving an already-
active account (use /login to re-authenticate).
201:
GET /v1/runs/:id or subscribe to run.* webhooks for the outcome.
Errors:
List registrations
GET /v1/registrations — optional ?identityId=... to scope to one identity.
Each row embeds latestRun (a run object, or null) for status display.
200:
Get a registration
GET /v1/registrations/:id
200: the registration object. 404 otherwise.
Log in again
POST /v1/registrations/:id/login
Queues a login run that re-authenticates the account with the vaulted credentials (completing email verification from the identity’s inbox if the app sends one). Works for both created and connected registrations.
201: { "registration": { ... }, "run": { ..., "type": "login", "status": "queued" } }
Errors: 429 RUN_LIMIT_EXCEEDED; 409 {"code": "REVOKED"} if this is a revoked connection.
Open a logged-in browser session
POST /v1/registrations/:id/session
Opens a browser on the identity’s persistent profile — already logged in to this app — and returns a CDP URL for puppeteer.connect / chromium.connectOverCDP. See Sessions.
By default the login is verified by recency: if the last confirmed login is fresh (within ~10 minutes), the session opens immediately; if it’s older, Sente queues a re-login run first and answers 409 SESSION_STALE with the runId to poll — retry once that run completes.
201:
cdpUrl is returned once and never stored. One live session per identity. Errors (409, with code):
Close the session
DELETE /v1/registrations/:id/session
Stops and releases the identity’s open browser session. Idempotent.
204 with no body.
Export session state
POST /v1/registrations/:id/session/export
Returns a portable Playwright storageState (cookies + localStorage) for the logged-in account, loadable into your own Playwright, Puppeteer, or browser-use — no Sente browser needed afterwards. Accepts the same verify / maxStaleSec body and the same 409 SESSION_STALE / SESSION_PENDING contract as /session. If a session is already open it exports from that; otherwise Sente opens one, exports, and closes it.
200:
Get credentials
GET /v1/registrations/:id/credentials
For Sente-created accounts only: returns the vaulted username and password in plaintext (you need the password Sente generated). Every read is audited.
200:
origin is generated (Sente made the password) or supplied (you provided it).
For connected accounts this endpoint returns 403 {"error": "connected-account credentials are write-only", "code": "CREDENTIALS_WRITE_ONLY"} — you already have your own password, and Sente never reads a customer’s credential back out. See Connections.
Update credentials
PUT /v1/registrations/:id/credentials
Overwrites the vault only — it does not change the password at the app. Use it after you rotate the password at the app yourself, so the next login run uses the new one.
204 with no body. 409 {"code": "REVOKED"} if the registration is a revoked connection.