kind: "connected", so it shares the registration endpoints. Sessions, re-login, credential writes, and session export live at /v1/registrations/:id/... and take the connection’s id.
Known limits, before you build against this:
- SSO-only accounts cannot be connected. If the account signs in only through Google/Okta/etc. or a passkey, there is no username and password for Sente to use.
- Authenticator (TOTP) 2FA re-logins without a human — supply
credentials.totpSeedand the server computes the 30-second code at login. The seed is vaulted encrypted, is never returned by the API, and never reaches any model. - Email-code MFA needs a human in the live view — unless you repoint that account’s notification email to the identity’s Sente address and pass
verifyToIdentity: true, in which case the code lands in Sente’s inbox and is injected automatically. - SMS codes always need a human. The run blocks with
MFA_REQUIREDand pages one. There is no SMS channel.
Create a connection
POST /v1/connections
Queues a
connect run that logs in with the supplied credentials and marks the connection active on success.
201:
verifyToIdentity is an HTTP-only field today. The TypeScript SDK, the Python SDK, and the CLI all send appUrl + credentials (and an optional identityId) but do not expose it — call the endpoint directly if you need it.Re-connecting rotates credentials
Posting again for the same (identity, app origin) re-connects the existing row: it replaces the vaulted username, password, and TOTP seed, clears any revoke, resets the status topending, and drives a fresh connect run. That single behaviour covers three jobs — rotating a password, adding or replacing a TOTP seed, and re-enabling a revoked connection.
Omitting totpSeed on a re-connect clears the vaulted seed; resend it if the account still has authenticator 2FA.
Errors
The mirror-image conflict —
register against an existing connection — is 409 ALREADY_CONNECTED on POST /v1/registrations.
If the connect fails on an identity Sente auto-provisioned for this call, that identity is deleted again — a failed connect doesn’t consume your identity cap.
List connections
GET /v1/connections
Returns only
kind: "connected" rows, newest first, each with latestRun.
identityId that isn’t your org’s returns 404 {"error": "identity not found"}.
Get a connection
GET /v1/connections/:id
200: the connection object. 404 {"error": "not found"} for unknown ids, other orgs’ resources, and for registration ids that are created rather than connected — this endpoint is kind-scoped, so use GET /v1/registrations/:id for those.
Credentials are write-only
There is no credential read for connections.GET /v1/registrations/:id/credentials on a connected account returns 403:
POST /v1/connections with the new one.
Revoke a connection
POST /v1/connections/:id/revoke
Withdraws the delegation. The connection becomes disabled: login and credential writes answer 409 REVOKED, and sessions refuse to open with 409 NOT_ACTIVE. The vault is kept, so re-enabling is one POST /v1/connections away. No body.
200:
revokedAt. Writes a connection.revoke audit event.
Delete a connection
DELETE /v1/connections/:id
Revoke and purge: the vaulted password and TOTP seed are erased. This is the offboarding guarantee — afterwards Sente holds no secret for this account. The row itself remains, disabled, so the audit trail and the origin slot survive.
204 with no body. Writes a connection.delete audit event.
Use revoke to pause a delegation you expect to restore; use delete when offboarding and Sente should hold nothing. Both are
connected-only — calling either with a created registration’s id returns 404.
Related
Connect an account
The guide, including the 2FA paths.
Human takeover
What happens when a code goes to your phone.
Security
How the vault and the audit trail work.
