Pagination and idempotency
How lists are bounded, and how Idempotency-Key makes a retried write safe.
Pagination
No endpoint pages today: every list comes back whole. list-weeks answers at most 26 weeks, newest first (about six months); an older week stays readable by its Monday with get-week. A week's order, versions and creatives are always one answer.
Writes are bounded instead: a report takes at most 2,000 items, each unit or show day once, in a JSON body of at most 256 KB (512 KB when applying log matches). Split a bigger batch into several calls.
Idempotency
Every write that records something takes an Idempotency-Key header: acknowledge-version, report-affidavits, report-show-airings and apply-log-matches. It is 8 to 48 letters, digits, dashes or underscores, and a UUID is a good choice. The service keeps the first answer to each key: when a request times out or the connection drops, send it again with the same key, and if the first attempt did save you get its answer instead of a second record.
Idempotency-Key: <a new UUID for each request>
- The key is the identity of the request, not of its body: a repeat with the same key on the same endpoint answers the first result as an ordinary 200 even when the body changed, and records nothing new.
- A key reused on another endpoint records nothing either. The service answers with the first request's stored result, which does not fit the new endpoint, so the request usually fails with 502
upstream_failed, and a retry with that key fails the same way. Send it again with a new key. - So make a new key for every new request, keep it with that request, and send it again only to retry that request. The code samples on each endpoint page make a new key every time they run; a script that hard-codes one key saves its first run only.
- Without the header the portal makes a key for you, so a retry you send without one counts as a new request.
X-Request-Idon the answer carries the key you sent, so you can match answers to requests.- A malformed key answers 400
bad_requestand records nothing.
Log uploads are not idempotent
upload-log stores a new upload every time: an Idempotency-Key is only echoed as X-Request-Id, and a repeat spends upload quota. When an upload answered 202 with its id, poll GET /api/uploads/{upload} with the same station key until it is ready instead of posting the file again. Applying its matches is protected differently: an upload is applied once, and a repeat of the same choice answers the first result with replayed: true.