Resend a pending invite (admin)
/api/invites/{id}/resendAdmin-triggered resend from the teammate roster; distinct from POST /api/invites/resend, which is public and token-keyed for someone acting on their own expired invite link. This one is id-keyed and admin-gated, for "they still haven't accepted, send it again."
RLS's tenant-scoped select already proves the id belongs to the caller's own company, so an id from a different company is simply not found, the same reasoning DELETE /api/members/{id} relies on. An invite that has already been accepted or already revoked is likewise not found: this route only ever acts on a still-pending one.
Issues a fresh token and a fresh expiry (the old link stops working the moment this succeeds) and re-sends the invite email.
Authorization
sessionCookie The dashboard's Supabase Auth session cookie, set at sign-in. Large sessions are split across
numbered chunks (…auth-token.0, .1), so treat this as a cookie family rather than one name.
Every request re-validates it against the Auth server (getUser()), never by decoding the cookie
locally: a JWT nothing has checked is not a credential. Tenancy is then read from the verified
app_metadata.company_id claim and enforced by row-level security; it is never read from request
input, on any route, ever.
role (admin / staff) is deliberately not in RLS. It gates specific actions in route code,
the operations marked admin below, so hiding a button in the UI is cosmetic only, and a route's
own check is the enforcement.
In: cookie
Path Parameters
The book_invites row id.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/invites/string/resend"{ "ok": true}Remove a teammate (admin) DELETE
Order matters and is deliberate: the `company_id` claim is nulled FIRST, then the roster row is deleted. The reverse could leave a claim-holding non-member with live RLS access to everything. If the row delete fails the user is locked out but still listed; retrying fixes it, and the dangerous state cannot occur. You cannot remove yourself, and you cannot remove the last admin.
Cancel a pending invite (admin) POST
Sets `revoked_at` rather than deleting the row: a revoked invite's token must stop working (checked by both accept and resend), but the row staying around is the only record that an invite existed and was cancelled. Same lookup as resend; only a still-pending invite in the caller's own company can be revoked; RLS proves the tenancy, and an already-accepted or already-revoked row reads as not found.