---
name: regsn-api
description: "Work with the Regulatory Snapshot API: async regulatory scans, snapshots, exports"
---

# Regulatory Snapshot API

Regulatory Snapshot (https://regsn.app) runs AI-powered regulatory horizon
scans across jurisdictions and regulatory areas, and returns the result as a
structured, cited snapshot. This skill teaches the public `/v1` HTTP API at
`https://api.regsn.app`.

Machine contract: https://api.regsn.app/openapi.json (YAML: `/openapi.yaml`).
Prose reference: https://docs.regsn.app/api (markdown twin of any page:
append `.md` to its URL). Docs index for agents: https://docs.regsn.app/llms.txt

## Authentication

Every request carries a bearer API key:

```
Authorization: Bearer regsn_live_<32 chars>
```

- Keys are minted in the developer dashboard at https://api.regsn.app during a
  signed-in browser session. There is no API for creating keys with a key —
  key management is dashboard-session-only, by design.
- The raw key is shown **exactly once** at creation. If it is lost, revoke and
  re-mint in the dashboard.
- Missing or malformed keys get `401` with a problem+json body; do not retry
  a `401` without changing the key.

## The object model

```
scan ──produces──▶ snapshot ──feeds──▶ export
```

- A **scan** is a run: jurisdictions × areas × horizon, executed by an engine.
  Scans are asynchronous jobs with `running / completed / failed / cancelled`
  states and live progress.
- A **snapshot** is the dated, self-contained result. Its `data` envelope
  carries `items[]`, `trends[]`, `executive_summary`, `executive_narrative`,
  and optionally `_briefing` (sub-editor editorial block: `briefing_headline`,
  `briefing_standfirst`, `priorities[]` with short labels and jurisdiction
  tags, `bottom_line_tight`, `pull_quote`, `sentiment_label`,
  `sentiment_rationale`), `auditor` (verification sidecar), `translations`,
  and `_meta`. Treat the envelope as open — new keys appear over time.
- An **export** is an artefact job over one snapshot: PDF, deck, infographic,
  audio, and more (`GET /v1/meta/export-types` lists the catalogue).

## Canonical flow

### 0. Estimate before you scan

Scans cost real money and draw from a prepaid budget. Estimate first — it is
free, unmetered against the scans bucket, and needs no real names (the
estimator buckets on counts, not strings):

```bash
curl https://api.regsn.app/v1/scans/estimate \
  -H "Authorization: Bearer $REGSN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jurisdictions":["UK","EU"],"areas":["AML / KYC"],"horizon":12}'
# → { "low_cents": 38, "expected_cents": 55, "high_cents": 91, ... }
```

Check remaining budget with `GET /v1/usage/budget` to avoid a `402` on create.

### 1. Create the scan

Always send an `Idempotency-Key` (any fresh UUID) so retries can never run a
duplicate paid scan:

```bash
curl "https://api.regsn.app/v1/scans?mode=async" \
  -H "Authorization: Bearer $REGSN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "jurisdictions": ["UK", "EU"],
    "areas": ["AML / KYC"],
    "horizon": 12,
    "engine": "v4.5-beta"
  }'
# → 202 { "scan_id": "…", "status": "running",
#         "status_url": "/v1/scans/…", "stream_url": "/v1/scans/…/stream" }
```

Notes: `horizon` is months, one of `3, 6, 12, 18, 24, 36`. `mode=sync`
(the default) blocks up to 120 s and returns the snapshot inline if the scan
finishes in time; otherwise it degrades to the same `202`. For agent use,
`mode=async` + polling is the predictable path.

### 2. Poll — or stream

Poll every 5–10 seconds; never tighter:

```bash
curl https://api.regsn.app/v1/scans/$SCAN_ID \
  -H "Authorization: Bearer $REGSN_API_KEY"
# → { "status": "running", "progress": { "phase": "…", "percent": 62 }, ... }
# → when done: { "status": "completed", "snapshot_id": "…", "cost_cents": 61.4 }
```

Or subscribe to Server-Sent Events (`GET /v1/scans/{id}/stream`, not
rate-limited). Each `data:` line is JSON discriminated by `type`:
`progress`, then a terminal `complete` (carries `snapshotId` and the full
envelope), `error`, or `cancelled`. A `: heartbeat` comment arrives every
30 s. `POST /v1/scans/{id}/cancel` is best-effort cancellation.

### 3. Read the snapshot

