orakel
Docs navigation

Canonical

Limitations

Known gaps, rate limits, data-freshness boundaries, and the paid-data policy.

Updated 2026-04-21

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 incrementally
  • financials 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. fiveYrSurvivalRate is null for all FI companies.
  • Stats context — wages derived: avgMonthlyWage is derived (wages sum ÷ staff-years ÷ 12) and may differ from a direct survey figure.
  • Stats context — wages currency: avgMonthlyWage is 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. fiveYrSurvivalRate is null for all SE companies.
  • Stats context — wages currency: avgMonthlyWage is 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.

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 mapMC_TO_FIELD in lib/ytj/financials.ts decodes only totalAssets reliably; other Financial columns land null for FI rows.
  • FI company universe — Phase 1 ships a seed list, not every Y-tunnus. Contact hello@orakel.cloud to 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.