---
title: Endpoints
---

# Endpoints

All endpoints are hosted at `https://id.littlexlittle.org`. The discovery document at [`/.well-known/openid-configuration`](discovery.md) is the source of truth — read it at runtime rather than hardcoding paths.

| Method | Path | Spec | Auth |
|---|---|---|---|
| `GET`  | `/.well-known/openid-configuration` | OIDC Discovery | Public |
| `GET`  | `/.well-known/jwks.json` | RFC 7517 | Public |
| `GET`  | `/sdk.js` | LXL custom | Public |
| `GET`  | `/oidc/authorize` | OAuth 2.0 §4.1 | User session |
| `POST` | `/oidc/token` | OAuth 2.0 §4.1.3, §6 | Client (Basic or POST) |
| `GET`  | `/oidc/userinfo` | OIDC Core §5.3 | Bearer access_token |
| `POST` | `/oidc/revoke` | RFC 7009 | Client |
| `POST` | `/oidc/introspect` | RFC 7662 | Confidential client |
| `GET`  | `/oidc/logout` | OIDC RP-Logout 1.0 | Optional id_token_hint |
| `GET`  | `/oidc/iframe/check_session` | OIDC Session Mgmt 1.0 | Cookie |
| `GET`  | `/oidc/onetap` | LXL custom | Cookie |
| `GET`  | `/fedcm.json` | FedCM | Public |

---

## `GET /oidc/authorize`

Start the authorization code flow. The user is shown a consent screen if they have not previously consented to the requested scopes for this client.

### Query parameters

| Name | Required | Description |
|---|---|---|
| `response_type` | yes | Must be `code`. |
| `client_id` | yes | Your registered client identifier. |
| `redirect_uri` | yes | Must match a pre-registered redirect URI exactly. |
| `scope` | yes | Space-separated scopes. Must include `openid`. |
| `state` | recommended | Opaque CSRF token; echoed back verbatim. |
| `nonce` | recommended | Bound into the `id_token` to prevent replay. |
| `code_challenge` | required for public clients | base64url(SHA256(verifier)). |
| `code_challenge_method` | required if `code_challenge` set | Must be `S256`. |
| `prompt` | no | `none` \| `login` \| `consent` \| `select_account`. |
| `login_hint` | no | Account code or email to pre-fill. |
| `id_token_hint` | no | Previous id_token, used for silent re-auth. |
| `max_age` | no | Force re-auth if last login is older. |
| `ui_locales` | no | Space-separated BCP 47 locales. |

### Response

302 redirect to `redirect_uri` with either `?code=...&state=...` on success or `?error=...&error_description=...&state=...` on failure.

---

## `POST /oidc/token`

Exchange a code or refresh token for tokens.

### Body (form-encoded)

#### Authorization code

```http
grant_type=authorization_code
code=AUTH_CODE
redirect_uri=https://yoursite.org/cb
client_id=YOUR_CLIENT_ID
code_verifier=PKCE_VERIFIER          (public clients)
client_secret=YOUR_SECRET            (confidential clients, alt: HTTP Basic)
```

#### Refresh

```http
grant_type=refresh_token
refresh_token=REFRESH
client_id=YOUR_CLIENT_ID
client_secret=YOUR_SECRET            (confidential clients)
scope=openid profile email           (optional, narrows scope)
```

### Response

```json
{
  "access_token":  "...",
  "refresh_token": "...",
  "id_token":      "eyJ...",
  "token_type":    "Bearer",
  "expires_in":    3600,
  "scope":         "openid profile email"
}
```

---

## `GET /oidc/userinfo`

Returns the user claims authorized by the access token's scopes.

```bash
curl https://id.littlexlittle.org/oidc/userinfo \
  -H "Authorization: Bearer ACCESS_TOKEN"
```

```json
{
  "sub": "Bootim",
  "email": "you@example.org",
  "email_verified": true,
  "name": "Jane Doe",
  "picture": "https://cdn.littlexlittle.org/u/Bootim.jpg",
  "lxl.app": "bootim",
  "lxl.access": ["Website:Media", "Donations:View"]
}
```

---

## `POST /oidc/revoke`

[RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009). Revoke an access or refresh token.

```http
token=THE_TOKEN
token_type_hint=access_token | refresh_token   (optional)
client_id=YOUR_CLIENT_ID
client_secret=YOUR_SECRET                       (confidential clients)
```

Always returns `200` with empty body. Revoking a refresh token revokes the entire chain.

---

## `POST /oidc/introspect`

[RFC 7662](https://datatracker.ietf.org/doc/html/rfc7662). Confidential clients only.

```http
token=THE_TOKEN
token_type_hint=access_token
```

```json
{
  "active": true,
  "scope": "openid profile email",
  "client_id": "your-client-id",
  "username": "Bootim",
  "exp": 1714683600,
  "iat": 1714680000,
  "sub": "Bootim",
  "aud": "your-client-id",
  "iss": "https://id.littlexlittle.org"
}
```

---

## `GET /oidc/logout`

[OIDC RP-Initiated Logout 1.0](https://openid.net/specs/openid-connect-rpinitiated-1_0.html). See the [logout guide](../guides/logout.md).

| Param | Description |
|---|---|
| `id_token_hint` | The user's id_token (recommended). |
| `post_logout_redirect_uri` | Where to send them after sign-out. Must be registered. |
| `state` | Echoed back. |
| `client_id` | Required if `id_token_hint` is omitted. |
