> ## 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.

# Onboarding flow

> Invite someone, put them in groups, and grant them access before they accept.

Inviting someone through the API creates the user straight away. That is the part worth knowing before you build anything: an invitation is not a pending email with nothing behind it — it provisions a user and associates them with your organization at the moment you send it.

So you can finish somebody's onboarding in one run of your script and they walk into a workspace that is already set up for them.

<Info>
  Inviting requires an [API key](https://app.nekt.ai/settings/api-keys) created by an **Owner** or an **Admin**. A key created by a Member cannot invite. See [the ceiling rule](/platform-api/permissions/overview#the-ceiling-rule).
</Info>

***

## What "pending" means

An invited user exists in three states, and the difference matters when you read them back:

| State           | `is_active` | `is_pending` | What they can do                        |
| --------------- | ----------- | ------------ | --------------------------------------- |
| **Invited**     | `false`     | `true`       | Hold groups and grants. Cannot sign in. |
| **Active**      | `true`      | `false`      | Everything their role and grants allow. |
| **Deactivated** | `false`     | `false`      | Nothing. Grants are gone.               |

A pending user is deliberately **not active**. Anything that counts the people in your organization — seat counts, the billing contact, member lists — leaves them out until they accept. What they *can* do is receive access, so that the moment they accept, everything is already there.

<Note>
  Because pending is not active, an invitee never appears in a count of your members and is never billed for. Accepting is what moves them.
</Note>

***

## The flow

<Steps>
  <Step title="Invite">
    Only `email` is required. `role` defaults to `member`. If you do not know the person's name yet, leave it out — they will set it themselves when they accept.

    ```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": "analyst@example.com", "role": "member"}'
    ```

    See [Invite User](/platform-api/invitations/invite).
  </Step>

  <Step title="Find them as a recipient">
    The invitee now appears in the recipients endpoints alongside your existing members, which is what makes the next two steps possible.

    ```bash theme={null}
    curl --request GET \
      --url "https://api.nekt.ai/api/v1/permission-recipients/?expand[]=users&search=analyst@example.com" \
      --header "x-api-key: YOUR_API_KEY"
    ```

    Keep the `id` from the response — groups and grants both target it.
  </Step>

  <Step title="Grant access">
    Grants work exactly as they do for an accepted member, on all three axes.

    You can grant to the invitee directly, or grant to a **group** — if they are already in one, whatever that group can reach, they can reach.

    ```bash theme={null}
    curl --request POST \
      --url https://api.nekt.ai/api/v1/permissions/ \
      --header "x-api-key: YOUR_API_KEY" \
      --header "Content-Type: application/json" \
      --data '{
        "assignments": [
          {"permission_level": "viewer", "users": ["USER_ID"], "layers": ["LAYER_ID"]}
        ]
      }'
    ```

    See [Permissions flow](/platform-api/permissions/overview).

    <Note>
      **A group is usually the better target.** Grant the group once, then put the invitee in it —
      they inherit everything it holds, and so does the next user you add. Pending invitees can
      be grouped before they accept, exactly like accepted members. See
      [Add Members](/platform-api/permission-groups/add-members).
    </Note>
  </Step>

  <Step title="They accept">
    The invitation email carries the link. Accepting sets their credential and clears the pending state.

    **No permission is created, moved, or replayed at this point.** Everything you granted is already attached to them, which is why acceptance cannot half-fail and leave someone with the wrong access.
  </Step>
</Steps>

***

## Onboard someone end to end

```python theme={null}
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.nekt.ai"
EMAIL = "analyst@example.com"
GOLD_LAYER = "e4d5c6b7-a8b9-40c1-d2e3-f4a5b6c7d8e9"

headers = {"x-api-key": API_KEY, "Content-Type": "application/json"}

requests.post(
    f"{BASE_URL}/api/v1/invitations/",
    headers=headers,
    json={"email": EMAIL, "role": "member"},
).raise_for_status()

# The invitee is a recipient from this moment on, so the id is available immediately.
recipients = requests.get(
    f"{BASE_URL}/api/v1/permission-recipients/",
    headers=headers,
    params={"expand": "users", "search": EMAIL},
).json()
user_id = recipients["users"][0]["id"]

requests.post(
    f"{BASE_URL}/api/v1/permissions/",
    headers=headers,
    json={
        "assignments": [
            {"permission_level": "viewer", "users": [user_id], "layers": [GOLD_LAYER]}
        ]
    },
).raise_for_status()
```

***

## Things worth knowing before you build

**Only Members appear as permission recipients.** Invite someone as `admin` or `owner` and they will not show up in the recipients endpoints — not because the invitation failed, but because Owners and Admins bypass data-level permissions entirely, so there is nothing to grant them. Invite as `member` when you intend to grant.

**Expiry does not revoke.** The email link expires after seven days; the access does not. Resending re-opens the link and keeps every group and grant already attached, so you never re-grant on a resend.

**Revoking is destructive.** It removes every grant on all three axes, and every group membership — and deletes the user if this was their only pending invitation. It is not the same as letting an invitation lapse. See [Revoke an Invitation](/platform-api/invitations/revoke).

**Someone who already has a Nekt account keeps it.** Inviting an existing user to a second organization adds a membership; it does not create a second user or touch their name or password.

***

## Related

* [Invite User](/platform-api/invitations/invite) — including resending and changing the role.
* [List Invitations](/platform-api/invitations/list) — the outstanding ones.
* [Revoke an Invitation](/platform-api/invitations/revoke) — and what it takes back.
* [Permissions flow](/platform-api/permissions/overview) — the three grant axes.
* [Members](/workspace/members) — what each role can do, in the app.
