invitations

Accept an invitation

Accept a workspace invitation token and receive a session token pair.

The raw token from the invitation email is the credential for the ordinary case: an invitee with no existing account accepts anonymously and lands logged in (access + refresh tokens) scoped to the invitation's tenant with the invited role. An Authorization header is optional, and needed only to complete the one case below that a token alone cannot: POST anonymously first, and send the bearer only if this endpoint asks for it.

Errors:

  • 404: unknown token.
  • 400: expired or revoked invitation.
  • 409: invitation already accepted, the workspace membership could not be linked to the account that accepted it, or the workspace has no active owner and the invitation would bring back its last owner row with a lower role (errors[0].type is last_owner). The second is not retryable by the invitee: the acceptance is rolled back and an admin has to sort the membership out, most often because that person already belongs to this workspace under another address. The third is rolled back too and the invitation stays pending: the workspace needs an owner restored, which Patricia support escalates.
  • 401 INVITATION_SIGN_IN_REQUIRED: the invited address already has an account. Sign in, then POST this endpoint again with the bearer token; the invitation is untouched and still usable.
  • 403 INVITATION_WRONG_ACCOUNT: a bearer was sent, but it is signed in as somebody other than the invited address's owner — most often a forwarded link. Sign in as the invited address and retry. The invitation is untouched, and the message deliberately does not say who it was for.
  • 403 FORBIDDEN: every other refusal on this route — the account needs recovery, the account can no longer be used, the invitation went to a secondary address rather than the account's main one, the two identity planes disagree about who is joining, or the membership did not come out active. The invitation stays pending in all of them. They share the generic code on purpose: the dashboard shows the message, and there is no action the invitee can take that a distinct code would unlock. Deliberately not enumerated in the response description — a count there goes stale the first time one is added.
post/v1/invitations/{token}/accept

Request

  • Base URL: https://api.patricia.app (the document declares no server; this is the origin it was published from)
  • URL: https://api.patricia.app/v1/invitations/{token}/accept
  • Auth: one of:
    • HTTP bearer
    • none

Path parameters

tokenstring required

The raw invitation token received via email

Response

Successful Response

access_tokenstring required
refresh_tokenstring required
token_typestring
expires_ininteger required
landing_hint'pending_invitation' | 'diverted_unknown_workspace'

A non-authorization hint explaining WHY a session landed where it did.

The dashboard reads it to show the right next step instead of a bare landing. It never grants access: the token's tenant claim (or its absence) is the sole authority. Two values, and they differ in whether the session has a workspace at all:

PENDING_INVITATION lands TENANT-LESS — a returning user with at least one pending invitation and no active available home. It is NOT "only pending memberships": the branch is chosen on has_pending before the deactivated/unavailable fallback, so a user holding a pending invite alongside deactivated or unavailable ones lands here too. The SSO guard declines to mint an empty duplicate tenant, and the hint points them at accepting the invite / signing in from the connected workspace.

DIVERTED_UNKNOWN_WORKSPACE lands WITH an active workspace — a returning user who signed in from a chat workspace Patricia does not know. The guard diverts them to their existing primary workspace rather than minting a second one, and the hint is what lets the dashboard say so and offer a deliberate way to create a separate workspace instead of failing silently.

decision_keystring nullable

Changes

No recorded changes to this operation across all 1 revision of this API.