Nexus Filings™ / docs
v1 · stable Authentication Reference Playground Dashboard

API documentation

Normalized financial data built from official filings. Every response uses the same schema, whatever the country or accounting taxonomy of origin.

Quickstart

1. Create your free API key (no card needed) from the dashboard. 2. Send your first request:

curl
curl "https://api.nexusfilings.io/v1/companies/search?q=sample" \
  -H "X-API-Key: YOUR_API_KEY"

3. With the id returned by the search, request the detail:

curl
curl "https://api.nexusfilings.io/v1/companies/GB:SC000001/financials" \
  -H "X-API-Key: YOUR_API_KEY"

Authentication

Every call (except the billing webhook) requires the X-API-Key header.

⚠ Do not expose your API key in frontend code or in public repositories. If you think it leaked, generate a new one from the dashboard — the old one stops working. There is no way to "recover" a compromised key, only to replace it.

Base URL and environments

environments
Production      https://api.nexusfilings.io/v1
Development     http://127.0.0.1:8420/v1   (local server, for your own testing only)

Endpoints

MethodEndpointUsage unitsDescription
GET/companies/search0Search by name and/or by exchange
GET/companies/{id}/financials1 per company returnedNormalized detail. Free: 1 fiscal year per request (selectable with ?fiscal_year=); paid plans: their whole history in one request
POST/companies/batch1 per company returnedDetail of several companies; ids without data cost 0 — not available on Free
POST/screen1 per company in the resultsFilter by metrics; 0 results cost 0 — not available on Free

Search companies

Searches by name (q, at least 2 characters) across the demo catalog and the real listed companies of the UK, Denmark, Norway and SEC-registered US companies. Real matches include preloaded: true if data for that company is already stored. It doesn't use any usage units. Business plans also search the full UK registry (non-listed companies, via Companies House), with registry and company_status; in Denmark, Norway and the United States the search covers listed/registered companies only.

You can also search by exchange with exchange (e.g. ?exchange=Nasdaq, ?exchange=XLON for the London Stock Exchange Main Market, ?exchange=AIMX for AIM) — case-insensitive, exact match. At least one of q or exchange is required; passing both returns the union of both searches. Exchange search only covers listed/registered companies (it never applies to the full UK registry or the demo catalog).

GET /companies/search
{
  "results": [
    { "id": "GB:SC000001", "name": "Sample Trading Ltd", "jurisdiction": "GB" }
  ]
}

Financial detail

The number of years returned depends on the plan (see limits): Free returns one fiscal year per request (the latest, or the one you request with ?fiscal_year=2024; the response includes available_years with the years you can ask for), and paid plans return their whole history in a single request. Every field carries its provenance: direct if it comes as-is from the filing, derived if Nexus calculated it, or unavailable if it could not be obtained or derived with confidence. Amounts are in the filing's own currency — never converted.

GET /companies/GB:SC000001/financials
{
  "company_id": "GB:SC000001",
  "years_returned": 1,
  "filings": [{
    "income_statement": {
      "revenue": { "value": 1250000, "source": "direct" },
      "net_profit": { "value": 95500, "source": "direct" }
    },
    "ratios": {
      "net_margin": { "value": 0.0764, "source": "derived" }
    }
  }]
}

First request for a company that is not preloaded — asynchronous response

