Denne guiden er skrevet for utviklere og kodeagenter som skal hente selskapsdata fra Companybook inn i et eget system, for eksempel et CRM, et datavarehus eller en kundeliste som skal berikes hver natt. Følg stegene i rekkefølge. Alt som står her kan kontrolleres mot OpenAPI-kontrakten.
1. Hva du trenger
- En Companybook-konto med Plus. REST API er en del av Plus (personlig) og Business Plus (team). Free-kontoer kan bruke MCP, men får
403 plan_requiredpå REST. Kontoer opprettes i lukket beta via ventelisten. - En API-nøkkel. Opprett den under Agenttilgang → Ny tilgang. Er du medlem av et team med Business Plus, velg teamet under Trekk credits fra, så belastes teamets felles saldo.
- Nøkkelen i en miljøvariabel på serveren, for eksempel
COMPANYBOOK_API_KEY. Aldri i kildekode, logger, nettleserkode eller en chat.
Kontroller tilgangen før du bygger noe:
curl -s https://companybook.co/api/v1/me -H "Authorization: Bearer $COMPANYBOOK_API_KEY"
Svaret skal ha "api_access": true. Feltet credential gjelder nøkkelen du kaller med: billed_to (personal eller team), hvilken saldo som belastes (credential.credits), grensene (credential.limits) og hvor mye som er brukt i dag og denne måneden (credential.used). For en teamnøkkel er det teamets saldo og grenser som gjelder; credits på toppnivå er brukerens personlige saldo. /me og /capabilities virker på alle planer; resten krever Plus.
2. Slik er API-et bygget opp
| Operasjon | Bruk |
|---|---|
GET /resolve?query=…&types=["org"]&limit=5 | Finn et selskap fra navn eller organisasjonsnummer. Gir kandidater med id, name og score. |
POST /entities/batch | Hent opptil 100 selskaper i ett kall (25 på Free via MCP), med valgfrie utvidelser. Dette er arbeidshesten for integrasjoner. |
GET /entities/{id} | Samme som over for ett selskap. |
POST /search | Finn selskaper med filtre (kommune, NACE, omsetning, organisasjonsform). |
POST /traversals | Følg relasjoner som eierskap, maks tre hopp. |
GET /usage | Eget forbruk siste 30 dager. |
Base-URL er https://companybook.co/api/v1. Alle svar på dataoperasjoner er en cb/v1-konvolutt med data, coverage, warnings, as_of, truncated og cost.
Selskaps-ID-er har formen cb:org:<organisasjonsnummer>, for eksempel cb:org:923609016. Et organisasjonsnummer er alltid 9 siffer.
3. Hent mange selskaper i ett kall
Har du organisasjonsnumrene, bruk POST /entities/batch med extend:
curl -s https://companybook.co/api/v1/entities/batch \
-H "Authorization: Bearer $COMPANYBOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": ["cb:org:923609016", "cb:org:817209882"],
"extend": ["financial_history", "subunits", "web_identities", "group_parent"]
}'
ids: 1–100 ID-er per kall. Anbefalt: 50 per kall når du bruker alle fire utvidelsene, og kall sekvensielt, ikke parallelt.extender valgfritt. Utelat utvidelser du ikke trenger; hver utvidelse øker datamengden som måles.includeer noe annet: relasjoner (kanter) følger bare med når du ber om dem, for eksempel["HAS_ROLE"], eller["*"]for alle. Utenincludefår du ingen kanter, men hvert selskap haractive_predicatessom viser hvilke relasjoner som finnes og hvor mange. Kanter teller som poster.
Felter per selskap (data.entities[].payload)
| Felt | Betydning |
|---|---|
org_nr, name | Organisasjonsnummer og navn |
entity_type, parent_org_nr | hovedenhet eller underenhet, og hovedenheten til en underenhet |
org_form, org_form_description | Organisasjonsform, f.eks. AS |
nace_code, nace_description, secondary_nace_code, secondary_nace_description | Næringskoder |
address, postal_code, city, municipality, municipality_code | Forretningsadresse |
postal_address, postal_address_postal_code, postal_address_city | Postadresse |
latitude, longitude | Koordinater for forretningsadressen |
employees, founded_date, registration_date | Ansatte og datoer |
is_bankrupt, is_liquidating, is_under_forced_liquidation, is_deleted, deleted_at, cessation_date | Status. Bruk disse til kredittvarsel |
is_in_group, last_annual_report_year, registered_in_vat | Konsernflagg, siste regnskapsår, MVA-registrering |
Et felt som mangler i payload, er ukjent. Det betyr ikke false eller 0.
Utvidelser (data.extensions, nøklet på organisasjonsnummer)
| Utvidelse | Innhold |
|---|---|
financial_history | Alle regnskapsår, nyeste først. Kun selskapsregnskap (ikke konsern). Ett år per rad; er året både fra Proff og Brønnøysund, vinner Proff. Felter: fiscal_year, revenue, operating_costs, operating_result, result_before_tax, net_result, total_assets, total_equity, total_debt, source. Maks 30 år. |
subunits | Underenheter registrert på hovedenheten, med adresse, næring, ansatte og koordinater. Maks 50 per selskap i en batch. Ber du om ett selskap alene (GET /entities/{id}), får du opptil 1000. Er en liste avkortet, står organisasjonsnummeret i data.extensions_truncated.subunits. Underenhetene har de samme feltnavnene som selskapet (nace_code, nace_description, address, postal_code, city, municipality_code). De gamle registernavnene (industry_code, address_street osv.) følger med til v2, men ny kode bør bruke de nye. |
web_identities | Nettsted og sosiale profiler: identity_type, full_url, is_primary, og for nettsteder site_kind og site_status (skill et aktivt nettsted fra et parkert domene). |
group_parent | Øverste eier i eierkjeden (org_nr, name, depth), fulgt gjennom aksjonærregisteret, eller null hvis ingen eier over selskapet er registrert. Ikke det samme som registrert konsern: group_parent finnes også for selskaper som ikke er i et konsern i Brønnøysund (is_in_group er false). Vil du bare ha konsernmor i registerets forstand, bruk group_parent kun når is_in_group er true. |
Kontaktinformasjon som e-post og telefon leveres ikke via API-et.
Utvidelsene gjelder selskapet du ber om. For en underenhet ligger regnskap, konsern og ofte nettsted på hovedenheten: hent parent_org_nr i samme eller neste kall.
4. SDK for TypeScript og JavaScript (beta)
@companybook/sdk pakker stegene over: nøkkelkontroll, batcher på 50, sekvensielle kall, Retry-After ved 429 og typede feil. Ingen avhengigheter; krever Node 20 eller nyere.
import { Companybook } from '@companybook/sdk';
const cb = new Companybook({ apiKey: process.env.COMPANYBOOK_API_KEY });
const { entities, extensions, missing, units } = await cb.entities.batchAll(orgNumbers, {
extend: ['financial_history', 'web_identities', 'group_parent'],
});
const { subunits, truncated } = await cb.entities.subunits('817209882');
const left = await cb.remaining(); // poster og kall igjen i dag og denne måneden
Feil kommer som CompanybookError med status, code, retryAfter og fatal (401, 402, 403: stopp kjøringen).
5. Når du bare har et navn
Bruk GET /resolve og kontroller treffet før du lagrer koblingen:
curl -s -G https://companybook.co/api/v1/resolve \
-H "Authorization: Bearer $COMPANYBOOK_API_KEY" \
--data-urlencode 'query=Vinmonopolet' \
--data-urlencode 'types=["org"]' \
--data-urlencode 'limit=5'
score rangerer kandidatene, men er ikke en sannsynlighet. Godta et treff automatisk bare når navnet og postnummeret eller poststedet stemmer med det du har fra før. Ellers: legg det til manuell kontroll.
6. Forbruk og grenser
- All bruk måles, også gratis data. Grunndata koster 0 credits, men teller mot volumgrensene: på Plus 120 kall i minuttet, 10 000 kall og 50 000 poster per døgn. Utvidelser teller som poster.
- API-et reserverer plass før kallet og avregner faktisk mengde etterpå. Et kall med 100 ID-er og alle utvidelser reserverer mye, men belaster bare det som leveres.
- Sjekk
credential.usedogcredential.limitsiGET /mefør en stor kjøring; tellerne er de samme som grensene håndheves mot, ogcredential.resetssier når døgnet og måneden nullstilles (UTC). - Følg eget forbruk i bruksoversikten eller med
GET /usage. Teamnøkler vises under teamet i bruksoversikten.
7. Feil og hva du skal gjøre
| Status og kode | Betydning | Gjør dette |
|---|---|---|
401 authentication_required / invalid_token | Nøkkelen mangler, er feil eller er tilbakekalt | Stopp. Ikke prøv igjen med samme nøkkel. |
403 plan_required | Planen dekker ikke operasjonen; svaret har required_tier og upgrade_url | Stopp og si fra til eieren av kontoen. |
400 invalid_arguments | For mange ID-er, ukjent utvidelse eller feil format | Rett forespørselen; ikke prøv igjen uendret. |
402 credits_exhausted | Saldoen er brukt opp | Stopp til neste måned eller til saldoen er økt. |
429 volume_limit / expense_limit | Volumgrensen er nådd | Vent minst Retry-After sekunder. Ikke lag flere nøkler for å komme rundt grensen. |
503 data_unavailable / metering_unavailable | Midlertidig feil hos oss | Prøv igjen senere med samme forespørsel. |
8. Anbefalt oppsett for en nattlig synk
- Les listen over organisasjonsnumre fra ditt eget system og fjern duplikater.
- Del opp i grupper på 50 og kall
POST /entities/batchsekvensielt med de utvidelsene du trenger. - Lagre
as_ofsammen med dataene. Hent ikke samme selskap oftere enn én gang i døgnet: registerdata endrer seg sjelden raskere. - Ved
429: ventRetry-Afterog fortsett der du slapp. Ved403eller401: avbryt hele kjøringen og varsle. - Logg antall selskaper, antall mangler (
coverage.missing) ogcost.unitsper kjøring. Logg aldri nøkkelen.
9. Slik vet du at integrasjonen virker
GET /megirapi_access: true.- Et batch-kall med
cb:org:923609016(Equinor ASA) girentity_type: "hovedenhet"og flere år idata.extensions.financial_history["923609016"]. - Et kall med en ID som ikke finnes gir ID-en i
coverage.missing, ikke en feil. - Forbruket vises i bruksoversikten innen et minutt.
Mer
- OpenAPI-kontrakt — autoritativ beskrivelse av alle operasjoner.
- MCP-guide — for agenter som kobler seg til med MCP i stedet for REST.
- Plan og tilgang — hva som inngår i Free og Plus.