---
title: "Invite Member"
method: POST
path: "/teams/{team_id}/invitations"
tags: ["teams"]
---

# Invite Member

`POST /teams/{team_id}/invitations`

Invite a user to join a team.

Requires owner, admin, or billing role. Owner-role invitations are
rejected; ownership can only be transferred to an existing team member.
Supports pre-signup invites (invitee doesn't need an account yet).

**Accepted risk (ENG-1281):** AAL2 enforcement was intentionally removed
(PR #3928) — users without MFA enrolled were being blocked from routine
team operations. Inviting an attacker-controlled email as
``admin``/``billing`` is the cleanest L-A16 escalation path: the
attacker accepts on their own AAL2 account and instantly has
MANAGE_BILLING on the victim team. This risk is accepted per the design
decision.

## Path parameters

- `team_id` string, required

## Request body

- TeamInvitationCreate — Request model for inviting a member to a team.
  - `email` string, email, required — Email address of the person to invite
  - `role` 'owner' | 'billing' | 'admin' | 'editor' | 'viewer' — Team member roles with hierarchical permissions. Wire DTO mirror of the ORM ``TeamRoleType`` enum. Used only for API request/response serialization; authorization decisions route through the ORM matrix (``database_tables.permissions``), never this enum.

## Response `200`

Successful Response

- TeamInvitationResponse — Response model for a team invitation.
  - `id` string, required
  - `team_id` string, required
  - `team_name` string, required
  - `email` string, required
  - `role` 'owner' | 'billing' | 'admin' | 'editor' | 'viewer', required — Team member roles with hierarchical permissions. Wire DTO mirror of the ORM ``TeamRoleType`` enum. Used only for API request/response serialization; authorization decisions route through the ORM matrix (``database_tables.permissions``), never this enum.
  - `status` 'pending' | 'accepted' | 'declined' | 'expired', required — Status of a team invitation.
  - `invited_by` string, required
  - `inviter_name` string, nullable
  - `inviter_email` string, nullable
  - `created_at` string, required
  - `expires_at` string, required
  - `email_sent` boolean — Whether the invitation email was successfully handed off to SendGrid. Only meaningful on the create-invite response; list endpoints do not track historical delivery and default to True.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/pioneer/apis/brain-api.md) · [All operations](https://skmtc.net/pioneer/apis/brain-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/pioneer/brain-api/versions/31dfe831e079/schema)
