Invites

List your organization's pending invitations and revoke the ones you no longer want.

An invite is an offer to join your organization with a role. It never creates a person: the invitee accepts it themselves, by email.

EndpointScopeToken owner's role
POST /invitesmembers:writeAdmin
GET /invitesmembers:readAdmin
DELETE /invites/{id}members:writeAdmin

All three routes need an owner who is currently an organization Admin; a Member's token gets 403 insufficient_scope.

Invitations can be sent from the portal (Settings → Team → Invite Member) or with POST /invites below; this API also lists and revokes the pending ones.

The invite object

FieldTypeNotes
idstringOpaque id.
emailstring
rolestringadmin or member.
project_idsstring[]Initial project access for a member, applied on acceptance. May be empty.
statusstringAlways pending — the list holds pending invites only.
expires_atstringWhen the invitation link stops working.
created_atstring

The invitation token itself is never returned.

{
  "id": "e2f3a4b5-c6d7-4e8f-9a0b-1c2d3e4f5a6b",
  "email": "[email protected]",
  "role": "member",
  "project_ids": ["5b3e9a41-0c7d-4e2f-8a16-9d4b7c2e1f08"],
  "status": "pending",
  "expires_at": "2026-10-01T10:15:00Z",
  "created_at": "2026-09-24T10:15:00Z"
}

Create an invite

POST /api/v1/mgmt/invites

Creates an invitation for email. It runs the same flow as the portal: the address is normalized, role is member (default) or admin (never superadmin), and project_ids grants a member project access on acceptance (every id must be a project of your organization; ignored for admin). An organization with an active SSO connection only accepts the admin's own email domain. No interactive re-login or acceptance step is added here — the invitee accepts by email. Requires Idempotency-Key.

The response carries a status, and its HTTP status code reflects whether a new invite was actually created:

statusHTTP statusMeaning
created201A new invitation was sent.
already_member200The address already belongs to the organization; no invite is sent (the member's name/is_active are returned).
already_pending200A pending invitation already exists; it is returned, never duplicated.
curl -X POST https://portal.<domain>/api/v1/mgmt/invites \
  -H "Authorization: Bearer $TF_PAT" \
  -H "Idempotency-Key: 2a3b4c5d-6e7f-4a8b-9c9d-0e1f2a3b4c5d" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","role":"member","project_ids":["5b3e9a41-0c7d-4e2f-8a16-9d4b7c2e1f08"]}'
{
  "status": "created",
  "id": "e2f3a4b5-c6d7-4e8f-9a0b-1c2d3e4f5a6b",
  "email": "[email protected]",
  "role": "member",
  "project_ids": ["5b3e9a41-0c7d-4e2f-8a16-9d4b7c2e1f08"],
  "expires_at": "2026-10-01T10:15:00Z"
}

List invites

GET /api/v1/mgmt/invites

The organization's pending invites, newest first. Paginated with limit and cursor; there are no filters.

curl https://portal.<domain>/api/v1/mgmt/invites \
  -H "Authorization: Bearer $TF_PAT"
{
  "data": [
    {
      "id": "e2f3a4b5-c6d7-4e8f-9a0b-1c2d3e4f5a6b",
      "email": "[email protected]",
      "role": "member",
      "project_ids": ["5b3e9a41-0c7d-4e2f-8a16-9d4b7c2e1f08"],
      "status": "pending",
      "expires_at": "2026-10-01T10:15:00Z",
      "created_at": "2026-09-24T10:15:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Revoke an invite

DELETE /api/v1/mgmt/invites/{id}

Immediate: the link stops working and the invite leaves the pending list. No body. Requires Idempotency-Key. Returns 204 No Content.

curl -X DELETE https://portal.<domain>/api/v1/mgmt/invites/e2f3a4b5-c6d7-4e8f-9a0b-1c2d3e4f5a6b \
  -H "Authorization: Bearer $TF_PAT" \
  -H "Idempotency-Key: 2a3b4c5d-6e7f-4a8b-9c9d-0e1f2a3b4c5d"

Errors specific to invites

StatusCodeWhen
400invalid_request (param email)email is missing, malformed, or not a single bare address.
400invalid_request (param role)role is not member or admin.
400invalid_request (param project_ids)An id in project_ids is not a project of your organization, or more than 100 ids.
403insufficient_scopeToken lacks members:read/members:write, or the owner is not currently an Admin.
404not_foundInvite absent, already gone, or in another organization.
409conflictThe org has an SSO connection and email is not the admin's own domain.
409conflict (param email)The address cannot be invited to this organization.
422unsupported_filterAny query parameter other than limit and cursor on the list.