POST /api/v1/bgp/roa/import
POST /api/v1/bgp/roa/import?as_id=<uuid>&source=dn42
ROA import: snapshot-replaces the (as, source) route-origin-authorization set from an RPKI-style JSON body — flat files, no RTR for v1 (e.g. the DN42 registry's ROA export: curl https://dn42.burble.com/roa/dn42_roa_46.json | curl -X POST --data-binary @- …). Identical open rows stay untouched (no churn), absent rows close bitemporally (as-of-T validation stays answerable), new triples open. ROA status never enters any history change_hash — a registry update must not reopen intervals.
Auth: engineer/admin. Query: as_id (required), source (label, default import, ≤64 chars — each source is its own snapshot). Body (≤200k entries): {"roas": [{"asn": "AS64500"|64500, "prefix": "10.0.0.0/8", "maxLength": 24}]} — max_length is accepted as an alias; an absent maxLength means "exactly this prefix length" (RFC 6482). AS 0 is accepted: an AS0 ROA asserts "nobody may originate this prefix" (RFC 6483 §4 / RFC 7607 §4 — the DN42 registry ships them for unallocated space); it covers at read time but can never match, so every announcement under it validates invalid — the intended effect. Response 200 OK: {"added": 2, "removed": 1, "unchanged": 5, "open_total": 7}. Errors: 400 naming the failing entry index on an invalid asn/prefix/maxLength.