Tenant invitations

The tenant invitations resource manages pending invites — emails sent to someone outside the tenant offering a role on it. Accepted invitations turn into tenant member rows; until then they sit here, viewable + revocable + resendable.

The only resource that sends email

Unlike most of this API — which is pure data-plane CRUD — POST /v1/tenant_invitations and POST /v1/tenant_invitations/{id}/resend both send a real email via Resend. The email send is awaited synchronously so the API response status reflects whether the email actually went out: a successful row insert followed by a Resend failure returns 502 email_send_failed with the new invite ID in the response, so you can retry via /resend without re-creating the row (and double-emailing on success).

Token never appears in API responses

The plaintext invite token only ever lives in (a) the email body and (b) the URL the recipient clicks. The database stores only a SHA-256 hash; the API response shape doesn't include the token at all. There is no programmatic path to retrieve a sent invite's token — by design.

Notes

  • Invites expire after 7 days by default.
  • Resend is rate-limited to one call per 60 seconds per invite (server-side, in the underlying RPC).
  • Capability-gated to owner/admin (or any member in flat-mode tenants).
  • The invite email currently shows (unknown) as the inviter's identity for API-driven invites; the JWT minted for API requests doesn't carry the user's email and we don't want a per-request lookup just for personalisation. Dashboard-issued invites still show the inviter's email.

Endpoints