Editorial

Editorial promises

Three things this database will not do. Each of them is already true of the code that serves this page, and each names the rule it comes from — a promise you cannot check is a slogan.

Core fields stay free, and stay visible

A record’s name, its amounts, its deadline, the link to the official page and the date we last checked it are visible to anyone, without an account. There is no login wall in front of them, no countdown, no blurred row that resolves on upgrade, and no field that is shown to a subscriber and hidden from you.

What the paid tiers add is workflow — alerts, saved searches, client profiles, bulk matching. None of it is a field. If you ever find a core field behind a wall, that is a bug in our code and not a change of policy.

Where this comes from

Red line 3 in the project’s own constitution: core fields permanently free to see. It is why the record page is a server-rendered public route with no session check in front of its fields.

A field we could not verify reads “Not stated”

A field we could not verify is shown as “Not stated” — never as 0, never as an empty list, and never as a guess. Those three are not softer versions of “we don’t know”. Each of them is a claim, and each is a claim the source never made.

The clearest example

A record’s matching requirement has three states, not two. Stored as null it means “the source did not say either way”, and we do not render that as “no match needed” — because an applicant who reads “no match needed” and files on that basis has been told something no funder ever published. The column carries no default for the same reason: a default false would bring the same trap back through the side door.

The extraction model is scored per field and a low-confidence field is dropped to null before it reaches a page. An empty eligibility array would tell you we checked and found no restrictions; we use null instead, because we did not.

Where this comes from

The project’s data red lines: never fabricate or flatter a figure, and show “Not stated” rather than 0, an empty array, or a model’s guess. It is written into the extraction schema, not just into a review checklist.

A source we could not reach is not a grant that closed

A source we failed to reach is a fact about our crawler, not about the grant. A portal that times out, rate-limits us, or moves a page tells you something about our sweep and nothing about whether the money is still there.

So a single failure changes nothing. A record’s status moves only after three consecutive failures spanning at least 48 hours, which is long enough to outlast an outage and a maintenance window. And when a whole source starts failing above its threshold, the sweep trips a breaker and stops writing altogether — because the one thing worse than a stale record is a thousand records marked closed by our own outage.

Where this comes from

The project’s data red lines: a failed fetch is not a closure, and a source-wide failure rate above threshold halts the sweep rather than editing entries. Both are implemented in the freshness sweep, not merely intended.

Hold us to it

Every figure on this site states the date it was measured and links to the page it came from, which is what makes these promises checkable rather than merely stated. If you find a core field behind a wall, a blank rendered as a zero, or a grant marked closed that is not, that is a bug in this database — tell us. A correction moves the record and its verification date, which is the only kind of apology a database can make.

Report something wrong