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
| Method | Path | Role required | Description | Status |
|---|---|---|---|---|
| POST | /api/v1/auth/organizations/{orgId}/invitations | owner / admin | Create and send invitation | 201 |
| GET | /api/v1/auth/organizations/{orgId}/invitations | owner / admin | List pending invitations | 200 |
| POST | /api/v1/auth/invitations/{token}/accept | Any (JWT) | Accept an invitation | 200 |
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
| Parameter | Type | Description |
|---|---|---|
orgId | UUID | Organization to invite the user into |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email address of the invitee. Must match the email they register or log in with. |
role | string | Yes | Role 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
| Field | Type | Description |
|---|---|---|
id | UUID | Invitation identifier |
email | string | Email address the invitation was sent to |
role | string | Role that will be assigned on acceptance |
expiresAt | ISO 8601 | When the invitation expires (7 days from creation) |
createdAt | ISO 8601 | When 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
| Parameter | Type | Description |
|---|---|---|
orgId | UUID | Organization 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
| Field | Type | Description |
|---|---|---|
items | array | Pending invitations |
items[].id | UUID | Invitation identifier |
items[].email | string | Invited email address |
items[].role | string | Role assigned on acceptance |
items[].expiresAt | ISO 8601 | Expiry timestamp |
items[].createdAt | ISO 8601 | Creation timestamp |
total | integer | Total 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
| Parameter | Type | Description |
|---|---|---|
token | string | One-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
| Field | Type | Description |
|---|---|---|
organizationId | UUID | The organization the user has joined |
role | string | The 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
| Status | Endpoint | Reason |
|---|---|---|
401 | All | Missing or expired JWT token |
403 | POST /invitations | Caller is not an owner or admin |
403 | GET /invitations | Caller is not an owner or admin |
403 | POST /accept | Authenticated user's email does not match the invitation email |
404 | POST /invitations | Organization not found, or caller is not a member |
404 | POST /accept | Token not found or already used |
409 | POST /invitations | An active invitation for this email already exists in this organization |
410 | POST /accept | Invitation has expired — request a new one |
{
"error": "Invitation expired",
"details": {}
}See Error Handling for the full list of error codes.
See also
- Organizations & Members — manage roles and remove members after they've joined
- User Auth — register and log in to get a JWT token
- Authentication guide — JWT and API key overview