# Authentication

> How requests are authenticated, what the errors mean, and how request ids help support.

Canonical: https://grout.app/developer/documentation/setting-up/authentication/

Send the key as a bearer token on every request:

```http
GET /v1/students HTTP/1.1
Host: serverless.grout.app
Authorization: Bearer grt_live_k3JdP8x…
```

There is no session, cookie or refresh token. The key identifies the institution; nothing else in the request does.

## Response envelope

```json
{ "success": true, "data": { … } }
```

```json
{ "success": false, "error": "insufficient_scope", "message": "This endpoint requires scope(s): students:write",
  "required": ["students:write"], "missing": ["students:write"] }
```

Validation failures use `422 validation_error` with an `issues` array of `{ path, message }`.

## Errors

| Status | `error` | Meaning |
|---|---|---|
| 401 | `unauthorized` | No bearer token, or the token is not a `grt_` key |
| 401 | `invalid_api_key` | Unknown, revoked, expired, or institution not approved — deliberately indistinguishable |
| 403 | `insufficient_scope` | See `required` / `missing` |
| 404 | `not_found` | Resource does not exist **in your institution** |
| 409 | `conflict` and friends | State conflict (already added, already verified, insufficient allowance…) |
| 422 | `validation_error` and friends | Body or query invalid |
| 429 | `rate_limited` | Honour `Retry-After` |
| 500 | `internal_error` | Quote `X-Request-Id` to support |
| 503 | `rate_limiter_unavailable` | Transient; retry after 5 s |

## Request ids

Every response carries `X-Request-Id: req_…`. Log it next to your own correlation id. Support can trace a request end to end from it.

## CORS

Browser calls from `*.grout.app` origins are allowed, but a key must never be embedded in client-side code. Call the API from your server and expose only what your users need.

## Checking a key

`GET /v1/me` returns the key's name, scopes, rate limit and institution. Use it as a health check in your deploy pipeline:

```bash
curl -fsS https://serverless.grout.app/v1/me -H "Authorization: Bearer $GROUT_API_KEY" > /dev/null \
  && echo "key ok"
```
