Skip to main content
Create Invite
Creates an invitation, addressed by exactly one of email, userId, or username. Requires the invite capability. Always sends an email (no toggle). Fires workspace.invite.created.
Requires workspaces.inviteAcceptUrl on the project. The invitation email’s only call to action is a deep-link built from that setting, and it has no default — so an unconfigured project cannot create invitations at all. Without it this endpoint returns 409 workspace/missing-invite-accept-url and persists nothing (no invitation row, no email, no webhook).This applies even when the invitee already has an account — there is no special case. See Project settings for how to configure it.
The invited capabilities/permissions are validated against the inviter’s own resolved set on the workspace — no-escalation on both arrays. The rank floor applies only when the inviter has a direct member row on the workspace: then the invited rank must be strictly larger (less senior) than the inviter’s own. A reach-holder inviter (holding invite via an open inherit chain, with no direct row) is not in the workspace’s rank ladder and may invite at any rank. Duplicate handling:
  • Inviting an existing member409 (change the grant via Update Member).
  • A live invite (pending and not past expiresAt) for the same target → idempotent refresh (updates the grant, resets a 14-day expiry).
  • A terminal (accepted/declined/revoked) or effectively-expired invite does not block — a fresh pending is created. (An accepted invite means the user is already a member, so re-inviting them returns 409 instead.)
Invite-by-email to an address that already has an account resolves and stores the userId at creation. The account lookup is case-insensitive, so an account stored as Jane@Example.com is still bound when invited as jane@example.com.

Path Parameters

string
required
The workspace UUID.

Body Parameters

string
Invitee email (trimmed + lowercased server-side). One of email/userId/username is required. Matching an existing account is case-insensitive, so an address that was stored with different capitalization (as OAuth-created accounts are) still binds its userId.
string
Invitee user id (existing users only). Here userId is the invite target, not an acting user.
string
Invitee username (existing users only).
string[]
Capabilities to apply on accept. Defaults to []. Subject to no-escalation.
string[]
Opaque permissions to apply on accept. Defaults to []. Subject to no-escalation.
number
required
Initial rank to apply on accept. For a direct-member inviter it must be strictly larger (less senior) than their own; a reach-holder inviter (no direct row) may set any rank.
string
Optional initial cosmetic title.

Response

Returns the created WorkspaceInvitation object.

Error Responses

A project misconfiguration, not a bad request — the payload is fine and the caller is authorized. Set workspaces.inviteAcceptUrl in your project settings and retry the identical request.
See also: useCreateWorkspaceInvite · createWorkspaceInvite (js-sdk) · createWorkspaceInvite (node-sdk)