> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nekt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Invite User

> Invite one person to your organization, or resend the invitation they already have.

Invites a single person to your organization. The same call also **resends** an existing invitation: posting an address that already has a live invitation resends it rather than creating a second one.

Inviting someone provisions them immediately as a **pending member**, so you can add them to permission groups and grant them access before they accept. See [Pending users and pre-granted invitations](#pending-users-and-pre-granted-invitations) below.

## Request body

| Parameter               | Type   | Required | Description                                                                            |
| ----------------------- | ------ | -------- | -------------------------------------------------------------------------------------- |
| `email`                 | string | Yes      | The address to invite. Normalized before storing, so casing never creates a duplicate. |
| `role`                  | string | No       | One of `owner`, `admin`, or `member`. Defaults to `member`.                            |
| `first_name`            | string | No       | Shown in the member list before the person accepts.                                    |
| `last_name`             | string | No       | Shown in the member list before the person accepts.                                    |
| `functional_area`       | string | No       | The invitee's functional area.                                                         |
| `other_functional_area` | string | No       | Free-text functional area, when none of the predefined options fit.                    |

<Note>
  `first_name` and `last_name` are optional. An admin often has only an address, and the person names themselves afterward from their profile or the onboarding step. The invitation email greets an unnamed invitee by their address.
</Note>

## Response

Returns the [Invitation](/platform-api/invitations/invitation) object. The status code tells you which of the two things happened:

* `201 Created` — a new invitation was created.
* `200 OK` — an existing invitation was resent.

## Example

```bash theme={null}
curl --request POST \
  --url https://api.nekt.ai/api/v1/invitations/ \
  --header "x-api-key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "email": "newcomer@example.com",
    "role": "member"
  }'
```

## Resending and role changes

Sending the same address again is safe and is how you chase someone who has not accepted. Nobody is duplicated: the existing invitation is resent with a fresh expiry, and the invitee's existing groups and grants are untouched.

If the `role` differs from the outstanding invitation, the resend is a role **change** — it moves the person on both the invitation and their pending membership.

<Warning>
  Moving an existing `admin` or `owner` invitee to another role requires an owner. This is the same ceiling that applies to changing the role of an accepted member.
</Warning>

## Pending users and pre-granted invitations

Because an invitation provisions the person right away, they exist as a pending member the moment the call succeeds:

* **Grant access before acceptance.** A pending member is a normal target for the group editor and every permission-assign endpoint — no separate flow.
* **Pending is not inactive.** In the member list a pending member carries its own status; it is not the same as a deactivated user.
* **They cannot log in until they accept.** The invitation token is the only proof that the person controls the address.
* **Revoking is destructive.** Revoking (see [Errors](#authentication)) removes the invitee's groups and grants, not just the email.

The invitation email expires after 7 days; the pre-granted access does not. An admin resends and nothing has to be re-granted.

## Authentication

This endpoint requires an [API key](/platform-api/introduction#create-an-api-key) in the `x-api-key` header.

Only an **owner or an admin** can invite, and nobody can invite somebody to a role above their own. For an API key, that ceiling is read from the role of the user who created the key.

## Errors

| Status | When                                                                                                   |
| ------ | ------------------------------------------------------------------------------------------------------ |
| `400`  | The address already belongs to an active member of the organization.                                   |
| `400`  | `email` is missing or malformed.                                                                       |
| `403`  | The caller is a member, or the request names a role above the caller's own.                            |
| `403`  | The request changes the role of an existing `admin` or `owner` invitee and the caller is not an owner. |

## Related

* [Bulk Invite Users](/platform-api/invitations/bulk-invite) — invite several people in one call.
* [Invitation object](/platform-api/invitations/invitation) — the full response schema.


## OpenAPI

````yaml POST /api/v1/invitations/
openapi: 3.0.3
info:
  title: Nekt API
  version: v1
  description: Nekt API Documentation
  contact:
    email: support@nekt.ai
servers:
  - url: https://api.nekt.ai
security: []
paths:
  /api/v1/invitations/:
    post:
      tags:
        - v1
      description: >-
        Invite one person, or resend the invitation they already have.


        `create` rather than `perform_create` because the status code depends on
        which of the two

        happened, and `perform_create` cannot influence it -- `CreateModelMixin`
        discards what it

        returns and answers 201 either way. A resend creates nothing, so it
        answers 200.
      operationId: v1_invitations_create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Invitation'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Invitation'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Invitation'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invitation'
          description: ''
      security:
        - ApiKeyAuth: []
components:
  schemas:
    Invitation:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        first_name:
          type: string
          maxLength: 150
        last_name:
          type: string
          maxLength: 150
        email:
          type: string
          format: email
          title: Email address
          maxLength: 254
        role:
          allOf:
            - $ref: '#/components/schemas/RoleEnum'
          default: member
          description: >-
            Defaults to `member`. You cannot invite somebody to a role above
            your own, and on the Free plan only owners can be invited.


            * `owner` - Owner

            * `admin` - Admin

            * `member` - Member
        functional_area:
          nullable: true
          oneOf:
            - $ref: '#/components/schemas/FunctionalAreaEnum'
            - $ref: '#/components/schemas/BlankEnum'
            - $ref: '#/components/schemas/NullEnum'
        other_functional_area:
          type: string
          nullable: true
          maxLength: 128
        sent_at:
          type: string
          format: date-time
          readOnly: true
        expires_at:
          type: string
          format: date-time
          readOnly: true
        accepted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        revoked_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        created_by:
          allOf:
            - $ref: '#/components/schemas/OrganizationUser'
          readOnly: true
      required:
        - accepted_at
        - created_at
        - created_by
        - email
        - expires_at
        - id
        - revoked_at
        - sent_at
    RoleEnum:
      enum:
        - owner
        - admin
        - member
      type: string
      description: |-
        * `owner` - Owner
        * `admin` - Admin
        * `member` - Member
    FunctionalAreaEnum:
      enum:
        - data_analytics
        - sales
        - customer_support
        - operations
        - marketing
        - finance
        - product_development
        - growth
        - executive_leadership
        - other
      type: string
      description: |-
        * `data_analytics` - Data & Analytics
        * `sales` - Sales
        * `customer_support` - Customer Support
        * `operations` - Operations
        * `marketing` - Marketing
        * `finance` - Finance
        * `product_development` - Product Development
        * `growth` - Growth
        * `executive_leadership` - Executive Leadership
        * `other` - Other
    BlankEnum:
      enum:
        - ''
    NullEnum:
      enum:
        - null
    OrganizationUser:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        first_name:
          type: string
          readOnly: true
        last_name:
          type: string
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
          title: Email address
        picture:
          type: string
          format: uri
          readOnly: true
          nullable: true
        role:
          type: string
          readOnly: true
        functional_area:
          readOnly: true
          nullable: true
          oneOf:
            - $ref: '#/components/schemas/FunctionalAreaEnum'
            - $ref: '#/components/schemas/NullEnum'
        other_functional_area:
          type: string
          readOnly: true
          nullable: true
        date_joined:
          type: string
          format: date-time
          readOnly: true
        last_login:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        is_active:
          type: boolean
          readOnly: true
          default: false
        is_pending:
          type: boolean
          readOnly: true
          default: false
      required:
        - date_joined
        - email
        - first_name
        - functional_area
        - id
        - is_active
        - is_pending
        - last_login
        - last_name
        - other_functional_area
        - picture
        - role
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: 'API Key authentication. Format: ''x-api-key: api_key'''

````