Nordlet

← Dokumentaatio / Oppaat

Rajapinnan käytännöt

Pyyntöjen rakenne, käyttöoikeusalueet, listahaut, rahamäärät, virheet, idempotenttius ja pyyntörajoitukset.

Pyyntöjen rakenne

Jokainen operaatio on RPC-tyylinen POST-pyyntö:

POST /v1/{module}/{resource}/{action}

Moduulit: reference, partners, catalog, sales, purchases, ledger, bank, declarations, files, webhooks, audit. Toiminnot ovat verbejä: create, get, update, delete, list sekä domain-kohtaisia toimintoja, kuten issue, register, match, apply-advance, generate.

Tunnistautuminen ja käyttöoikeusalueet

Authorization: Bearer <api key>. Avaimilla on käyttöoikeusalueita (scopes), jotka tarkistetaan toimintokohtaisesti:

  • {module}:read - luku- ja listausoperaatiot
  • {module}:write - muutokset
  • {module}:* tai * - yleismerkit

Puuttuva käyttöoikeusalue johtaa koodiin 403 forbidden. Puuttuva tai virheellinen avain johtaa koodiin 401 unauthorized.

Listahaut

Kaikilla list-toiminnoilla on yhteinen sopimus:

{
  "page": 1,
  "pageSize": 50,
  "sort": [{ "field": "createdAt", "dir": "desc" }],
  "filter": [{ "field": "paymentStatus", "op": "eq", "value": "unpaid" }]
}

Suodatinoperaattorit: eq (yhtä suuri), ne (eri suuri), contains (kirjainkooltaan merkitsemätön tekstihaku, vain tekstikentät), gte (suurempi tai yhtä suuri kuin), lte (pienempi tai yhtä suuri kuin), in (mikä tahansa enintään 500 arvon listasta). Lajiteltavat ja suodatettavat kentät on määritetty sallituiksi päätepisteittäin (katso OpenAPI-määrittely); tuntemattomista kentistä palautetaan virhe 400. Lisää pyyntöön totals: ["field", …] laskeaksesi yhteen numeeriset kentät kaikilta vastaavilta riveiltä; kun tietueisiin liittyy valuutta, totalsByCurrency palauttaa samat summat valuuttakohtaisesti eriteltyinä. Vastaukset: { rows, total, page, pageSize, totals?, totalsByCurrency? }.

Rahamäärät ja päivämäärät

Rahamäärät ovat desimaalimerkkijonoja, joissa on enintään 4 desimaalia ("121.0000"), eivät koskaan liukulukuja. Arvonlisävero lasketaan rivikohtaisesti käyttäen puolikaupallista pyöristystä (half-up rounding). Päivämäärät ovat muodossa YYYY-MM-DD ja aikaleimat ISO 8601 UTC -muodossa.

Virheet

Yhtenäinen virherakenne kaikkialla:

{
  "error": {
    "code": "validation",
    "message": "Request validation failed",
    "requestId": "k1x…",
    "key": "request_invalid",
    "fieldErrors": { "lines.0.unitPriceExclVat": ["Invalid value"] }
  }
}

Koodit: validation (400/422 sekä 413, jos ladattu tiedosto tai pyynnön runko on liian suuri), unauthorized (401), payment_required (402, kokeilujakso tai ennakkomaksettu saldo on päättynyt; viestissä kerrotaan, miten jatkaa), forbidden (403), not_found (404), conflict (409), idempotency_key_reuse (422), idempotency_in_progress (409), rate_limited (429), internal (5xx). Kun viesti on kiinteä vakioviesti, key nimeää sen, jotta asiakassovellus voi näyttää oman käännöksensä, ja params sisältää viestiin sijoitettavat arvot (esimerkiksi { "period": "2026-09" } lukitulle tilikaudelle). Sisällytä requestId aina, kun ilmoitat ongelmista.

Idempotenttius

