Canonical
Limitations
Known gaps, rate limits, data-freshness boundaries, and the paid-data policy.
This page catalogs what Orakel doesn't do. Known gaps are explicit choices, not bugs — most trace back to the paid-data policy below.
Rate limits
Per-key throughput is tier-based (lib/tiers.ts). Individual keys can override any tier default via ApiKey.rateLimit, ApiKey.dailyLimit, ApiKey.monthlyLimit.
| Tier | Requests / minute | Daily | Monthly | Max page size |
|---|---|---|---|---|
free |
20 | 500 | 5,000 | 20 |
pro |
60 | 5,000 | 50,000 | 100 |
enterprise |
120 | unlimited | unlimited | 100 |
internal |
120 | unlimited | unlimited | 100 |
Per-IP guards (lib/rate-limit.ts):
- API auth failures — 20 per 15 min
- Admin login — 5 per 15 min
- Magic-link send — 5 per email per hour
- Access-request form — 3 per hour
Anti-scrape guards:
- Cursor depth — 50 pages per 5 min per key on
/api/companies - Free tier must pass at least one filter to
/api/companies(requireFilterOnSearch)
All limiters are in-memory; counters reset on deploy. Single server, no Redis. Quota counts are DB-backed (UsageLog) with a 60 s in-memory cache.
Data freshness
| Source | Cadence | Lag bound |
|---|---|---|
| Brreg companies (NO) | Diff every 15 min | ~15 min |
| Brreg companies (NO) | Monthly full snapshot | 1 month max |
| Regnskapsregisteret (NO) | Continuous, chunked | 6 months after fiscal year end |
| Aksjonærregisteret (NO) | Annual snapshot | ~1 year |
| Doffin (NO) | Daily incremental | ~24 h |
| Mattilsynet (NO) | Weekly (Mon 05:00) | ~1 week |
| Helsedirektoratet TBR (NO) | Weekly (Mon 07:00) | ~1 week |
| SSB Klass (NO) | Classifications on-demand; stats monthly (1st, 06:00) | varies |
| PRH / YTJ (FI) | Weekly (Mon 03:00 UTC) | ~1 week |
| Tilastokeskus XBRL (FI) | Daily (04:00 UTC) | ~24 h |
| Bolagsverket + SCB (SE) | Daily (05:00 UTC) | ~24 h |
| Enrichment pipeline | Daily chunks + weekly seed | ~24 h |
Times are UTC unless stated. Lag bounds are upper bounds at steady state; cold starts and access-gated sources (e.g. Regnskapsregisteret preview API) can exceed them.
Financial-year depth
Coverage depth differs by country because the upstream APIs behave differently:
- NO (Brreg Regnskapsregisteret). Returns only the latest filed year per fetch. Multi-year coverage accumulates passively across sync runs — roughly one new year per calendar year of operation. A company first synced today returns one year; deeper history requires Brreg's paid Regnskapsregisteret archive (not purchased under the paid-data policy).
- FI (Tilastokeskus XBRL). Lists all available digital filing periods per company and fetches each, so multi-year history arrives in one sync — bounded by the ~30K digital-filer universe noted in
KNOWN_GAPS.FI. - SE (Bolagsverket HVD). iXBRL from FY 2020+; pre-2020 is paper-only. See
KNOWN_GAPS.SE.
Country coverage
Norway, Finland, Sweden (Phase 3a + 3b), and Denmark are live. SE Phase 3c roles awaits Bolagsverket «Företagsinformation» credential application — no timeline.
The per-entity matrix lives in the field catalog.
KNOWN_GAPS.FI — from lib/countries.ts, verbatim:
roles — not exposed by free PRH APIs (paid Virre only)financial field decoding — dimensional XBRL taxonomy; only totalAssets reliably mapped from one fixture, expand incrementallyfinancials coverage — ~30K digital filers; paper filings require paid Virre
FI stats context (Tilastokeskus StatFin):
- Stats context — survival rate: StatFin does not expose cohort survival rates via PxWeb.
fiveYrSurvivalRateis null for all FI companies. - Stats context — wages derived:
avgMonthlyWageis derived (wages sum ÷ staff-years ÷ 12) and may differ from a direct survey figure. - Stats context — wages currency:
avgMonthlyWageis in EUR.
KNOWN_GAPS.SE — from lib/countries.ts, verbatim:
roles — requires separate Bolagsverket «Företagsinformation» credential (apply when customer asks)financials coverage — HVD contains only digitally filed iXBRL from FY 2020+; digital filing was voluntary through FY 2025 so large/listed ABs (Volvo, H&M, Ericsson) historically filed PDF and are absent. Mandatory FY 2026 → first large-AB filings arrive spring 2027.financials pre-2020 — paper-only, no digital history
SE stats context (SCB):
- Stats context — survival rate: SCB does not expose enterprise survival cohorts via PxWeb API.
fiveYrSurvivalRateis null for all SE companies. - Stats context — wages currency:
avgMonthlyWageis in SEK.
KNOWN_GAPS.DK — from lib/countries.ts, verbatim:
beneficial ownership — post-Sept 2025 6AMLD requires legitimate-interest justification; skipped by default
GDPR obligations
Aksjonærregisteret contains personal data. If you re-distribute shareholder records, you need a documented legal basis. See Aksjonærregisteret for the full discussion — Orakel's own legal basis is Art. 6(1)(f) legitimate interest, natural-person rows are hidden unless ?includePersons=true, and birth dates are never stored.
Paid-data policy
Orakel ships on free public data only. Paid subscriptions (Virre, Näringslivsregistret, Bisnode, D&B, Vainu, Apollo, Proxycurl-at-scale, BuiltWith, etc.) are not purchased until a specific paying customer's contract revenue covers the cost. Gaps are documented and shipped empty. When a customer asks for gap-covered data, the paid subscription is priced into the deal.
Current gaps that trace to this policy:
| Country | Gap | Paid source that would fill it |
|---|---|---|
| FI | Board members / responsible persons (roles) | Virre |
| FI | Financials for ~paper filers | Virre |
| FI | Full XBRL concept map (only totalAssets decoded) |
Taxonomy reference data |
| SE | Roles | Näringslivsregistret |
| SE | Financials pre-2020 | Paper archive digitisation |
| DK | Beneficial ownership post-Sept 2025 | 6AMLD legitimate-interest process |
| All | Enrichment at scale | Bisnode, D&B, Vainu, Apollo, Proxycurl, BuiltWith, Clearbit, ZoomInfo |
Gaps are documented rather than back-filled with speculative paid data. When a specific field is required for a customer use case, Orakel prices the source into the engagement rather than shipping it as a general feature.
Known stubs and partial features
- SSB Klass Tier 2 — planned expansion beyond the current three tables (07459, 11419, 14000). Not yet exposed.
- FI XBRL concept map —
MC_TO_FIELDinlib/ytj/financials.tsdecodes onlytotalAssetsreliably; otherFinancialcolumns land null for FI rows. - FI company universe — Phase 1 ships a seed list, not every Y-tunnus. Contact
hello@orakel.cloudto have a specific company added. - SE financials — schema present, ingestion pending Phase 3b credentials.
- SE natural-person enskild firma — 12-digit personal orgNumbers are skipped in Phase 3a.
Response headers lag the source list
lib/attribution.ts sets X-Data-Source to the NO-only source list and X-Data-License: NLOD 2.0 on every response. After Phase 1 (FI) and Phase 3a (SE), PRH, Tilastokeskus, Bolagsverket, and SCB data is returned by the API but not reflected in those headers — the header is kept as a country-agnostic NLOD 2.0 compliance signal, not a dynamic per-response source list.
For accurate per-response attribution use the _sources body field — it reflects the exact sources contributing to each response and stays in sync as new countries and enrichers come online.
Security boundaries
API keys are SHA-256 hashed at rest — if lost, issue a new one; they cannot be recovered. Destination configs (Attio tokens, webhook secrets) are AES-256-GCM encrypted at rest. Admin sessions are DB-backed, httpOnly, sameSite=strict, 24 h expiry. Secret comparisons are timing-safe. CSRF tokens are required on admin mutations.