```bash
curl https://api.regsn.app/v1/snapshots/$SNAPSHOT_ID \
  -H "Authorization: Bearer $REGSN_API_KEY"
```

The envelope is under `data`. Prefer the sub-resources when you need one
slice — they are much smaller than the full document:

```
GET /v1/snapshots/{id}/items                the regulatory items
GET /v1/snapshots/{id}/trends               cross-item trends
GET /v1/snapshots/{id}/executive-summary    { bottom_line, priorities[] }
GET /v1/snapshots/{id}/executive-narrative  prose; ?language=fr|de|es|it|zh|ja|pt
GET /v1/snapshots/{id}/drift                changes vs the prior comparable
                                            snapshot; { "available": false }
                                            is the normal first-run case
GET /v1/snapshots/{id}/briefing             sub-editor editorial block
                                            (headline, pull quote, sentiment);
                                            { "available": false } on snapshots
                                            that predate the sub-editor
```

`GET /v1/snapshots` lists past snapshots (`limit`/`offset`, `from`/`to`,
`jurisdiction`, `area` filters). There is no `starred` filter — sending one
returns `422 unknown_parameter`.

### 4. Export

Exports are always asynchronous — create, poll, download:

```bash
curl https://api.regsn.app/v1/exports \
  -H "Authorization: Bearer $REGSN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d "{\"snapshot_id\":\"$SNAPSHOT_ID\",\"provider\":\"internal-pdf\",\"artifact_type\":\"pdf\"}"
# → { "export_job_id": "…", "status": "queued", "status_url": "/v1/exports/…" }

curl https://api.regsn.app/v1/exports/$EXPORT_ID \
  -H "Authorization: Bearer $REGSN_API_KEY"          # poll until "completed"

curl -OJ https://api.regsn.app/v1/exports/$EXPORT_ID/download \
  -H "Authorization: Bearer $REGSN_API_KEY"          # saves the artefact
```

Also available: `GET /v1/exports` (list), `DELETE /v1/exports/{id}`.
`GET /v1/meta/export-types` is the per-type options vocabulary.

## Gotchas

- **Rate buckets, per key**: reads 60/min · scan creation 6/hour · export
  creation 30/hour · other mutations 30/min. `429` responses carry
  `Retry-After` and RateLimit headers — honour them.
- **Patience**: scans take minutes; exports take seconds to minutes. Poll at
  5–10 s; the 6-scans/hour bucket makes tight retry loops self-defeating
  anyway.
- **Errors are RFC 9457 problem+json** with a stable machine `code` — branch
  on `code`, never on the human-readable `detail`. The ones to handle:
  `budget_exhausted` (402 — check `/v1/usage/budget`), `not_found` (404 —
  also covers other-account ids), `idempotency_key_in_use` /
  `idempotency_in_progress` (409), `validation_error` (422, per-field
  `errors[]`), `unknown_parameter` (422), `rate_limit_exceeded` (429).
  Quote the `X-Request-Id` header when reporting problems.
- **Engines**: `v4` (default), `v4.5-alpha`, `v4.5-beta`. Retired ids
  (`v1`, `v2`, `v3`, `admiral`) fail with `422` / field code
  `engine_deprecated`. Discover live values at `GET /v1/meta/engines`.
- **Retry policy**: retry `429` (after `Retry-After`), `500`, `503` with
  backoff; never blind-retry other `4xx`. Pair every POST retry with the
  same `Idempotency-Key` — replays return the original response.
- **Discovery over hardcoding**: `GET /v1/meta/jurisdictions`, `/meta/areas`,
  `/meta/models`, `/meta/engines`, `/meta/export-types` are cheap reads
  listing the product's live vocabulary. Names are free text (not
  membership-checked), but the meta lists are what the product itself uses.
- **Telemetry**: `GET /v1/usage` (requests, scans, exports, cost;
  `from`/`to`/`group_by`) and `GET /v1/usage/budget` (remaining pool).

## Pointers

- OpenAPI spec: https://api.regsn.app/openapi.json · human reference:
  https://api.regsn.app/reference
- Docs (each page also serves a `.md` twin): https://docs.regsn.app/api —
  quickstart, scans, snapshots, exports, errors, rate-limits, idempotency
- Docs index for agents: https://docs.regsn.app/llms.txt · full text:
  https://docs.regsn.app/llms-full.txt
- Agent entry page: https://docs.regsn.app/docs-for-agents
