# Nextstep API — Typed errors and rate limits

Nextstep public API failures use application/json with a stable code, a human-readable message and an error field retained for existing clients. Branch on code or the HTTP status; message text may improve over time. Database health failures also retain status: unavailable. Unknown public API paths include a documentation link. Explicit Markdown requests for missing resources receive a Markdown 404; API clients should request application/json.

```sh
{"code":"invalid_request","message":"limit must be an integer between 1 and 3.","error":"limit must be an integer between 1 and 3."}
```

## Error codes

400 invalid_request: correct the input. 403 forbidden: the request origin is disallowed. 404 not_found: check the documented path. 405 method_not_allowed: use GET or HEAD as indicated by Allow. 413 payload_too_large: reduce the request body. 415 unsupported_media_type: a submitted body requires application/json. 429 rate_limited: wait for Retry-After. 500 internal_error: retry with bounded exponential backoff. 503 unavailable: a temporary database, capacity or restart failure; honour Retry-After when supplied. The public read-only API does not require a request body.

## Quota and response headers

A client network receives 300 public API requests per 60-second fixed window, beginning with its first request. IPv4 addresses and IPv6 /64 networks identify clients. GET, HEAD and rejected requests share one quota across all public endpoints and legacy aliases. Counters are bounded, process-local and reset on restart; this is not an account-level distributed quota. Health probes at /api/ready and /api/live and private workspace APIs do not use this quota. Forwarded client addresses are trusted only when the deployment explicitly enables its trusted proxy setting.

```sh
RateLimit-Policy: "public-read";q=300;w=60
RateLimit: "public-read";r=299;t=60
```

The header syntax follows draft-ietf-httpapi-ratelimit-headers-11, an IETF Internet-Draft, not a finalized RFC. q is the request quota, w is the window in seconds, r is the remaining quota after the current request, and t is seconds until reset. An exhausted window returns HTTP 429 with Retry-After in seconds. Retry-After takes precedence over RateLimit timing. Cache stable metadata, avoid polling fictional records and add jitter to retries. Rate-limit headers are advisory snapshots, not a reservation for future calls.

- [OpenAPI specification](https://nextstep.fans/openapi.json): Named Error schema and documented response headers
- [Versioning policy](https://nextstep.fans/docs/versioning): Compatibility and retirement
- [Developer portal](https://nextstep.fans/developers): Quickstart
