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

# Auth API Reference

> API endpoints for team management, token operations, and user preferences

All endpoints require authentication via Supabase JWT in the `Authorization: Bearer <token>` header. Org context is resolved from the JWT's user membership.

## Team Management

### Invite Member

<ParamField body="email" type="string" required>
  Email address of the user to invite.
</ParamField>

<ParamField body="role" type="string" required>
  Role to assign. One of: `owner`, `admin`, `analyst`, `viewer`. Cannot exceed your own role level.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.quintai.dev/v1/team \
    -H "Authorization: Bearer $QUINT_JWT" \
    -H "Content-Type: application/json" \
    -d '{
      "email": "analyst@company.com",
      "role": "analyst"
    }'
  ```

  ```json 201 Response theme={null}
  {
    "id": "mem_abc123",
    "email": "analyst@company.com",
    "role": "analyst",
    "status": "pending",
    "invited_at": "2026-04-12T10:00:00Z"
  }
  ```
</CodeGroup>

<ResponseField name="id" type="string">
  Membership ID.
</ResponseField>

<ResponseField name="status" type="string">
  Either `pending` (invite sent, not yet claimed) or `active` (user has logged in and claimed the invite).
</ResponseField>

***

### List Members

Returns all members of your organization, including pending invites.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.quintai.dev/v1/team \
    -H "Authorization: Bearer $QUINT_JWT"
  ```

  ```json 200 Response theme={null}
  {
    "members": [
      {
        "id": "mem_abc123",
        "email": "owner@company.com",
        "role": "owner",
        "status": "active",
        "joined_at": "2026-03-01T08:00:00Z"
      },
      {
        "id": "mem_def456",
        "email": "analyst@company.com",
        "role": "analyst",
        "status": "pending",
        "invited_at": "2026-04-12T10:00:00Z"
      }
    ]
  }
  ```
</CodeGroup>

***

### Update Member Role

<ParamField path="id" type="string" required>
  Membership ID of the member to update.
</ParamField>

<ParamField body="role" type="string" required>
  New role. Cannot exceed your own role level.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://api.quintai.dev/v1/team/mem_def456 \
    -H "Authorization: Bearer $QUINT_JWT" \
    -H "Content-Type: application/json" \
    -d '{"role": "admin"}'
  ```

  ```json 200 Response theme={null}
  {
    "id": "mem_def456",
    "email": "analyst@company.com",
    "role": "admin",
    "updated_at": "2026-04-12T11:00:00Z"
  }
  ```
</CodeGroup>

<Warning>
  You cannot downgrade the last owner. The API returns `409 Conflict` if this would leave the org with no owners.
</Warning>

***

### Remove Member

<ParamField path="id" type="string" required>
  Membership ID to remove.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.quintai.dev/v1/team/mem_def456 \
    -H "Authorization: Bearer $QUINT_JWT"
  ```

  ```json 200 Response theme={null}
  {
    "deleted": true,
    "id": "mem_def456"
  }
  ```
</CodeGroup>

Removing a member also revokes all their personal tokens. Service and deploy tokens are unaffected.

***

## Token Operations

### Create Token

<ParamField body="name" type="string" required>
  Human-readable label for the token.
</ParamField>

<ParamField body="kind" type="string" required>
  Token type: `personal`, `service`, or `deploy`.
</ParamField>

