Tilbake
API og webhooks
API og webhooks
Innstillinger

Et versjonert REST-API for å lese og skrive selskapets data, og webhooks som varsler deg når noe skjer. Alle endepunkter er dokumentert her.

  1. Gå til Innstillinger → Integrasjoner
  2. Opprett et token med bare de tilgangene integrasjonen trenger
  3. Velg levetid — tolv måneder er standard
  4. Kopier tokenet — det vises bare én gang

Send tokenet som Authorization-header på hvert kall:

curl https://konradoffice.no/api/v1/contacts \
  -H "Authorization: Bearer kon_xxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"

Tokenet avgjør hvilket selskap kallet handler på vegne av. Det finnes ingen parameter for å bytte selskap, og et token når aldri data utenfor sitt eget.

Bare eier og daglig leder kan opprette tokens. Alle svar er JSON, og alle datoer er ISO 8601.

Alt ligger under /api/v1. Versjonen står i stien fra første dag, så en endring som bryter noe er noe man velger å ta i bruk, ikke noe man våkner til.

MetodeStiTilgangGjør
GET/api/v1/contactscontacts:readListe kontakter
GET/api/v1/contacts/{id}contacts:readHente én kontakt
POST/api/v1/contactscontacts:writeOpprette kontakt
GET/api/v1/productsproducts:readListe produkter
GET/api/v1/products/{id}products:readHente ett produkt
POST/api/v1/productsproducts:writeOpprette produkt
GET/api/v1/invoicesinvoices:readListe fakturaer
GET/api/v1/invoices/{id}invoices:readHente én faktura med linjer

Disse tilgangene finnes også, men har ingen endepunkter ennå: vouchers:read og webhooks:manage.

GET /api/v1/contacts

Krever contacts:read. Parametre:

ParameterBetydning
typecustomer, supplier eller both
searchFritekst mot navn
updated_sinceBare kontakter endret etter dette tidspunktet
per_page1–100, standard 25
{
  "data": [
    {
      "id": 12,
      "contact_number": "CON20260012",
      "type": "customer",
      "is_private": false,
      "name": "Bakeriet AS",
      "organization_number": "123456789",
      "email": "post@bakeriet.no",
      "phone": "22334455",
      "address": {
        "street": "Storgata 1",
        "postal_code": "0155",
        "city": "Oslo",
        "country": "NO"
      },
      "payment_terms_days": 14,
      "is_active": true,
      "created_at": "2026-08-30T09:15:00+02:00",
      "updated_at": "2026-08-30T09:15:00+02:00"
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": "..." },
  "meta": { "current_page": 1, "per_page": 25, "total": 143 }
}

GET /api/v1/contacts/{id}

Krever contacts:read. Samme felter, uten data-liste. Kontakter i andre selskaper gir 404.

POST /api/v1/contacts

Krever contacts:write.

FeltKravMerknad
namePåkrevdMaks 255 tegn
typePåkrevdcustomer, supplier eller both
organization_numberValgfriNøyaktig ni siffer
emailValgfriGyldig e-postadresse
phoneValgfriMaks 30 tegn
address, postal_code, cityValgfri
countryValgfriTo bokstaver, standard NO
payment_terms_daysValgfri0–365, standard 14
curl -X POST https://konradoffice.no/api/v1/contacts \
  -H "Authorization: Bearer kon_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Bakeriet AS","type":"customer","organization_number":"123456789"}'

Svarer 201 med den opprettede kontakten. Kontaktnummer tildeles automatisk. Utløser webhooken contact.created.

GET /api/v1/products

Krever products:read. Parametre:

ParameterBetydning
searchFritekst mot navn
active_onlytrue utelater deaktiverte produkter
updated_sinceBare produkter endret etter dette tidspunktet
per_page1–100, standard 25
{
  "data": [
    {
      "id": 7,
      "sku": "KAFFE-500",
      "name": "Kaffe 500 g",
      "description": "Mørkbrent",
      "price": 129.00,
      "cost_price": 74.50,
      "is_stocked": true,
      "is_active": true,
      "created_at": "2026-08-30T09:15:00+02:00",
      "updated_at": "2026-08-30T09:15:00+02:00"
    }
  ]
}

GET /api/v1/products/{id}

Krever products:read.

POST /api/v1/products

Krever products:write.

FeltKravMerknad
namePåkrevdMaks 255 tegn
pricePåkrevdTall, minst 0
skuValgfriMå være ledig i selskapet
descriptionValgfriMaks 1000 tegn
cost_priceValgfriTall, minst 0
is_stockedValgfriOm produktet lagerføres

Svarer 201 med det opprettede produktet.

GET /api/v1/invoices

Krever invoices:read. Sortert med nyeste fakturadato først.

ParameterBetydning
contact_idBare fakturaer til denne kontakten
unpaid_onlytrue gir bare ubetalte
from, toAvgrenser på fakturadato
per_page1–100, standard 25

GET /api/v1/invoices/{id}

Krever invoices:read. Denne tar med fakturalinjene; listen gjør det ikke.

{
  "data": {
    "id": 42,
    "invoice_number": "F-2026-0042",
    "type": "invoice",
    "contact_id": 12,
    "invoice_date": "2026-06-15",
    "due_date": "2026-07-15",
    "amounts": {
      "subtotal": 10000.00,
      "discount_total": 0.00,
      "vat_total": 2500.00,
      "total": 12500.00,
      "balance": 12500.00
    },
    "sent_at": "2026-06-15T10:02:00+02:00",
    "paid_at": null,
    "lines": [
      {
        "id": 91,
        "description": "Konsulenttimer",
        "quantity": 10.0,
        "unit": "time",
        "unit_price": 800.00,
        "discount_percent": 0.0,
        "vat_percent": 25.0,
        "line_total": 8000.00,
        "line_vat": 2000.00
      }
    ],
    "created_at": "2026-06-15T09:58:00+02:00"
  }
}

balance er utestående beløp; null betyr betalt.

Fakturaer kan foreløpig bare leses. Å opprette en faktura berører nummerserie, MVA og hovedbok, og gjøres ikke fra et tynt API-kall før skrivestien er noe vi kan stå inne for.

Lister er paginert. Hvert svar har links og meta:

"meta": { "current_page": 2, "last_page": 6, "per_page": 25, "total": 143 }

Følg links.next til den er null. per_page kan settes opp til 100 — ber du om mer, får du 100.

For løpende synkronisering, bruk updated_since med tidspunktet for forrige vellykkede kjøring i stedet for å hente alt på nytt:

GET /api/v1/contacts?updated_since=2026-08-30T09:00:00%2B02:00&per_page=100

Et token får levetid når det opprettes: 3, 12 eller 24 måneder, eller uten utløp. Standard er tolv måneder.

Et token uten utløp er et token ingen husker å tilbakekalle når integrasjonen legges ned. Velg det bare når noe faktisk krever det, og noter hvorfor.

Et utløpt token slutter å virke av seg selv og svarer 401, akkurat som et tilbakekalt. Oversikten viser når hvert token utløper, og hvilke som står uten utløp.

Tokenet vises bare én gang. Bare en hash lagres, så det kan ikke hentes fram igjen — heller ikke av oss. Mister du det, tilbakekall det og lag et nytt.

Tilbakekalling virker umiddelbart. Integrasjoner som bruker tokenet slutter å virke ved neste kall, så lag heller ett token per integrasjon enn ett felles.

KodeBetyr
401Tokenet mangler, er ukjent, tilbakekalt eller utløpt
403Tokenet mangler tilgangen kallet krever
404Ressursen finnes ikke i selskapet tokenet tilhører
422Ugyldig innhold
429For mange kall

401 skiller ikke mellom ukjent, tilbakekalt og utløpt. Å si hvilket det er, hjelper en angriper med å kartlegge gyldige tokens.

403 sier hvilken tilgang som mangler:

{ "message": "Tokenet mangler tilgangen «invoices:read».", "required_scope": "invoices:read" }

422 gir feltvise meldinger:

{ "message": "...", "errors": { "name": ["Navn er påkrevd."] } }

120 kall per minutt per token. Kall uten token er begrenset hardere, siden avsenderen ikke er identifisert.

Grensen går per token, ikke per adresse: flere integrasjoner deler ofte én server, og en IP-basert grense ville latt en travel nabo strupe alle andre.

Ved 429 sier Retry-After hvor lenge du bør vente.

Opprett et endepunkt under Innstillinger → Integrasjoner og velg hvilke hendelser du vil høre om. URL-en må være https.

HendelseUtløses når
contact.createdEn kontakt opprettes
contact.updatedEn kontakt endres
invoice.createdEn faktura opprettes
invoice.sentEn faktura sendes
invoice.paidEn faktura registreres betalt
product.createdEt produkt opprettes
voucher.receivedEt bilag mottas

Alle sju utløses. invoice.sent og invoice.paid kommer på overgangen — det øyeblikket feltet går fra tomt til satt — så du får dem én gang, ikke på nytt hver gang noe annet på fakturaen endres.

contact.updated utløses bare når noe en integrasjon bryr seg om er endret: navn, organisasjonsnummer, e-post, telefon, type, adresse, betalingsbetingelser eller aktiv-status. Nyttelasten sier hvilke felter det gjaldt, i changed. Interne oppdateringer som siste kontaktdato varsler ikke.

Hendelsene kommer fra selve datalaget, ikke fra enkelte skjermbilder, så de utløses uansett om posten kom fra grensesnittet, API-et, en import eller AI-assistenten.

Hvert kall er en POST med JSON:

{
  "event": "invoice.sent",
  "created_at": "2026-08-30T09:15:00+02:00",
  "data": {
    "id": 42,
    "invoice_number": "F-2026-0042",
    "contact_id": 12,
    "total": 12500.00,
    "due_date": "2026-07-15",
    "sent_at": "2026-08-30T09:15:00+02:00"
  }
}

Hvert kall bærer disse headerne:

HeaderInnhold
X-Konrad-SignatureHMAC-SHA256 av tidsstempel.body
X-Konrad-TimestampUnix-tid da kallet ble laget
X-Konrad-EventHendelsen, for ruting
X-Konrad-DeliveryLeverings-ID, for å kjenne igjen gjenforsøk
$forventet = hash_hmac('sha256', $timestamp . '.' . $body, $hemmelighet);

if (! hash_equals($forventet, $signatur)) {
    abort(400);
}

if (abs(time() - (int) $timestamp) > 300) {
    abort(400);
}

Tidsstempelet er en del av det signerte, så et fanget kall kan ikke spilles av senere. Avvis alt eldre enn noen minutter, og sammenlign i konstant tid — en signaturkontroll som lekker timing er ingen kontroll.

Svarer du 2xx, regnes leveringen som fullført. Alt annet prøves på nytt med økende mellomrom: 10 sekunder, 1 minutt, 5 minutter, 15 minutter, 1 time.

Et endepunkt som feiler 15 ganger på rad slås av, og du ser det i oversikten. En URL som har vært død i to uker skal slutte å lage arbeid.

Leveringen skjer på kø, så et tregt endepunkt gjør ikke faktureringen treg.

Svar raskt. Ta imot kallet, legg det i din egen kø, og svar 200. Gjør du tungt arbeid før du svarer, får du gjenforsøk du ikke trenger.

Bruk X-Konrad-Delivery til å kjenne igjen gjenforsøk, så samme hendelse ikke behandles to ganger.

  • Lag ett token per integrasjon, ikke ett felles — da kan du tilbakekalle én uten å stoppe resten
  • Gi bare tilgangene som trengs. En nettbutikk som sender ordrer skal ikke kunne lese lønn
  • Bruk updated_since i stedet for å hente alt på nytt
  • Tokens kan ikke hentes fram igjen. Mister du et, tilbakekall det og lag et nytt
  • Et token som ikke har vært brukt vises med «Aldri brukt» — nyttig for å finne integrasjoner som aldri kom i gang
Hva er nytt Kom i gang
Innboks Kom i gang
Første gangs bruk Kom i gang
Dashboard Kom i gang
Mine aktiviteter Kom i gang
Morgenrapport Kom i gang
Konrad Kom i gang
Kontaktregister CRM & Salg
Vareregister CRM & Salg
Salg (Tilbud, Ordrer, Faktura) CRM & Salg
Automatisk purring CRM & Salg
E-signatur på tilbud CRM & Salg
Kundeportal CRM & Salg
Leverandørportal CRM & Salg
Abonnementsfakturering CRM & Salg
Lager Lager & Innkjøp
Prosjekter Prosjekt & Tid
Arbeidsordrer Prosjekt & Tid
Timeregistrering Prosjekt & Tid
Prosjektlønnsomhet (AI) Prosjekt & Tid
Økonomi Økonomi & Regnskap
KPI-kort med trender Økonomi & Regnskap
Sanntids resultat Økonomi & Regnskap
Scenarioplanlegger Økonomi & Regnskap
MVA-autopilot Økonomi & Regnskap
Avviksdeteksjon (AI) Økonomi & Regnskap
Automatisk periodisering Økonomi & Regnskap
Kontoutdrag-forklarer Økonomi & Regnskap
Cashflow Autopilot Økonomi & Regnskap
Likviditetstiltak Økonomi & Regnskap
Prisoptimalisering (AI) Økonomi & Regnskap
Prediktiv budsjettering Økonomi & Regnskap
Selskapsanalyse Økonomi & Regnskap
Smartbilag (AI) Økonomi & Regnskap
Kvitteringsskanner Økonomi & Regnskap
Betalingsforslag Økonomi & Regnskap
Regnskapsrobot Økonomi & Regnskap
Regnskapsrobot Autopilot Økonomi & Regnskap
Godkjenningsflyt Økonomi & Regnskap
Kontoavstemming Økonomi & Regnskap
Bokføringsregler Økonomi & Regnskap
QR-kode på bilag Økonomi & Regnskap
Bransjesammenligning Økonomi & Regnskap
Rapporter & Excel Økonomi & Regnskap
MVA-meldinger Økonomi & Regnskap
Lønn Økonomi & Regnskap
Styreportal Årsoppgjør
Aksjonærregister Årsoppgjør
Skatt Årsoppgjør
Årsregnskap Årsoppgjør
AI-årsoppgjørsassistent Årsoppgjør
Altinn Årsoppgjør
Compliance-kalender Årsoppgjør
Byrå og klienter Regnskapsbyrå
Oppdragsavtale Regnskapsbyrå
Bilagsprising Regnskapsbyrå
Hvitvasking (AML) Regnskapsbyrå
EHF-mottak Regnskapsbyrå
Innstillinger Innstillinger
Bankintegrasjon Innstillinger
API og webhooks Innstillinger
Sikkerhet og 2FA Innstillinger
Avdelinger Innstillinger
Kontoplan Innstillinger
Selskap og brukere Innstillinger
No results found
Fant ingen sider. Prøv et annet ord, eller søk i innholdet.