---
audience: developer
summary: Sign-in, registration, refresh, OIDC config.
title: Auth API
path: reference/api/auth
status: published
---

# Auth API

5 endpoints. All under `/v1/auth/`. See
[Authenticate with ScaiKey](/docs/scaiwave/tutorials/developer/authenticate-with-scaikey)
for the overview.

| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | `/v1/auth/config` | None | Discover the OIDC config (issuer, JWKS URI, supported scopes). |
| POST | `/v1/auth/login` | None | Exchange an OIDC `code` for tokens. |
| POST | `/v1/auth/token` | None | Direct password grant (if enabled). |
| POST | `/v1/auth/refresh` | None (refresh token in body) | Rotate access token. |
| POST | `/v1/auth/register` | Bearer | Create / refresh the local participant for the bearer's principal. |

## GET /v1/auth/config

Returns the tenant's OIDC config for the client to bootstrap.

```bash
curl https://your-host/v1/auth/config
```

```jsonc
{
  "data": {
    "issuer": "https://scaikey.example.com",
    "authorization_endpoint": "https://scaikey.example.com/auth",
    "token_endpoint": "https://scaikey.example.com/token",
    "scopes_supported": ["openid", "profile", "email"],
    "redirect_uri": "https://scaiwave.example.com/v1/auth/login"
  }
}
```

## POST /v1/auth/login

Server-side OIDC code exchange. Body: `code` (query param or form
field).

```bash
curl -X POST https://your-host/v1/auth/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=$AUTH_CODE&redirect_uri=$REDIRECT"
```

```json
{
  "data": {
    "access_token": "eyJ...",
    "refresh_token": "...",
    "token_type": "Bearer",
    "expires_in": 3600
  }
}
```

Errors:

- `SW_AUTH_OIDC_FAILED` — code invalid / expired.
- `SW_AUTH_REDIRECT_MISMATCH` — `redirect_uri` doesn't match config.

## POST /v1/auth/token

Direct password grant. Disabled by default; enable per-tenant with
`features.auth.password_grant_enabled = true`.

```bash
curl -X POST https://your-host/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&username=$USER&password=$PASS"
```

## POST /v1/auth/refresh

```bash
curl -X POST https://your-host/v1/auth/refresh \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "refresh_token=$REFRESH"
```

Returns the same shape as `/login`. Rotates the refresh token if
your config has rotation enabled.

## POST /v1/auth/register

Idempotent: creates a `Participant` row for the bearer's principal
if one doesn't exist. Always safe to call on first sign-in.

```bash
curl -X POST https://your-host/v1/auth/register \
  -H "Authorization: Bearer $TOKEN"
```

```json
{
  "data": {
    "participant_id": "5e4d…",
    "tenant_id": "abc-…",
    "display_name": "alice",
    "email": "alice@example.com",
    "personal_workspace_id": "ws-…"
  }
}
```
