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

# User Provisioning

> Provision end-user accounts and organization memberships for partner integrations

## Overview

The User Provisioning API lets trusted partner services create (or look up) Junis user
accounts by email and attach them to the partner's organization as **pending members** —
reusing the standard invite flow, so the user's first Google login automatically
activates the membership and links their Google account.

<Warning>
  **Opt-in scope required**: This endpoint requires the `users:provision` scope, which is
  **never** included in any default scope set. It must be explicitly granted to the API key.
  The key's backing user must also be an **owner or admin** of the organization.
</Warning>

<Note>
  Provisioned accounts do **not** receive the signup credit bonus and do not have a
  memory profile until the user actually logs in with Google for the first time.
</Note>

***

## Endpoint

```
POST https://api.junis.ai/api/external/management/users
```

### Authentication

Include your API key in the `X-API-Key` header:

```bash theme={null}
X-API-Key: jns_live_YOUR_API_KEY_HERE
```

### Request Parameters

| Parameter         | Type   | Required | Description                                              |
| ----------------- | ------ | -------- | -------------------------------------------------------- |
| `email`           | string | **Yes**  | Email of the user to provision (normalized to lowercase) |
| `name`            | string | No       | Display name (defaults to the email local part)          |
| `organization_id` | string | **Yes**  | Must match the organization your API key resolves to     |

### Example Request

```bash theme={null}
curl -X POST https://api.junis.ai/api/external/management/users \
  -H "X-API-Key: jns_live_YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "name": "Alice",
    "organization_id": "org-uuid"
  }'
```

### Response

```json theme={null}
{
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "alice@example.com",
  "created": true,
  "membership_status": "pending"
}
```

| Field               | Type    | Description                                                        |
| ------------------- | ------- | ------------------------------------------------------------------ |
| `user_id`           | string  | Junis user ID — usable as `on_behalf_of` in Chat Completions       |
| `email`             | string  | Normalized email                                                   |
| `created`           | boolean | `true` if a new account was created, `false` if it already existed |
| `membership_status` | string  | `pending` (awaiting first login) or `active`                       |

***

## Behavior

<Steps>
  <Step title="Create-or-get user">
    If a user with the email already exists, it is returned unchanged (`created: false`).
    Otherwise a new account is created with `google_id = NULL` — no signup bonus,
    no memory profile (both happen on the real first login).
  </Step>

  <Step title="Ensure pending membership">
    If the organization has no membership row for this email, a `pending` invite with the
    `member` role is created — identical to inviting the user from the dashboard.
  </Step>

  <Step title="First Google login links everything">
    When the user signs in with Google using that email, the account is linked to their
    Google identity, the pending membership is activated, and the invited organization
    becomes their current organization.
  </Step>
</Steps>

The endpoint is **idempotent** — calling it repeatedly for the same email returns the
same user and membership state.

***

## Errors

| Status | Code                  | Description                                                                                        |
| ------ | --------------------- | -------------------------------------------------------------------------------------------------- |
| `403`  | `insufficient_scopes` | API key lacks the `users:provision` scope                                                          |
| `403`  | —                     | Key's organization does not match `organization_id`, or the backing user is not an org admin/owner |
| `422`  | —                     | Invalid email address                                                                              |

***

## Acting on Behalf of Provisioned Users

Use the returned `user_id` as `on_behalf_of` in
[Chat Completions](/api-reference/chat-completions) (requires the `users:delegate` scope).
Sessions and messages belong to the provisioned user, while subscription checks and
credit charges stay with your API key's backing user. Pending members are allowed, so
delegation works before the user's first login.
