Skip to main content
An invitation is a pending offer to join your organization. It carries a target email, a target role, and a one-time secret token. When the recipient accepts the invite (by following the URL you build with that token), their organization_members row is created and member.joined fires.
Invitations expire automatically. The expires_at field on every invitation tells you when. Expired invitations cannot be accepted — re-invite the user with a fresh POST /team/invitations.

The invitation object

Create an invitation

POST /team/invitations with the recipient’s email and the target role id. The response returns the new invitation and a one-time secret token — this is the only time the token is shown, so capture it now.
cURL
Build the accept URL with the returned token:
Treat the token as a secret. Anyone who possesses it can accept the invitation as the named email address (after Sign-In). Send it via a side channel you trust (transactional email, in-app DM), and do not log it.
POST /team/invitations is idempotent — pass an Idempotency-Key header to make safe retries. See Idempotency.

List pending invitations

cURL
Returns only invitations with status = "pending". Already accepted/declined/expired/revoked rows are not surfaced — query the audit log if you need full history.

Get one

cURL

Cancel an invitation

DELETE /team/invitations/{id} revokes a pending invitation. Once revoked, the token stops working — even before its expires_at. Fires invitation.revoked.
cURL
Returns 204 No Content. Already-accepted, declined, expired, or revoked invitations cannot be revoked again — the endpoint returns 409 conflict in that case.