API Reference
Invitations

Invitations

Invite users to your organization by email. The invitee receives a link with a one-time token; clicking it and accepting the invitation adds them as a member.

All endpoints on this page require a valid JWT token. To get one, see User Auth. For an overview of organization roles, see Organizations & Members.

Base URL: https://pharlo.io
Auth: Authorization: Bearer <jwt_token>


How it works

Admin creates an invitation

An owner or admin calls POST /organizations/{orgId}/invitations with the invitee's email and desired role. The API sends an email with a link containing a one-time token.

Invitee registers or logs in

If the invitee doesn't have an account yet, they register first — see User Auth. The email used for registration must match the invitation email.

Invitee accepts the invitation

The invitee calls POST /invitations/{token}/accept with their JWT. They are immediately added to the organization with the assigned role.

⚠️

Invitations expire after 7 days. If the invitee doesn't accept in time, create a new invitation. Pending invitations can be reviewed with GET /organizations/{orgId}/invitations.


Endpoints

MethodPathRole requiredDescriptionStatus
POST/api/v1/auth/organizations/{orgId}/invitationsowner / adminCreate and send invitation201
GET/api/v1/auth/organizations/{orgId}/invitationsowner / adminList pending invitations200
POST/api/v1/auth/invitations/{token}/acceptAny (JWT)Accept an invitation200

POST /api/v1/auth/organizations/{orgId}/invitations

Creates an invitation and sends an email to the invitee. Requires owner or admin role.

Only admin and member roles can be assigned via invitation — the owner role is not transferable.

Path parameters

ParameterTypeDescription
orgIdUUIDOrganization to invite the user into

Request body

FieldTypeRequiredDescription
emailstringYesEmail address of the invitee. Must match the email they register or log in with.
rolestringYesRole to assign on acceptance: admin or member

Example request

curl -X POST \
  https://pharlo.io/api/v1/auth/organizations/018e1f3a-7c2b-7000-8f4d-1a2b3c4d5e6f/invitations \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "colleague@example.com", "role": "member"}'

Response 201 Created

FieldTypeDescription
idUUIDInvitation identifier
emailstringEmail address the invitation was sent to
rolestringRole that will be assigned on acceptance
expiresAtISO 8601When the invitation expires (7 days from creation)
createdAtISO 8601When the invitation was created
{
  "id": "018e4c6d-3e5f-7000-bg7b-5e6f7a8b9c0d",
  "email": "colleague@example.com",
  "role": "member",
  "expiresAt": "2026-05-04T10:00:00Z",
  "createdAt": "2026-04-27T10:00:00Z"
}

GET /api/v1/auth/organizations/{orgId}/invitations

Lists all pending invitations for the organization — those that have not yet been accepted or expired. Requires owner or admin role.

Path parameters

ParameterTypeDescription
orgIdUUIDOrganization identifier

Example request

curl https://pharlo.io/api/v1/auth/organizations/018e1f3a-7c2b-7000-8f4d-1a2b3c4d5e6f/invitations \
  -H "Authorization: Bearer $JWT_TOKEN"

Response 200 OK

FieldTypeDescription
itemsarrayPending invitations
items[].idUUIDInvitation identifier
items[].emailstringInvited email address
items[].rolestringRole assigned on acceptance
items[].expiresAtISO 8601Expiry timestamp
items[].createdAtISO 8601Creation timestamp
totalintegerTotal number of pending invitations
{
  "items": [
    {
      "id": "018e4c6d-3e5f-7000-bg7b-5e6f7a8b9c0d",
      "email": "colleague@example.com",
      "role": "member",
      "expiresAt": "2026-05-04T10:00:00Z",
      "createdAt": "2026-04-27T10:00:00Z"
    }
  ],
  "total": 1
}

POST /api/v1/auth/invitations/{token}/accept

Accepts an invitation. The authenticated user is added to the organization with the role specified in the invitation.

⚠️

The JWT token used here must belong to a user whose email matches the invitation email. If the invitee doesn't have an account yet, they must register first using that same email address.

Path parameters

ParameterTypeDescription
tokenstringOne-time token from the invitation email link

The token is embedded in the link sent to the invitee's email. It looks like:

https://your-app.com/accept?token=a1b2c3d4e5f6...

Extract the token query parameter and pass it to this endpoint.

Example request

curl -X POST \
  https://pharlo.io/api/v1/auth/invitations/a1b2c3d4e5f6g7h8i9j0/accept \
  -H "Authorization: Bearer $JWT_TOKEN"

Response 200 OK

FieldTypeDescription
organizationIdUUIDThe organization the user has joined
rolestringThe role assigned: admin or member
{
  "organizationId": "018e1f3a-7c2b-7000-8f4d-1a2b3c4d5e6f",
  "role": "member"
}

After accepting, the organization will appear in the user's list — see GET /auth/organizations.


Error responses

StatusEndpointReason
401AllMissing or expired JWT token
403POST /invitationsCaller is not an owner or admin
403GET /invitationsCaller is not an owner or admin
403POST /acceptAuthenticated user's email does not match the invitation email
404POST /invitationsOrganization not found, or caller is not a member
404POST /acceptToken not found or already used
409POST /invitationsAn active invitation for this email already exists in this organization
410POST /acceptInvitation has expired — request a new one
{
  "error": "Invitation expired",
  "details": {}
}

See Error Handling for the full list of error codes.


See also