Companies in the main catalog (large / listed) always answer instantly — they are preloaded. If you request a company (from the UK or Denmark) outside that catalog that nobody has asked for before, its first filing has to be downloaded and processed on the spot, which can take a few minutes (longer for large Danish companies). If no data can be found for the company (it doesn't exist or never filed accounts), the retry returns 404 company_data_unavailable, and if the source registry fails, 502 source_unavailable; the result is remembered for a few minutes so it isn't retried on every request. Instead of leaving the HTTP connection waiting all that time (many clients and load balancers cut the connection earlier anyway), the endpoint returns 202 Accepted immediately:

GET /companies/{id}/financials — first time, not cached
// HTTP 202
{
  "status": "processing",
  "company_id": "GB:07209813",
  "detail": "First request for this company: its real filings are being downloaded and processed...",
  "retry_after_seconds": 10
}

The API's detail fields are always in English; the error codes are stable and are what you should handle in code. Repeat the same GET after retry_after_seconds — while it is processing in the background it keeps returning 202; as soon as it finishes it returns 200 with the full filing, exactly the same shape as a normal request. Polling retries are not charged extra units, only the original request that triggered the processing. In addition, each plan has a monthly allowance of new companies to process (Free 5, Pro 50, Business 500): only the request that triggers a new processing counts, not retries or already-processed companies. If it runs out, the API responds 429 new_company_processing_limit_reached; if the shared daily capacity runs out, 503 processing_capacity_reached.

Batch

Charged by the number of companies returned, not per call: 1 usage unit per company that comes back with data. An ID that doesn't exist returns null in its place, costs nothing and doesn't abort the rest of the batch; the response includes units_charged. It also serves real UK and Danish companies that are already processed; a batch never triggers the processing of a new company, so the ones with a real-company format but no data yet come back as null and are listed in not_preloaded — request them one by one with GET /companies/{id}/financials.

POST /companies/batch
// body
{ "ids": ["GB:SC000001", "DK:12345678"] }

Screening

Charged by the number of companies returned, not per call: 1 unit per company in the results, and 0 units if none match. It scans the demo data and the real listed UK and Danish companies that are already preloaded. Screening is limited per minute by plan (see limits): beyond it the API answers 429 screening_rate_limited, which costs nothing.

POST /screen
// body
{ "jurisdiction": "GB", "min_net_margin": 0.10 }

Response schema

Every filing, whatever the country, returns exactly these groups of fields:

structure
income_statement   revenue · gross_profit · operating_profit · net_profit
balance_sheet      total_assets · total_liabilities · equity · cash_and_equivalents · net_debt
ratios             gross_margin · net_margin · roe   (always "derived")

Error codes

400

batch_too_large

More IDs were requested than the plan allows in a single call.

401

invalid_or_missing_api_key

The X-API-Key header is missing or the key doesn't exist.

403

*_not_available_on_plan

The endpoint (batch or screening) or the full registry is not included in your current plan.

404

company_not_found

No company exists with that ID.

429

burst_exceeded / monthly_quota_exceeded

You exceeded the rate limit (per second) or the monthly usage allowance. remaining_monthly comes in the body when applicable.

429

screening_rate_limited

You exceeded the plan's screenings per minute (see the limits table). It costs no usage units; retry after retry_after_seconds.

422

invalid_request

A parameter or the JSON body is missing or has the wrong type or format (for example q in a search, a non-numeric fiscal_year, or ids that is not a list of strings up to 64 characters each). The detail array lists each field and its message.

413

request_too_large

The request body is larger than 1 MiB.

400

password_too_long

Passwords are limited to 1,000 characters.

404

fiscal_year_not_available

The requested fiscal_year isn't available for that company or plan. The body includes available_years.

404

company_data_unavailable

No financial data could be found for the company (it doesn't exist or never filed accounts). The result is remembered for a few minutes.

429

new_company_processing_limit_reached

The plan's monthly allowance of new companies to process is used up. Already processed companies are unaffected.

502

source_unavailable

The source registry didn't respond or failed while processing the company. Retry later.

503

processing_capacity_reached

The shared daily capacity to process new companies is used up. Already processed companies remain available; retry after retry_after_seconds.

500

internal_server_error

Our error, not yours. If it persists, contact us with the request timestamp.

Limits and plans

ℹ 7-day free trial of Pro, no card. Verify your email address in the dashboard, then start the trial from the Subscription section. You get every Pro benefit, with up to 10 new companies processed during the trial (instead of 50). When it ends your account returns to Free automatically. One trial per person.
ℹ 1 company returned = 1 usage unit. Batch and screening requests are charged by the number of companies returned, not by the number of API calls: a request that returns 50 companies uses 50 units from your monthly allowance, exactly like 50 single requests. Searching costs 0; requests that fail or return nothing cost 0; retries while a new company is being processed cost nothing (you are charged once, when the data is delivered).
FreeProPro TeamBusiness
Companies / month (usage units)2505,00010,00050,000
Burst (req/sec)25820
History1 year5 years5 yearsfull (up to the last 5 filed fiscal years)
Years per request1whole historywhole historywhole history
All registered companies, listed or not (full registry)not availablenot availablenot availableincluded
Batch (max IDs)not available2040100
Screeningnot availableincludedincludedincluded
Screenings per minutenot available203060
New companies processed / month550100500
Users per workspace11up to 5 (3 included + 2 extra)up to 10 (6 included + 4 extra)

Pro, Pro Team and Business are billed monthly or annually — annual billing is 2 months free compared to paying monthly (16.7% off, e.g. Pro is $49/month or $490/year). Every limit above renews every month regardless of the billing interval you choose: an annual subscription doesn't accumulate 12 months of allowance into a single year, it gets the same monthly allowance renewed 12 times.

Pro Team and Business are shared workspaces: everyone in the team has their own API key, but they all draw from the same monthly allowance above — it isn't multiplied per user. Only the workspace owner manages billing and invites or removes members; extra seats beyond the included count are $25/month each, billed together with the plan and prorated immediately. Extra seats can only be purchased once every included seat is already filled — invite teammates first, then buy more capacity.

To cancel a paid subscription (or just review invoices and the payment method on file), go to the Subscription screen of the dashboard and press Manage subscription — it opens our payment provider's Customer Portal, where cancellation actually happens. We never cancel a subscription from inside Nexus Filings directly, so this button is the only way to do it.

Support and contact

ForWrite to
Technical support and API issues (include the request timestamp and, if you have it, the company_id)support@nexusfilings.io
Sales, Business and Enterprise planssales@nexusfilings.io
General questions, privacy and legalcontact@nexusfilings.io

Pro plans get email support and Business plans get priority support, both through the developer support address. Nexus Filings is a product of Kimera Software SAS, Maldonado, Uruguay.

Python SDK

bash
pip install nexus-filings
python
from nexus_filings_sdk import NexusFilingsClient

client = NexusFilingsClient(api_key="YOUR_API_KEY")
results = client.search("sample")
filing = client.get_financials("GB:SC000001")
print(filing["filings"][0]["income_statement"]["revenue"])

JavaScript / TypeScript SDK

bash
npm install nexus-filings
javascript
import { NexusFilingsClient } from "nexus-filings";

const client = new NexusFilingsClient({ apiKey: "YOUR_API_KEY" });
const results = await client.search("sample");
const filing = await client.getFinancials("GB:SC000001");

OpenAPI and other languages

We publish the full specification in OpenAPI 3.0. Any language without an official SDK — Rust, PHP, Go, Ruby, .NET — can generate a typed client from it with openapi-generator, or import it straight into Postman/Insomnia to test without writing code.

ℹ The spec lives in openapi.yaml in the project repository. If your language doesn't have its own SDK yet, this is the recommended route.

MCP server (beta)

Connect an AI assistant (Claude Code, Cursor, …) to Nexus Filings through the Model Context Protocol. The assistant can search companies, fetch normalized financials, run batch requests and screen by net margin — using your account's plan and usage units, exactly like the REST API.

endpoint
https://api.nexusfilings.io/mcp      (Streamable HTTP, stateless)

Authentication. Two options. API key: send it in a header, Authorization: Bearer YOUR_API_KEY or X-API-Key: YOUR_API_KEY (Claude Code, Claude Desktop, Cursor). The key is never accepted in the URL (query string). OAuth sign-in: for apps that don't accept keys (ChatGPT, Claude on the web) add the endpoint above as a custom connector and choose to sign in — you authorize with your Nexus Filings email and password on a page hosted by the API, and the app never sees them. Both use the same plan and usage units. You can review and revoke connected apps in the dashboard (Connect to AI); changing your password revokes them all.

ToolUsage unitsWhat it does
search_companies0Search by (partial) name; returns ids like GB:07209813
get_financials1 per companyNormalized financials of one company (optional fiscal_year); compact values plus the formula of every derived field
batch_financials1 per company returnedSeveral companies at once — Pro and Business
screen_companies1 per company returnedFilter processed companies by net margin and jurisdiction — Pro and Business
Claude Code
claude mcp add --transport http nexus-filings https://api.nexusfilings.io/mcp \
  --header "Authorization: Bearer YOUR_API_KEY"
Cursor — mcp.json
{
  "mcpServers": {
    "nexus-filings": {
      "url": "https://api.nexusfilings.io/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY" }
    }
  }
}
ℹ The first request for a company nobody has asked for before can take a few minutes. The tool waits up to about 45 seconds and, if the company is still being processed, answers processing — ask again a minute later (retries cost nothing). OAuth sign-in follows OAuth 2.1 (PKCE S256, dynamic client registration, refresh-token rotation) and is in beta: we have tested it with the official MCP client, not yet with every third-party app.

Guides

01 — Search and fetch a company's financials

Almost every flow starts the same way: search by name to get the id, then request the detail with it.

python
matches = client.search("sample")
company_id = matches[0]["id"]
filing = client.get_financials(company_id)

02 — Compare the UK and Denmark with the same schema

The real value of the unified schema: two countries, two different accounting taxonomies (UK GAAP and DK GAAP), the same field name in the response.

python
uk = client.get_financials("GB:SC000001")["filings"][0]
dk = client.get_financials("DK:12345678")["filings"][0]

for f in (uk, dk):
    r = f["income_statement"]["revenue"]
    print(f["company"]["jurisdiction"], r["value"], f["currency"])

03 — Screen companies by net margin

Available on Pro and Business. It returns only the companies that meet the filter, and charges according to that number of results.

python
result = client.screen(jurisdiction="GB", min_net_margin=0.10)
for company in result["results"]:
    print(company["name"], company["net_margin"])