Team — /v1/team
All team endpoints require a valid JWT session (Authorization: Bearer <jwt>). Org-level API keys are not accepted — team management is a session-only operation.
Public endpoints (/invites/:token/preview and /invites/:token/accept) require no authentication.
List members
Section titled “List members”GET /v1/team/membersAuthorization: Bearer <jwt>Returns all members in the org, plus plan metadata.
Response
{ "members": [ { "user_id": "usr_abc123", "role": "owner", "email_verified": true, "api_key_count": 2, "created_at": "2026-06-03T00:00:00Z" } ], "plan": "growth", "max_members": 15, "admin_role": true}max_members is null for Enterprise (unlimited).
List pending invites
Section titled “List pending invites”GET /v1/team/invitesAuthorization: Bearer <jwt>Returns pending invites that have not expired or been accepted. Requires Owner or Admin role.
Response
{ "invites": [ { "invite_id": "inv_abc123", "role": "user", "inviter_id": "usr_xyz", "created_at": "2026-06-10T00:00:00Z", "expires_at": "2026-06-17T00:00:00Z" } ]}Send an invite
Section titled “Send an invite”POST /v1/team/invitesAuthorization: Bearer <jwt>Content-Type: application/jsonRequires Owner or Admin role. Sends an invite email with a 7-day accept link. If a pending invite already exists for this email, it is expired and a fresh one is created.
Body
{ "role": "user"}role must be "user" or "admin". Admin role requires a Growth or above plan — returns 402 otherwise.
Response 201
{ "invite_id": "inv_abc123", "role": "user", "expires_at": "2026-06-17T00:00:00Z"}Errors
| Status | Error | Meaning |
|---|---|---|
| 402 | — | Seat limit reached for plan — upgrade required |
| 402 | — | Admin role not available on this plan |
| 409 | — | This email is already a member |
Cancel an invite
Section titled “Cancel an invite”DELETE /v1/team/invites/:invite_idAuthorization: Bearer <jwt>Requires Owner or Admin role. Permanently deletes the pending invite.
Response 200
{ "cancelled": true }Preview an invite (public)
Section titled “Preview an invite (public)”GET /v1/team/invites/:token/previewNo authentication required. Used by the accept-invite page to show org name and role before the user sets a password.
Response 200
{ "invite_id": "inv_abc123", "role": "user", "org_name": "Acme AI", "expires_at": "2026-06-17T00:00:00Z"}Returns 404 if the token is not found or has expired.
Accept an invite (public)
Section titled “Accept an invite (public)”POST /v1/team/invites/:token/acceptContent-Type: application/jsonNo authentication required. Creates a new user account, marks the invite accepted, and returns a JWT for immediate login.
Body
{ "password": "your-password"}Password must be between 8 and 128 characters.
Response 201
{ "token": "<jwt>", "user": { "user_id": "usr_abc123", "org_id": "org_xyz", "role": "user", "email_verified": true }}Returns 400 if the token is expired or already accepted. Returns 409 if an account with this email already exists.
Change a member’s role
Section titled “Change a member’s role”PATCH /v1/team/members/:user_id/roleAuthorization: Bearer <jwt>Content-Type: application/jsonRequires Owner role.
Body
{ "role": "admin"}role must be "owner", "admin", or "user".
Response 200
{ "user_id": "usr_abc123", "role": "admin"}Returns 400 if attempting to demote the last owner. Returns 403 if the caller is not an owner.
Remove a member
Section titled “Remove a member”DELETE /v1/team/members/:user_idAuthorization: Bearer <jwt>Requires Owner or Admin role. Owners can remove anyone (except the last owner). Admins can only remove Users.
Response 200
{ "removed": true }Returns 400 if attempting to remove yourself or the last owner.
Create a personal API key
Section titled “Create a personal API key”POST /v1/team/members/:user_id/api-keysAuthorization: Bearer <jwt>Owners and Admins can create keys for any member. Users can only create keys for themselves. The full key value is returned once and cannot be retrieved again.
Response 201
{ "key_id": "kid_abc123", "key": "ctv_key_...", "created_at": "2026-06-10T00:00:00Z"}Revoke a personal API key
Section titled “Revoke a personal API key”DELETE /v1/team/members/:user_id/api-keys/:key_idAuthorization: Bearer <jwt>Owners and Admins can revoke keys for any member. Users can only revoke their own keys. Revocation is immediate.
Response 200
{ "revoked": true }List own API keys
Section titled “List own API keys”GET /v1/team/members/me/api-keysAuthorization: Bearer <jwt>Returns the current user’s active (non-revoked) personal API keys. Key values are masked — only a preview prefix is returned.
Response 200
{ "keys": [ { "key_id": "kid_abc123", "preview": "ctv_key_a1b2c3d4e5f6...", "created_at": "2026-06-10T00:00:00Z" } ]}