---
title: "Issue a partner invite"
method: POST
path: "/v1/invites/partner/"
tags: ["invites"]
---

# Issue a partner invite

`POST /v1/invites/partner/`

## Request

- Base URL: `https://api.ethiack.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.ethiack.com/v1/invites/partner/`
- Auth: none declared

Issue a partner invite and send its email.

Args:
    body (CreatePartnerInviteRequest): Invitee email, partner, role.
    db (AsyncSession): Request-scoped database session.
    context (ActiveContext): Resolved caller identity and scope.

Returns:
    PartnerInviteResponse: The issued invite (never the token).

## Request body

- CreatePartnerInviteRequest: Body for ``POST /v1/invites/partner``. Attributes: email (EmailStr): Invitee email address. partner_id (int): Target partner (Cerbos scopes a partner manager to their own; admins may target any). role (PartnerRole): Membership role granted on redemption; must be an invitable role (``owner`` is rejected).
  - `email` string, email, required
  - `partner_id` integer, required
  - `role` 'owner' | 'admin' | 'billing_manager' | 'technical_manager', required: Sub-role within a :data:`ActorKind.PARTNER` context. Snake_case wire values are used in the DB, in JWT claims synced from Zitadel, and as components of Cerbos role strings (e.g. ``"partner_owner"``). Attributes: OWNER: Full authority over the partner account. ADMIN: Administrative authority below the owner. BILLING_MANAGER: Limited to billing-related operations. TECHNICAL_MANAGER: Technical operations on managed orgs (reports, scope) without billing authority.

## Response `201`

Successful Response

- PartnerInviteResponse: A partner invite as managers see it (never the token). Attributes: partner_id (int): Target partner. role (PartnerRole): Membership role granted on redemption.
  - `id` integer, required
  - `kind` 'organization' | 'partner' | 'triager', required: Which user kind an account invite grants on redemption. Doubles as the joined-table-inheritance discriminator: ``TRIAGER`` is the base :class:`Invite` (no grant payload); ``ORGANIZATION`` / ``PARTNER`` select the typed child. Attributes: ORGANIZATION: Membership in the invite's organization. PARTNER: Membership in the invite's partner. TRIAGER: The triager kind (platform-scoped, no payload).
  - `email` string, required
  - `status` 'pending' | 'redeemed' | 'revoked', required: The single terminal-state of an invite's lifecycle. A live invite is ``PENDING``; it moves once, irreversibly, to exactly one terminal state. Modelling this as one enum (rather than separate per-outcome timestamps) makes "redeemed AND revoked" unrepresentable rather than merely constraint-guarded, and mirrors :class:`~phoenix.db.models.pentest_hacker_invite.PentestHackerInviteStatus`. Expiry is NOT a member — it is passive and time-derived from ``expires_at``. Attributes: PENDING: Live and awaiting redemption (paired with a null ``resolved_at``). REDEEMED: Consumed by its invitee. REVOKED: Rescinded by a manager before redemption.
  - `created_at` string, date-time, required
  - `expires_at` string, date-time, required
  - `resolved_at` string, date-time, nullable, required
  - `redeemed_by_user_id` string, nullable, required
  - `expired` boolean, required
  - `live` boolean, required
  - `partner_id` integer, required
  - `role` 'owner' | 'admin' | 'billing_manager' | 'technical_manager', required: Sub-role within a :data:`ActorKind.PARTNER` context. Snake_case wire values are used in the DB, in JWT claims synced from Zitadel, and as components of Cerbos role strings (e.g. ``"partner_owner"``). Attributes: OWNER: Full authority over the partner account. ADMIN: Administrative authority below the owner. BILLING_MANAGER: Limited to billing-related operations. TECHNICAL_MANAGER: Technical operations on managed orgs (reports, scope) without billing authority.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/ethiack/apis/ethiack-api.md) - [All operations](https://skmtc.dev/ethiack/apis/ethiack-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ethiack/apis/ethiack-api/revisions/4eaba89bfebf?raw)
