Authentication, identifiers, errors and warnings — these work the same on every endpoint.
Every endpoint lives under https://api.sarora.de. There is no separate
sandbox — trial access is a normal key with a tighter quota.
export API="https://api.sarora.de" export KEY="your-key"
Every call carries the key in the X-API-Key header. Without a
valid key the API answers 401.
curl "$API/tickers/resolve/DE0007164600" \\ -H "X-API-Key: $KEY"
Four areas need no key: /health, /status, the
Swagger UI at /docs and POST /feedback. Everything
else is closed.
Wherever an endpoint expects {identifier} it accepts any of
the common identifiers — without you passing the type: ISIN, WKN,
ticker, CIK and LEI. Recognition is by shape.
DE0007164600 — two letters, twelve characters716460 — six charactersSAP, AAPL1000184 or cik:1000184529900D6BF99LW9R2E68 — 20 charactersIf a shape is ambiguous you can force it with a prefix: isin:,
wkn:, ticker:, cik:, lei:.
Errors come back as JSON with a detail field. On a
404 from the fundamentals endpoints it holds more than a string:
which entity was meant and which sources exist for it at all.
curl "$API/v1/fundamentals/XYZ/statements" -H "X-API-Key: $KEY"
{
"detail": "No statements for XYZ",
"entity": { "name": null, "resolved": false },
"suggestedSources": [],
"suggestedImporter": "tickers/resolve"
}422 on a sync endpoint is not an error: it
means there was nothing to do. Automated callers should treat it as success —
our own loop rests on exactly that.
Responses carrying fundamentals may include a warnings field.
The codes are stable and machine-readable.
A missing value is a statement here, not a failure. The rule is: a
missing value beats a wrong one. Whatever cannot be mapped with certainty
stays null — it then looks like a gap rather than like a number
you could rely on.
The most common case that looks like a bug and is not:
revenue is empty for banks, insurers and funds. A bank
does not report revenue; it reports interest income and non-interest income.
A fund reports investment income. The figures are there — they are simply
called something else:
net_interest_income, interest_income, noninterest_incomepremiums_earned, investment_incomeinvestment_income — there is no revenue line in the statementOf 6,480 US issuers with fundamentals, 915 carry no revenue.
Around 258 of those are banks and insurers and roughly 400 are funds, BDCs or
SPACs. We deliberately do not synthesise a revenue figure for them from
other lines: that would be a number appearing in no published statement.
The same holds for gross_profit (close to half of all issuers
report none — banks and many service businesses do not use the measure) and
for operating_income in the financial sector.
What is actually present is answered by
GET /v1/fundamentals/{identifier}/coverage before you query —
pools, period and metric coverage.
Endpoints under /v1 carry a promise: the metric vocabulary and
the response shape change only with a new version. The remaining endpoints
grew over time and stay as they are — we take nothing away, but they carry no
such promise.
Three steps: resolve the identifier, check coverage, fetch the figures.
curl "$API/tickers/resolve/DE0007164600" -H "X-API-Key: $KEY" curl "$API/v1/fundamentals/SAP/coverage" -H "X-API-Key: $KEY" curl "$API/v1/fundamentals/SAP/metrics?metrics=revenue&years=5" \\ -H "X-API-Key: $KEY"
The middle step is worth it: it tells you which data pools exist for this issuer and how far they reach — before you build a query that comes back empty.