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

# OAuth 2.1 (AI Clients)

> Authenticate AI assistants like Claude and ChatGPT using OAuth 2.1 with PKCE

Sessionboard supports OAuth 2.1 with PKCE for authenticating AI assistants (Claude, ChatGPT, and other MCP-compatible clients). This enables users to authorize AI tools to query their event data through a secure, permission-based flow.

## How It Works

```
1. AI client redirects user to Sessionboard consent page
2. User logs in, selects organization, approves requested scopes
3. Sessionboard redirects back with an authorization code
4. AI client exchanges the code for access + refresh tokens
5. AI client uses the access token for MCP queries
```

## Endpoints

All OAuth endpoints are on `public-api.sessionboard.com` (US) or `public-api-eu.sessionboard.com` (EU).

| Endpoint | Method | Description |
| - | - | - |
| `/oauth/authorize` | GET | Validate authorization request parameters |
| `/oauth/authorize/consent` | POST | User approves — generates authorization code |
| `/oauth/eligible-orgs` | GET | List orgs where the user has the Connect AI assistants permission |
| `/oauth/token` | POST | Exchange code for tokens, refresh tokens |
| `/oauth/revoke` | POST | Revoke access or refresh tokens |
| `/oauth/.well-known/oauth-authorization-server` | GET | RFC 8414 server metadata |

## Authorization Request

Redirect the user to the authorization endpoint with these parameters:

```
GET /oauth/authorize?
  client_id=your-client-id&
  redirect_uri=https://your-app.com/callback&
  response_type=code&
  scope=read:events+read:sessions+read:contacts&
  code_challenge=<S256_HASH>&
  code_challenge_method=S256&
  state=<random_state>
```

| Parameter | Required | Description |
| - | - | - |
| `client_id` | Yes | Your registered OAuth client ID |
| `redirect_uri` | Yes | Must match a registered redirect URI |
| `response_type` | Yes | Must be `code` |
| `scope` | No | Space-separated scopes (defaults to client's registered scopes) |
| `code_challenge` | Yes | PKCE challenge (S256 method) |
| `code_challenge_method` | Yes | Must be `S256` |
| `state` | Recommended | Opaque value for CSRF protection |

## Token Exchange

Exchange the authorization code for tokens:

```bash cURL theme={null}
curl -X POST https://public-api.sessionboard.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "AUTHORIZATION_CODE",
    "redirect_uri": "https://your-app.com/callback",
    "client_id": "your-client-id",
    "code_verifier": "YOUR_PKCE_VERIFIER"
  }'
```

**Response:**

```json theme={null}
{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...",
  "scope": "read:events read:sessions read:contacts"
}
```

## Refresh Tokens

Access tokens expire after 1 hour. Use the refresh token to get a new one:

```bash theme={null}
curl -X POST https://public-api.sessionboard.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "YOUR_REFRESH_TOKEN",
    "client_id": "your-client-id"
  }'
```

Refresh tokens expire after 7 days and are rotated on each use (the old token is revoked).

A refresh is refused with `400` and `"error": "invalid_grant"` when the refresh token is unknown, expired or already used, or when the user is no longer an active member of the organization. In each case, send the user through the authorization flow again.

## Using the Token

Include the access token as a Bearer token on API requests:

```bash theme={null}
curl https://public-api.sessionboard.com/v1/events \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Bearer tokens work on all `/v1/` endpoints alongside the existing `x-access-token` header authentication.

## Token Revocation

Revoke a token when the user disconnects:

```bash theme={null}
curl -X POST https://public-api.sessionboard.com/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{
    "token": "TOKEN_TO_REVOKE",
    "token_type_hint": "access_token"
  }'
```

## Available Scopes

| Scope | Description |
| - | - |
| `read:events` | View events and event details |
| `read:sessions` | View session data including titles, times, tracks, and statuses |
| `read:contacts` | View contact, participant, exhibitor, and sponsor information |
| `read:reports` | View and run saved custom reports |
| `read:dashboards` | View dashboards and widget data |
| `read:insights` | Query Reports / Dashboards data with SbQL and natural language |
| `read:transcriptions` | View session transcriptions and audio recordings |
| `read:media` | View uploaded media items and transcription status |
| `read:awards` | View Awards programs, categories, rounds, promo codes, submissions, and reviews |
| `read:registrations` | View registration forms, ticket types, registrations, orders, payment records, membership, attendees, check-ins and registration setup (preview) |
| `read:expo` | View floor-map booths and sponsorship inventory (preview) |
| `read:ask` | Ask questions about an event and get cited answers (MCP `ask_event`) |
| `write:sessions` | Create, update, and delete sessions |
| `write:contacts` | Create, update, and delete contacts |
| `write:exhibitors` | Create, update, and delete exhibitors |
| `write:sponsors` | Create, update, and delete sponsors |
| `write:fields` | Create, update, and delete custom fields |
| `write:metadata` | Rooms, tracks, tags, formats, levels, languages, and statuses |
| `write:events` | Dashboards, reports, agenda drafts, rules, and personas |
| `write:awards` | Create, update, and delete Awards programs, categories, rounds, promo codes, and submissions |
| `write:registrations` | Create and update ticket types, place registration orders, approve, decline, or cancel registrations, and check people in (preview) |
| `write:expo` | Update booths: hold, reserve, sell, block, release, and assign to exhibitors and sponsors (preview) |

> [!NOTE]
>
> The consent screen is where these scopes are approved. Dynamic client registration grants the scopes the server advertises, including the write scopes above. `write:transcriptions` and `write:media` are API-token scopes only. The preview scopes `read:registrations`, `write:registrations`, `read:expo` and `write:expo` are not listed in `scopes_supported` and are not granted by default: a client gets them only by naming them in its `scope` request. They answer only for events with Registration (or Expo) turned on.

## Permission Model

OAuth tokens inherit the authorizing user's permissions:

* **Organization admin with Connect AI assistants** → token can query all events in the org
* **Event-only user with Connect AI assistants** → token scoped to their permitted events
* **Connect AI assistants revoked** → token stops working immediately (checked on every request)
* **User deactivated in or removed from the organization** → token stops working immediately (`401`, "User is no longer an active member of this organization"), and refreshing it fails with `invalid_grant`. The user must reconnect after being reactivated.
* **AI features disabled for org** → all OAuth tokens for that org are blocked

API tokens (`x-access-token`) belong to the organization, not to a user, so they are not affected when the person who created them leaves.

The **Connect AI assistants** permission (in your organization's role settings) controls who can authorize OAuth connections. It is enabled by default for Admin roles.

## Server Metadata

Discover OAuth server capabilities at:

```
GET /oauth/.well-known/oauth-authorization-server
```

Returns supported response types, grant types, scopes, and endpoint URLs per [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.