Public IDs
| Resource | Form | Notes |
|---|---|---|
| Entity | ent_123881 | Merge-aware: old IDs keep resolving; lookups surface merged_from_id |
| Mention | men_2049815 | What you pass to Community Review for mention and appearance rows |
| Commercial row | com_119682 | What you pass to Community Review for reclassification |
| Monitor | mon_abc123 | Rows minted before the Monitors rename carry a legacy wl_ prefix; both resolve |
| Tracker | trk_9f2ab4c8d1e6 |
entity_id as ent_*, mention_id as men_*) alongside numeric media_id/appearance_id, which stay numeric everywhere in the API.
Pagination
List endpoints use cursor pagination. No total counts: fast, stable, infinite-scroll-friendly.| Parameter | Description |
|---|---|
limit | 1-100, default 20 |
cursor | Opaque token from a previous response’s next_cursor; omit on the first request |
has_more is false, next_cursor is null; stop. Cursors are opaque: pass them back verbatim, never construct or decode them. If the underlying ordering changes (rare), an old cursor may include duplicates or gaps; restart from null for a strict snapshot.
- Alert history (
GET /v1/monitors/{id}/alerts,GET /v1/trackers/{id}/alerts) takes?n=(1-100, default 25) and always returnshas_more: false. It is a recent-deliveries window, not a paginated archive. - Person appearances (
/v1/people/{slug}/appearances) and the related-entity lists (/v1/{type}/{slug}/{topics|people|...},/v1/channels/{slug}/guests) return{ items, total, offset, limit, hasMore }and no cursor, so they serve one page. For paginated appearance evidence use/v1/mentions?entity_id=...&is_appearance=true. - Discovery search (
/v1/entities/search) is a single ranked page:limit1-25, default 10, no cursor. Channel sponsors (/v1/channels/{id}/sponsors) is a single rollup:limit1-200, default 100, no cursor.
Idempotency
EveryPOST and PATCH accepts an Idempotency-Key header. Send one on every mutation; a UUID v4 per logical operation is the safe default.
- Arcmira processes the request and caches the response (body, status, and a hash of the request body) against your key for 24 hours, scoped per API key.
- A retry with the same key returns the cached response with
Idempotency-Replayed: true. - Reusing a key with a different body returns
409 idempotency_conflict: mint a new key for the new operation.
GET/DELETE don’t take idempotency keys (already idempotent); the cache may not outlive 24 hours, so long retry windows should mint fresh keys and handle the resulting conflicts; on transcript corrections, only final outcomes are cached and a 412 never replays.
Headers on every response
| Header | Description |
|---|---|
X-Request-Id | Correlation ID; same value as error.request_id on failures. Log it; quote it to support |
X-Arcmira-Version | API version serving the request |
RateLimit-Limit / -Remaining / -Reset | Per-key throttle state, on every response past the key check; see Usage, limits & billing |
Retry-After | On 429, and on in-flight transcription polls: seconds to wait. Always honor it |
Idempotency-Replayed | true when a successful response came from the idempotency cache |
Versioning and deprecation
- The API is versioned in the path (
/v1). Additive changes (new fields, new endpoints) ship without notice; removing or renaming anything gets adeprecatedmarker in the OpenAPI spec with migration prose, a changelog entry, and a deprecation window. - Build tolerant readers: ignore unknown fields, and handle unknown enum values gracefully (new event names, statuses, and error codes will appear).
- The live OpenAPI 3.1 document is at
GET /v1/openapi.jsonand mirrors this site’s API reference.