Skip to main content
By the end of this page your agent has an account at a third-party app — connected (one you already own) or registered (a new one) — and a browser session logged into it. You will not create an email identity first. Sente provisions the backing address for you. Everything runs against https://api.sente.run/v1.
1

Get an API key

Sign in at app.sente.run. The first sign-in creates your organization and puts you on the free tier — no card.On the API keys page, create a key and export it:
The API accepts it as Authorization: Bearer <key>. One key authenticates the whole organization — treat it like a production secret.
2

Install a client

sente login opens a browser and mints a key for you, so you can skip step 1. In CI, set SENTE_API_TOKEN instead — it always wins over the stored file.
3

Connect an account you already own

You supply the username and password once. Sente logs in with a real browser, vaults the credentials write-only, and keeps the account re-loginable. No identityId — the backing email address is provisioned from the app’s hostname.
Registering a new account is the same shape — sente register <appUrl> / registrations.register({ appUrl }) — and is only for apps whose terms permit it. Add --confirm-before-submit / confirmBeforeSubmit: true so a human clicks the final submit and accepts the app’s terms. See Register.
SSO-only accounts cannot be connected. If the account signs in only through Google/Okta SSO or a passkey, there is no username and password to vault. Same for accounts whose second factor is SMS — see the block handling in the next step.
4

Wait for the run, and handle a block

Connecting starts a run: one browser job. It ends completed or failed, or stops at blocked — meaning a human step is required. Nothing is worked around; the run holds for 10 minutes with an interactive live view, then fails with BLOCKED_TIMEOUT.
waitForRun takes milliseconds in TypeScript and seconds in Python. It returns the last-polled run on timeout rather than throwing — always check status.
Email verification is the one step you never handle: every inbound email to the account’s address is classified on arrival, and the run injects the code or link itself. See Verification codes.
5

Use the logged-in session

getSession hands back a remote browser already signed in, as a CDP URL. If the login went stale, Sente re-logs in first (vaulted credentials plus a fresh code from the account’s inbox) and sets healed: true — a cold call can take a minute.
One live session per identity, and open sessions bill per minute — always close them. To use your own browser stack instead, export a portable Playwright storageState: sente session export <registrationId> / registrations.exportSession(id). See Sessions.

What just happened

You never created an email identity, but one exists. When identityId is omitted, Sente auto-provisions the backing identity from the app’s hostname: app.example.com becomes app-example@sente.run, and a taken address gets a short random suffix (app-example-x7k2@sente.run). That address is a real mailbox — it receives the app’s verification emails, notifications, and password resets, and the run reads them.
Two consequences worth knowing:
  • The identity counts against your plan’s identity cap. If auto-provisioning would exceed it, the call returns 429 IDENTITY_LIMIT_EXCEEDED — pass an existing identityId to reuse an address across several apps, or upgrade.
  • If the connect or register itself then fails, the auto-created identity is rolled back, so a failed attempt does not eat the cap.
Pass identityId explicitly when you want several accounts to share one mailbox, or when the address matters (it appears in the app’s UI as the account’s email).

When it doesn’t work

Full lists: Run statuses and error codes · Human takeover.
Paste this into Claude Code, Cursor, or any coding agent that can read a URL:
The agent installs the CLI, runs sente login, provisions an identity, writes the key to .env, and wires send/receive into your codebase. One step still needs you: sente login opens a browser for you to sign in.

Next steps

  • Accounts — the account object, created vs connected, and how the identity relates to it.
  • Verification codes — waitForOtp and sente wait --otp for the signups you drive yourself.
  • Webhooks — get pushed run.blocked, run.completed, and run.failed instead of polling.