<ParamField body="scopes" type="string[]" required>
  Array of scopes: `read`, `ingest`, `manage`, `admin`, `*`.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.quintai.dev/v1/tokens \
    -H "Authorization: Bearer $QUINT_JWT" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "CI Read-Only",
      "kind": "service",
      "scopes": ["read"]
    }'
  ```

  ```json 201 Response theme={null}
  {
    "id": "tok_abc123",
    "name": "CI Read-Only",
    "kind": "service",
    "scopes": ["read"],
    "token": "qt_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
    "created_at": "2026-04-12T10:00:00Z"
  }
  ```
</CodeGroup>

<Warning>
  The `token` field is returned only in this response. Store it securely -- it cannot be retrieved again.
</Warning>

***

### List Tokens

Returns all tokens for your organization. Raw token values are never included.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.quintai.dev/v1/tokens \
    -H "Authorization: Bearer $QUINT_JWT"
  ```

  ```json 200 Response theme={null}
  {
    "tokens": [
      {
        "id": "tok_abc123",
        "name": "CI Read-Only",
        "kind": "service",
        "scopes": ["read"],
        "created_by": "mem_abc123",
        "last_used_at": "2026-04-12T09:30:00Z",
        "created_at": "2026-04-10T08:00:00Z"
      }
    ]
  }
  ```
</CodeGroup>

***

### Revoke Token

<ParamField path="id" type="string" required>
  Token ID to revoke.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.quintai.dev/v1/tokens/tok_abc123 \
    -H "Authorization: Bearer $QUINT_JWT"
  ```

  ```json 200 Response theme={null}
  {
    "deleted": true,
    "id": "tok_abc123",
    "revoked_at": "2026-04-12T12:00:00Z"
  }
  ```
</CodeGroup>

Revocation is immediate. Any request using this token after revocation returns `401 Unauthorized`.

***

## User Preferences

### Get Preferences

Returns the current user's preferences for the organization.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.quintai.dev/v1/preferences \
    -H "Authorization: Bearer $QUINT_JWT"
  ```

  ```json 200 Response theme={null}
  {
    "theme": "dark",
    "default_time_range": "24h",
    "default_view": "overview",
    "notifications": {
      "critical_alerts": true,
      "high_alerts": true,
      "browser_push": false,
      "email_digest": "daily"
    }
  }
  ```
</CodeGroup>

***

### Update Preferences

Performs a JSONB merge -- only the fields you send are updated. Omitted fields retain their current values.

<ParamField body="theme" type="string">
  `dark` or `light`.
</ParamField>

<ParamField body="default_time_range" type="string">
  Default time range for dashboards. One of: `1h`, `6h`, `24h`, `7d`, `30d`.
</ParamField>

<ParamField body="default_view" type="string">
  Landing page after login. One of: `overview`, `sessions`, `alerts`, `fleet`.
</ParamField>

<ParamField body="notifications" type="object">
  Notification preferences object. Merged with existing values.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://api.quintai.dev/v1/preferences \
    -H "Authorization: Bearer $QUINT_JWT" \
    -H "Content-Type: application/json" \
    -d '{
      "theme": "light",
      "notifications": {
        "browser_push": true
      }
    }'
  ```

  ```json 200 Response theme={null}
  {
    "theme": "light",
    "default_time_range": "24h",
    "default_view": "overview",
    "notifications": {
      "critical_alerts": true,
      "high_alerts": true,
      "browser_push": true,
      "email_digest": "daily"
    }
  }
  ```
</CodeGroup>

<Tip>
  The merge is shallow for top-level keys but deep for the `notifications` object. Sending `{"notifications": {"browser_push": true}}` updates only `browser_push` without touching other notification settings.
</Tip>

***

## Error Responses

All endpoints return consistent error shapes:

| Status | Code                       | Meaning                                                          |
| ------ | -------------------------- | ---------------------------------------------------------------- |
| `400`  | `bad_request`              | Invalid input, missing required fields                           |
| `401`  | `unauthorized`             | Missing or invalid authentication                                |
| `403`  | `insufficient_permissions` | Valid auth but insufficient role level                           |
| `404`  | `not_found`                | Resource doesn't exist in your org                               |
| `409`  | `conflict`                 | Operation would violate a constraint (e.g., removing last owner) |
| `429`  | `rate_limited`             | Too many requests, retry after `Retry-After` header              |

```json theme={null}
{
  "error": "insufficient_permissions",
  "message": "Admin role required for this action",
  "status": 403
}
```
