Technical Reference
How the V·I·G·I·L Edge API Works
V·I·G·I·L reports one binary condition. This note covers the endpoint that serves it: how often it is evaluated, what has to hold before the answer is allowed to change, and what the response carries.
1.Where the Work Happens
No evaluation runs on the device. The client issues an anonymous GET on a timer and renders whatever comes back. Fetching, matching, and confirmation all happen at the edge. A shipped build contains no code path that decides the condition locally. The client only draws the result.
2.Cadence and Caching
The edge divides wall-clock time into fixed 15-minute blocks on UTC boundaries: :00, :15, :30, :45. Which block a request lands in determines which evaluation it receives.
Clients are not synchronized to those boundaries. Each polls on its own 15-minute timer and again when the app returns to the foreground, so requests arrive spread across the block rather than as a burst at the top of it. The first request into a block runs the evaluation; every request after it reads the stored result. Response TTL is set to the remaining life of the block rather than a fixed duration, so a cached answer never outlives the window it describes.
Both /api/check and /api/v1/check resolve to the same evaluation and share a single cache entry per block. Shipped clients use the versioned path; the unversioned one remains for consumers that predate it.
3.How a Change Is Confirmed
On a cache miss the edge fetches a fixed set of independent, publicly syndicated news feeds in parallel, each under a five-second timeout, and screens their headlines against the condition being watched.
A match from one source does nothing on its own. More than one independent origin has to agree before a match becomes eligible at all.
Eligibility is still not confirmation. The first time quorum clears, the result is held and the public status stays false. It has to clear again in a later block, on a separate fetch, before anything changes. Simultaneous multi-source error is a documented failure mode in breaking news and usually corrects within the hour; a single-block latch would have pushed such an error to every install before the correction landed. The cost of the second block is up to fifteen minutes of delay on a real event, which was accepted as the better trade.
Once the status changes, no evidence the feeds can produce moves it back. A later headline, a correction, a retraction downstream — none of it un-latches the result. The only path back to false is an explicit withdrawal issued by this server, and the response states that outright rather than leaving it to be inferred.
4.Response Contract
Installed binaries fix their endpoint at release, so the shape at this path is frozen and will not change beneath them. Anything breaking ships behind a new version prefix. There is no authentication; the endpoint is public, takes no parameters, and returns JSON.
5.Behavior Under Failure
If the upstream fetches fail or the evaluation throws, the endpoint returns 200 with a well-formed negative and a 60-second TTL rather than a 5xx. Consumers only act on a true, so a negative is the safe default, and an error status would put the whole installed fleet into retry against an origin that is already struggling. The short TTL lets the next block recover normally.
That negative means only that the check did not complete. withdrawnAt is null on this path, because a server that could not finish an evaluation is in no position to state that anything was withdrawn.
6.Omissions
The response carries no matched headline, no source attribution, and no account of how the determination was reached. That material stays at the edge. The request carries no account, token, client identifier, or query string. Nothing in it separates one install from another.
The condition being watched is not documented here.