Lisää otsikko Idempotency-Key: <mikä tahansa merkkijono, enintään 255 merkkiä> mihin tahansa muutoksia tekevään kutsuun:

  • Uudelleenyritys samalla avaimella ja sisällöllä palauttaa tallennetun vastauksen tavu tavulta otsikolla x-idempotent-replay: true.
  • Sama avain, eri sisältö -> 422 idempotency_key_reuse.
  • Samanaikainen kaksoiskappale, kun ensimmäinen on vielä kesken -> 409 idempotency_in_progress.
  • Avaimet kuuluvat sen lähettäneelle API-avaimelle tai käyttäjälle sen yrityksen puitteissa, jonka puolesta kutsu tehdään, joten saman yrityksen kaksi integraatiota voivat käyttää samaa avainta. Ennen yrityksen olemassaoloa tehdyt kutsut sekä account/*-kutsut pitävät avaimet käyttäjäkohtaisina, joten toistettu account/companies/create luo yhden yrityksen.
  • Tallennettu vastaus palautetaan vain sen jälkeen, kun kutsuja läpäisee samat käyttöoikeustarkistukset uudelleen (käyttöoikeusalue, rooli, yritys ja laskutustila); muussa tapauksessa kutsu saa nykyisen virheen.
  • Avaimet vanhenevat 24 tunnin kuluttua. Virhevastaukset (4xx) toistetaan myös; 5xx-vastauksia ei tallenneta, joten uudet yritykset suoritetaan uudelleen.

Pyyntörajoitukset (Rate limits)

300 pyyntöä minuutissa per API-avain (per esitetty tunnistetieto; todentamattomia pyyntöjä rajoitetaan IP-osoitteen mukaan). Virheen 429 sattuessa noudata retry-after-otsikkoa. Otsikot x-ratelimit-* kertovat nykyisen kiintiösi tilan.

Verkkokoukut (Webhooks)

Tapahtumat kirjoitetaan transaktiotauluun (outbox) saman tietokantatransaktion yhteydessä kuin itse muutoskaan; perutusta dokumentista ei koskaan lähetetä tapahtumaa, eikä yhtään tapahtumaa kadoteta. Toimitukset:

  • POST-pyyntö URL-osoitteeseesi tapahtuman JSON-datalla
  • x-nordlet-timestamp: <unix-sekunnit>, aika, jolloin toimitus allekirjoitettiin
  • x-nordlet-signature-v2: t=<timestamp>,v1=<heksadesimaalimuotoinen HMAC-SHA256 merkkijonosta "<timestamp>.<raaka runko>"> käyttäen tilaussalaisuuttasi
  • x-nordlet-signature: sha256=<heksadesimaalimuotoinen HMAC-SHA256 raa'asta rungosta>, säilytetään ennallaan olemassa olevia vastaanottajia varten
  • x-nordlet-delivery sisältää toimitustunnisteen, joka pysyy samana saman toimituksen kaikissa uudelleenyrityksissä
  • Muu kuin 2xx-vastaus tai uudelleenohjaus yritetään uudelleen 30 sekunnin, 2 minuutin, 10 minuutin, 30 minuutin, 1 tunnin, 3 tunnin, 6 tunnin ja 12 tunnin kuluttua (yhteensä noin 24 tunnin ajan), ennen kuin toimitus merkitään epäonnistuneeksi
  • Kukin toimitus lähetetään kerrallaan yhden palvelimen toimesta, joten usean API-esiintymän ajaminen ei lähetä sitä kahdesti

Varmenna x-nordlet-signature-v2 ajallisesti vakaalla vertailulla (constant-time comparison) ennen sisällön luottamista ja hylkää toimitus, jonka aikaleima poikkeaa kellostasi yli 5 minuuttia. Aikaleima on osa allekirjoitettua tekstiä, joten kaapattua toimitusta ei voi toistaa myöhemmin uudella aikaleimalla. Tallenna käsittelemäsi x-nordlet-delivery-tunnisteet, jotta voit ohittaa saman toimituksen uudelleentoistot kyseisen ikkunan sisällä. Epäonnistunut toimitus voidaan lähettää uudelleen päätepisteellä webhooks/deliveries/redeliver.

Auditointi

Jokainen muutos kirjataan (actor, action, entity, diff) ja on haettavissa audit/list-päätepisteen kautta.

Kirjanpidon takuut

  • Päiväkirjamerkinnät ovat aina tasapainossa. Tätä valvotaan tietokannan viivästetyllä liipaisimella (deferred trigger) commit-hetkellä, ei pelkästään sovelluskoodissa.
  • Tositenumerot ovat aukottomia sarja- ja vuosikohtaisesti; numeroiden varaus on turvattu kilpailutilanteilta (concurrency-safe).
  • Lukitut tilikaudet hylkäävät kaikki niille ajoitetut kirjaukset (409).
  • Pehmeästi poistetut dokumentit säilyttävät auditointiketjunsa; kirjattuja tai rekisteröityjä dokumentteja ei voi poistaa.