UK public registers are free and public. Companies House, the FCA register,
Find a Tender, Contracts Finder, GOV.UK Find a Grant. All of it is open data
under the Open Government Licence, and none of it is usable by an AI agent
without a human in the loop.
Companies House needs an API key from a human dashboard. The FCA Register
API needs a developer account and written permission. Find a Tender publishes an OCDS feed with no keyword
search at all. GOV.UK Find a Grant has no API of any kind — it is HTML, and
that is the whole interface. An agent that tries to do this itself either
stops at a signup form or starts scraping.
api.ukintel.uk is those five sources behind eleven x402 endpoints. Call it,
get a 402 with payment terms, pay in USDC on Base, retry. No account, no API
key, no rate-limit negotiation.
The arithmetic
This is the part worth checking rather than believing.
An agent answering "is this UK supplier legitimate?" by browsing does roughly
five page-loads — Companies House search, company profile, filing history,
officers, FCA register — about 34,000 input tokens, plus ~2,500 tokens of
tool-call overhead and ~2,500 output tokens of reasoning.
On a mid-tier model at $2/M in and $10/M out, that is $0.098 per attempt.
Apply a realistic 30% retry-and-blocked-page factor and it is ~$0.13,
taking 30–90 seconds. On a frontier model at $10/M and $50/M it is $0.49 per
attempt, ~$0.64 with retries.
GET /v1/company/{number}/verdict costs $0.10 and returns roughly 800
structured tokens. Reading them costs $0.0016–$0.008 depending on the model.
Call it $0.102–$0.108, in about two seconds.
So: modestly cheaper on a mid-tier model, roughly 6× cheaper on a frontier
model, and in both cases the DIY route also burns ~36,000 tokens of context
the agent needed for the rest of its task.
There is a sharper version of this. A raw Companies House filing-history JSON
for a mid-sized company is about 60KB — around 15,000 tokens. Merely reading
that free file costs $0.030 on a mid-tier model and $0.150 on a frontier
model, every single time, before any thinking happens. The verdict endpoint
costs $0.10 all-in and has already done the judgement. On frontier models the
paid answer is cheaper than the free data.
That is the entire product thesis: sell fewer tokens that say more.
What it actually returns
Every endpoint returns the same envelope — query, result, verdict,
confidence, as_of, sources, attribution, notice, cost. Deterministic
key order, explicit nulls rather than missing keys, no HTML anywhere, ~800
tokens by default with ?detail=full to lift the cap.
as_of is when we fetched the underlying data, never when you asked.
Here is a real grant eligibility verdict, returned free from
/v1/preview?wing=grants today — a live DfE school-based nursery capital
grant against a showcase project profile:
"verdict": {
"score": 64,
"band": "eligible",
"flags": [
{ "code": "MISSING_DECLARATION",
"detail": "net_increase_childcare_places not declared; Proposed project will result in a net increase in the number of childcare places, accounting for existing provisions on site or nearby" },
{ "code": "MISSING_DECLARATION",
"detail": "landowner_permission not declared; Written permission from relevant freehold landowner to use land for nursery provision and carry out proposed works" },
{ "code": "REVIEW_REMAINING",
"detail": "3 criteria cannot be auto-assessed (OPERATIONAL_BY_SEPTEMBER_2030, PROJECT_CLASSIFICATION, PREVIOUS_GRANT_ADDITIONALITY) - review them against the source page." }
],
"rules_version": "1.0.0"
}
Note what it does not do. It does not guess. score: 64 is not confidence in
eligibility — it is the share of criteria affirmatively passed, with undeclared
facts counting half and named in missing[]. Declare them and call again and
the score firms up. A criterion nobody can auto-assess says so and points at
the source page.
The rules are published. Any hard criterion failing means ineligible, score
0, failing codes listed. No fails means eligible. Unparseable criteria means
uncertain — never a fabricated verdict.
Where the language model is, and is not
A language model writes the optional two-sentence narrative field on company
verdicts, the one-sentence emphasise note on top tender matches, and it
performs a single text-to-criteria conversion once per grant at ingest time.
It touches no score, on any endpoint, ever. Every 0–100 number comes from a
deterministic rule table that ships in the docs, versioned, with each rule that
fired named in the response. You can audit any score by hand, and you can
disagree with a rule and re-weight it — the tender fit-score returns every
factor's numerator and denominator so you can re-weight client-side without
calling us again.
This is a deliberate constraint, not a limitation we are apologising for. A
score an agent cannot audit is a score an agent should not act on.
The endpoints
| Endpoint | Price | What it answers |
|---|---|---|
GET /v1/company/search |
$0.005 | Find a UK company by name |
GET /v1/company/{number} |
$0.02 | Structured profile, filing dates, officer counts |
GET /v1/company/{number}/verdict |
$0.10 | 0–100 legitimacy verdict, named flags |
GET /v1/company/{number}/fca |
$0.02 | FCA register status only |
GET /v1/tenders/search |
$0.05 | Live UK tenders as briefs |
GET /v1/tenders/{ocid}/brief |
$0.10 | One tender, full dossier |
POST /v1/tenders/fit-score |
$0.20 | Supplier profile → scored matches |
GET /v1/grants/search |
$0.10 | Live GOV.UK grant calls |
POST /v1/grants/match |
$0.15 | Project profile → eligible grants, ranked |
GET /v1/grants/{id}/eligibility |
$0.15 | One grant, one project, criteria table |
GET /v1/funders/{name} |
$0.20 | Funder giving history from 360Giving |
Free, because frameworks probe before they route money: /v1/health,
/v1/preview (a real, freshly-computed sample in the exact paid shape,
rotating daily — add ?wing=tenders or ?wing=grants), and /v1/feedback.
Also available as an MCP server at https://api.ukintel.uk/mcp (13 tools,
listed in the official MCP registry as uk.ukintel/ukintel).
Freshness, and what we are honest about
Companies House is fetched live, cached six hours per company number. Find a
Tender and Contracts Finder are indexed on a six-hour cycle — 3,590 notices
right now; an index older than twelve hours drops confidence to medium and
raises an INGEST_STALE flag rather than quietly serving old data. Find a
Grant is a polite daily scrape — sequential, identified user-agent, robots.txt
honoured every cycle, and if robots ever disallows us we stop and say so with
a SCRAPE_BLOCKED flag.
Three things we would rather you heard from us than discovered:
-
The FCA cross-check runs against the Register's beta API. We hold
written permission from the FCA Register API team for this use (real-time
lookup, status/FRN/register-link only, attributed, nothing stored). Their
own caveat applies: the API is beta with limited support, so if it does not
answer, the endpoint degrades honestly —
fca.checked: false, the financial-services rules are skipped, and no FCA claim is made. We never assert "not regulated" from a failed lookup, only from a successful lookup that found nothing. -
Grant criteria come at two depths, and the response tells you which one
answered. Every indexed grant is assessed against Find a Grant's own
published "Who can apply" and "Location" fields, so a clearly ineligible
applicant is ruled out anywhere in the corpus. Most grants also have their
full eligibility text parsed into a criteria table — thresholds,
declarations and all — and only a grant at that depth can come back
eligible. A listing-only assessment is flaggedPARTIAL_CRITERIAand staysuncertainrather than being talked up, because those two fields are not the whole rulebook.result.criteria_provenance.completesays which you got. Coverage is public rather than a number we are asking you to trust:GET /v1/healthreportsgrants_index.with_criteriaandgrants_index.awaiting_criteriaagainstgrants_index.grants(today: 109 of 120 at full depth). - Tender buyer-history scores a neutral 8/15 for every buyer in v1. It is flagged in the response and documented in the rules table rather than silently invented. Buyer award-history is this wing's first planned upgrade.
CPV codes are null when the source release carries none. We report the
register; we do not guess.
Licensing
Companies House, Find a Tender, Contracts Finder and Find a Grant are Open
Government Licence v3.0, attributed in every response. 360Giving publisher
datasets carry mixed open licences — the funder corpus aggregates 516 of 874
published datasets across 229 funders, CC-BY-SA datasets are excluded from the
numbers entirely by policy, exclusions are counted in the response, and every
recent-award row carries its own source licence. Dossiers describe the covered
corpus, never the whole sector.
Officer names and dates of birth are deliberately not returned. Officer counts
and resignation churn are.
Try it without paying
curl https://api.ukintel.uk/v1/preview
curl https://api.ukintel.uk/v1/preview?wing=tenders
curl https://api.ukintel.uk/v1/preview?wing=grants
Real data, freshly computed, rotating daily, in the exact shape the paid
endpoints return.
If you use Claude Code, one line connects all 13 tools:
claude mcp add --transport http ukintel https://api.ukintel.uk/mcp
Machine docs: /llms.txt · /openapi.json · /.well-known/x402 ·
/.well-known/agent-card.json · MCP at /mcp
Something missing? POST /v1/feedback with {"message": "..."} is free, read
by a human, and is the fastest way to get a field added. Or email
hello@ukintel.uk.
Information, not advice. These are public register facts and rules-based
scores. A fit-score means fit, never "you will win". A grant eligibility
verdict means the stated criteria pass, never "you will get this grant" —
eligibility is not award, and the funder's assessment decides.
Top comments (0)