Live company-registry data from 30 national governments over plain HTTPS. REST and RPC routes share one auth pipeline; every response is tier-redacted and 60-second fresh from the upstream registry.
Looking for the AI / MCP server? See /docs. Looking for the web search? Use the home-page search box.
Free tier — 30 req/min per user. Grab a token from /account.
$ curl https://openregistry.sophymarine.com/api/v1/companies/GB/00185647 -H 'Authorization: Bearer or_pat_…'
{
"queried_at": "2026-05-17T12:30:00+01:00 (Europe/London)",
"jurisdiction": "GB",
"company_id": "00185647",
"company_name": "J SAINSBURY PLC",
"status": "active",
"incorporation_date": "1922-11-10",
"registered_address": "33 Charterhouse Street, London, EC1M 6HA",
"jurisdiction_data": { ... }
}
The queried_at timestamp is when we hit the registry. The unified top-level
fields are normalized across countries; the raw upstream payload comes back verbatim under
jurisdiction_data so nothing is hidden.
Fires a real request from your browser against this server. No data leaves the page; nothing is logged differently than a normal API call.
curl https://openregistry.sophymarine.com/api/v1/companies?q=tesco&jurisdiction=GB&limit=3
// click Run query to fire
Pick whichever fits your client:
GET /api/v1/companies/{jur}/{id}/officers): resource-oriented,
matches OpenCorporates / Companies House conventions, easy to cache, easy to read in URL bars.GET|POST /api/v1/rpc/{tool}): one endpoint per tool, 1:1 with the
MCP surface, takes arguments in query string or JSON body. Best when you're generating
calls programmatically.Both routes share the same auth, the same rate limits, and the same response envelope. Pick one per project; mixing is fine.
| Method | Path | Backing tool | What it returns |
|---|---|---|---|
| GET | /api/v1/jurisdictions |
list_jurisdictions |
Cross-country tool-support matrix. |
| GET | /api/v1/jurisdictions/{cc} |
list_jurisdictions |
Full schema + ID format + quirks for one country. |
| GET | /api/v1/companies?q=&jurisdiction= |
search_companies |
Search company names in one national registry. |
| GET | /api/v1/companies/{jur}/{id} |
get_company_profile |
Unified profile + raw `jurisdiction_data`. |
| GET | /api/v1/companies/{jur}/{id}/officers |
get_officers |
Directors / corporate officers, live. |
| GET | /api/v1/companies/{jur}/{id}/shareholders |
get_shareholders |
Latest shareholder filing (where exposed). |
| GET | /api/v1/companies/{jur}/{id}/filings |
list_filings |
Filing history with `document_id` for download. |
| GET | /api/v1/officers?q=&jurisdiction= |
search_officers |
Cross-company person search by name. |
| GET | /api/v1/documents/{jur}/{id} |
get_document_metadata |
Document size, format, page count. |
| GET | /api/v1/documents/{jur}/{id}/content |
fetch_document |
Raw bytes (Content-Type: application/pdf etc.). 302 for large files. |
| GET | /api/v1/documents/{jur}/{id}/navigation |
get_document_navigation |
PDF outline + per-page text preview. |
$ B=https://openregistry.sophymarine.com
$ T='Authorization: Bearer or_pat_…' # /account
# 1. Find the company by name
$ curl -H "$T" "$B/api/v1/companies?q=sainsbury&jurisdiction=GB&limit=2"
# 2. Pull the profile by the registry ID
$ curl -H "$T" "$B/api/v1/companies/GB/00185647"
# 3. Pull officers + shareholders + recent filings
$ curl -H "$T" "$B/api/v1/companies/GB/00185647/officers"
$ curl -H "$T" "$B/api/v1/companies/GB/00185647/shareholders"
$ curl -H "$T" "$B/api/v1/companies/GB/00185647/filings?limit=10"
# 4. Download a specific filing PDF
$ curl -H "$T" -o accounts.pdf \
"$B/api/v1/documents/GB/<document_id_from_step_3>/content?max_bytes=20000000"
One endpoint per MCP tool. Pass arguments as query parameters on GET, or a JSON body on POST.
| Method | Path | Tool |
|---|---|---|
| GET / POST | /api/v1/rpc/list_jurisdictions |
list_jurisdictions |
| GET / POST | /api/v1/rpc/search_companies |
search_companies |
| GET / POST | /api/v1/rpc/search_officers |
search_officers |
| GET / POST | /api/v1/rpc/get_company_profile |
get_company_profile |
| GET / POST | /api/v1/rpc/get_officers |
get_officers |
| GET / POST | /api/v1/rpc/get_shareholders |
get_shareholders |
| GET / POST | /api/v1/rpc/list_filings |
list_filings |
| GET / POST | /api/v1/rpc/get_document_metadata |
get_document_metadata |
| GET / POST | /api/v1/rpc/fetch_document |
fetch_document |
| GET / POST | /api/v1/rpc/get_document_navigation |
get_document_navigation |
# GET form — args in query string
$ curl -H 'Authorization: Bearer or_pat_…' \
"https://openregistry.sophymarine.com/api/v1/rpc/search_companies?jurisdiction=NO&query=equinor&limit=2"
# POST form — args in JSON body
$ curl -X POST https://openregistry.sophymarine.com/api/v1/rpc/get_officers \
-H 'Authorization: Bearer or_pat_…' \
-H 'Content-Type: application/json' \
-d '{"jurisdiction":"GB","company_id":"00185647"}'
Per-tool argument schemas: see /docs for each tool's input fields.
Two modes, both supported on every endpoint:
Authorization: Bearer or_pat_…) —
recommended for scripts and server-to-server use. Generate one at
/account → "API tokens" with a chosen TTL (7d / 30d / 90d / 1y / never).
Token is shown exactly once at creation, then only the prefix is visible. Revocation is
immediate. This is the curl-friendly auth path.Authorization: Bearer eyJ…): for MCP-style
clients that already implement the OAuth 2.1 flow (Claude Desktop, Cursor, etc.).
15-minute access token + 30-day refresh. See
OAuth discovery. Authenticated
callers get a tier-keyed per-user rate-limit bucket and higher fan-out cap
(Pro=10 / Max=30 / Enterprise=unlimited).Invalid tokens get 401 with a WWW-Authenticate hint.
Tier-redaction strips a small set of source-URL fields below Enterprise; the underlying
company data (jurisdiction_data) is identical across tiers. We do not modify or
summarise the registry's payload.
# Personal Access Token (your tier's per-user rate limit)
$ curl https://openregistry.sophymarine.com/api/v1/companies/GB/00185647 \
-H 'Authorization: Bearer or_pat_AbCdEf...wxyz'
| Bucket | Tier | Limit |
|---|---|---|
| Per-user (authenticated) | free | 30 / minute |
| Per-user (authenticated) | pro | 180 / minute |
| Per-user (authenticated) | max | 900 / minute |
| Per-user (authenticated) | enterprise | 3000 / minute |
| Per-country (upstream cap) | — | GB 100 / min, NL 15 / min, default 20 / min |
Per-country caps are shared across all tiers — that's our commitment to the upstream
registries. Hitting one returns 429 with Retry-After. The per-tier limits are
on top: an Enterprise user gets 3000 rpm total, distributed however they want
across countries.
Every error response is JSON with a stable shape:
{
"error": "rate_limit_exceeded",
"message": "Per-user rate limit (30 rpm) exceeded. Retry in 12s.",
"retry_after_seconds": 12,
"tier": "free"
}
| Status | error code | When |
|---|---|---|
| 400 | various | Bad arguments (missing required field, invalid jurisdiction code, etc.) |
| 401 | invalid_token | Bearer token present but failed validation (expired, wrong aud, unknown kid). |
| 402 | paid_tier_required | Endpoint covers a paid jurisdiction (e.g. KY) and the caller is on a free tier. |
| 404 | not_found | Unknown route, unknown company, or tool not exposed on this surface. |
| 405 | method_not_allowed | REST endpoint accepts only GET; RPC accepts GET or POST. |
| 429 | rate_limit_exceeded | One of the three buckets full. Retry-After header attached. |
| 501 | not_supported | Country's adapter doesn't expose this tool (e.g. IE has no get_officers). |
| 502 | upstream_error | Government registry returned an error or timed out. |
| 503 | jurisdiction_unavailable | Adapter not configured / credentials missing on this deployment. |
All routes return Access-Control-Allow-Origin: *. Use directly from the browser,
server-side, or any HTTP client.
Tips:
limit (default 25, max 1000 depending on tool)
and cursor or offset depending on the country.
See /docs per tool.?fresh=true bypasses the in-process
cross-call cache and hits the upstream registry directly./api/v1/companies/GB/00185647?jurisdiction=NO
treats jurisdiction=GB from the URL path; the query string is ignored.