# Changelog

> What changed, when. The APIs change additively; anything that would break an integration is announced here before it ships.

- **HTML:** https://offendersearch.app/docs/changelog
- **Base URL (live):** https://api.offendersearch.app — live keys (`os_live_…`)
- **Base URL (sandbox):** https://sandbox.offendersearch.app — test keys (`os_test_…`), never billed
- **Authentication:** `X-API-Key` request header
- **OpenAPI:** https://offendersearch.app/openapi.json · https://offendersearch.app/openapi.yaml
- **Docs index for agents:** https://offendersearch.app/llms.txt

## Entries

Entries are recorded from October 2026. Earlier changes are reflected in the reference pages themselves.

| Date | Product | Change |
| --- | --- | --- |
| 2026-10-25 | Monitoring | Webhook deliveries are signed per monitor: `POST /v1/monitors` returns `channels.webhookSecret` once, every delivery carries `X-Offendersearch-Signature: t=…,v1=…` over `<t>.<body>`, and `POST /v1/monitors/{monitorId}/webhook-secret` rotates the secret. |
| 2026-10-25 | Sex Offender | The full record is the default: `stateData` is populated on every record without `include`, and `omittedFields` is `[]`. New `exclude: ["stateData"]` drops it for a lighter payload. `include` is still accepted and changes nothing. |
| 2026-10-25 | Documentation | Developer portal: one reference layout for every product, request and response samples on every endpoint, Markdown twins and a per-product OpenAPI document. |

## Change policy

- Fields and enum values are added, not removed or renamed. Treat unknown enum values as "other" and unknown fields as ignorable.
- A breaking change would ship under a new base path and be announced here first; `/v1` has had none.
- The OpenAPI document at [/openapi.json](/openapi.json) is updated in the same change as the behaviour it describes.
