Documentation → Basics
Documentation

Basics

Authentication, identifiers, errors and warnings — these work the same on every endpoint.

Base URL

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"

Authentication

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.

Identifiers

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.

If a shape is ambiguous you can force it with a prefix: isin:, wkn:, ticker:, cik:, lei:.

Errors

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.

Warnings instead of silent assumptions

Responses carrying fundamentals may include a warnings field. The codes are stable and machine-readable.

When a metric is missing

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:

Of 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.

Versioning

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.

Your first call

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.