The API
A read-only view of the register, and a way to send us a flag. Free, keyed per partner, and metered so both sides can see the same numbers.
01What this is
The register holds enforcement actions, regulator warnings, court filings and permissions, harvested from 134 active official and independent sources and classified by one deterministic rule. This API is that register, read-only, plus a single write route for partners who want to flag a subject to us.
It is free. There is no paid tier and no per-call charge; every key carries a price of zero and is metered anyway, so that a partner and we can always reconcile the same usage figures.
02How a row gets here
Sources are harvested four times a day. Each item is then judged by one rule, and the rule is the same one the website uses — there is no second copy that could disagree. An item is admitted only if it carries both a subject and a predicate, and is not caught by an exclusion.
- Subject — what the item is about:
crypto,forex,investment. - Predicate — what is being said about it:
fraud,warning,law,grant.
A price move carries a subject and no predicate, so it is not admitted. A robbery carries a predicate and no subject, so it is not admitted either. That is the whole filter, and it is why the register is smaller than a news feed and more useful than one.
grantis the newest of the four and the least obvious: it is an authority deciding in somebody’s favour — a licence issued, a registration granted, victims repaid, a compensation process opened. A company’s own announcement about itself is not a grant by anyone and is not admitted.
Every verdict is stamped with the rule version that produced it, so a row can always be traced to the rule in force when it was judged.
03Authentication
Read routes are open. The write route needs a key.
curl -H "Authorization: Bearer <your key>" \
"https://api.marketstandard.org/v1/articles?subject=crypto&predicate=fraud&limit=5"No client requirements.Any HTTP client works, including Python’s standard urllib with no headers set. Sending a User-Agent that identifies you is appreciated rather than required — it is how we tell a partner integration apart from an anonymous scraper when something looks wrong.
04Reading the register
Four collections: /v1/articles, /v1/entities, /v1/firms and /v1/vocabulary. The full route list and every parameter is at /openapi.json; what follows is what the spec cannot tell you.
An unknown parameter is a 400, never ignored. A silently dropped filter returns the whole corpus with a 200, and that is indistinguishable from a query that genuinely matched everything. The same applies to an empty value: ?q= is refused, because it usually means a variable did not interpolate.
Enumerate, do not guess. /v1/vocabulary is read from the live data on every request and reports the accepted values with their counts, including values that are valid but currently empty. Jurisdictions are ISO 3166-1 alpha-2 plus Global; the list grows as coverage does.
To mirror the register, use changed_since, not since. sincefilters by the source’s publication date and cannot show you corrections, reclassifications or withdrawals. changed_since can, and reports removals in sync.deleted.
curl "https://api.marketstandard.org/v1/vocabulary"
curl "https://api.marketstandard.org/v1/articles?jurisdiction=GB&limit=5"
curl "https://api.marketstandard.org/v1/entities?role=subject&limit=5"On /v1/entities, read entity_role before entity_type. Type says what kind of thing a name is; role says whether the register is about it. Of the names in the register, the loudest by mention count are regulators, publishers and forensics vendors — all typed as firms. Build anything that names a company from role=subject and page_eligible, never from the type.
05Sending us a flag
POST /v1/flags takes a subject, a reason, a confidence and a provenance URL. It is the only write route. Flags are deduplicated deterministically, so retrying a timed-out request returns the same flag rather than creating a second assertion.
curl -X POST "https://api.marketstandard.org/v1/flags" \
-H "Authorization: Bearer <your key>" \
-H "Content-Type: application/json" \
-d '{"subject_name":"Example Capital Ltd","subject_type":"firm",
"reason":"named in an on-chain investigation",
"confidence":0.8,
"provenance_url":"https://example.org/report"}'We check the page you cite, and we tell you what we found. After a flag arrives we fetch its provenance_url and look for the subject name on it. The result is stored beside your flag as one of three states:
- supported — the page names the subject.
- unsupported — the page fetched cleanly and does not name the subject.
- inconclusive — the page would not fetch. Unknown, and it stays unknown; it is never counted as support.
Nothing is refused or deleted on the strength of that check. Your flag is recorded exactly as you made it and the check sits next to it, because a flag whose page does not mention its subject is almost always a typo or a redirect, and the useful thing is to show you rather than to drop the row. The check also runs a fabricated name against the same page every time, so we know what a wrong name scores by chance — a support rate is meaningless without it.
05bWhere the API and this website differ
The register behind this API holds twonational registers: ESMA’s union public register of investment firms, and Japan’s FSA list of registered crypto-asset exchange service providers. /v1/firmsreturns both, and every firm names the register it came from with that register’s own licence and acknowledgement in sources.
The website currently shows only the ESMA rows. So /firms reports a smaller number than /v1/firms does, and there are no individual pages for the Japanese firms yet. That is a gap in the website, not a disagreement about the data — both are reading the same store, and the API is the complete view.
We would rather say so than have you find it. If a count here does not match a count there, this is why; if you find any other difference between the two, it is a bug and we would like to know.
06What you may do with it
Article body text is never served. A summary appears only where the source licence permits reproduction; every other item is a link, a headline, a publisher, a date and our classification. Firm records are reproduced from ESMA’s union public register and every response carries the acknowledgement that licence requires.
A firm appearing on an authorised register is a record of a permission. It is not a recommendation, and not a statement that the firm is safe. A firm appearing nowhere in this register means we hold no coverage of it — it does not mean the firm is clear.
07Limits, stated plainly
- Rate. Every response carries
x-ratelimit-*headers, including on a refusal, so a metered call is always visible to both sides. A quota ofunlimitedis the word, not a number. - Freshness. The register updates four times a day. It is not a real-time feed and should not be used as one.
- Coverage. Absence is not evidence. The register reflects what our sources published and what the rule admitted, and both are measurable and incomplete.
- Errors. Every failure is JSON with a machine-readable
error, areasonnaming the offending value, and ahint. A 500 carries an error reference rather than the cause; quote it to us and we can find it.