Nordlet

← Dokumentacija / Vadovai

API konvencijos

Užklausų struktūra, autorizacijos sferos, sąrašų užklausos, pinigai, klaidos, idempotentiškumas, užklausų dažnio limitai.

Užklausų struktūra

Kiekviena operacija yra RPC tipo POST užklausa:

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

Moduliai: reference, partners, catalog, sales, purchases, ledger, bank, declarations, files, webhooks, audit. Veiksmai yra veiksmažodžiai: create, get, update, delete, list, bei domeno veiksmai, tokie kaip issue, register, match, apply-advance, generate.

Autentifikavimas ir sferos (scopes)

Authorization: Bearer <api key>. Raktams priskirtos sferos tikrinamos kiekvienam veiksmui:

  • {module}:read - gauti/sąrašo veiksmai
  • {module}:write - pakeitimai
  • {module}:* arba * - pakaitos simboliai (wildcards)

Trūkstama sfera užtraukia 403 forbidden klaidą. Trūkstamas arba netinkamas raktas užtraukia 401 unauthorized klaidą.

Sąrašų užklausos

Visi list veiksmai turi vieną bendrą sutartį:

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

Filtravimo operatoriai: eq (lygu), ne (nelygu), contains (teksto paieška neskiriant didžiųjų ir mažųjų raidžių, tik teksto laukams), gte (daugiau arba lygu), lte (mažiau arba lygu), in (bet kuri reikšmė iš iki 500 reikšmių sąrašo). Rikiuojami ir filtruojami laukai yra įtraukti į leistinųjų sąrašą kiekvienam galiniam punktui (endpoint) (žr. OpenAPI specifikaciją); nežinomi laukai gražina 400 klaidą. Į užklausą įtraukite totals: ["field", …], kad susumuotumėte skaitmeninius laukus visose atitinkančiose eilutėse; kai įrašuose nurodyta valiuta, totalsByCurrency pateikia tas pačias sumas, padalintas pagal valiutos kodą. Atsakymai: { rows, total, page, pageSize, totals?, totalsByCurrency? }.

Pinigai ir datos

Piniginės vertės yra dešimtainiai tekstiniai laukai su iki 4 skaitmenų po kablelio ("121.0000") - niekada nenaudokite slankiojo kablelio (floats). PVM apskaičiuojamas kiekvienai eilutėms atskirai, taikant apvalinimą į viršuesnę pusę (half-up rounding). Datos pateikiamos formatu YYYY-MM-DD; laiko žymos (timestamps) yra ISO 8601 UTC formatu.

Klaidos

Visur naudojamas vienodas paketas:

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

Kodai: validation (400/422, taip pat 413, kai įkeltas failas arba užklausos turinys yra per didelis), unauthorized (401), payment_required (402, bandomasis laikotarpis arba išankstinis apmokėjimas pasibaigė; pranešime nurodoma, kaip tęsti), forbidden (403), not_found (404), conflict (409), idempotency_key_reuse (422), idempotency_in_progress (409), rate_limited (429), internal (5xx). Kai pranešimas yra vienas iš fiksuotų pranešimų, laukas key jį įvardija, kad kliento programa galėtų pateikti savo vertimą, o params išsaugo reikšmes, kurios į jį įstatomos (pavyzdžiui, { "period": "2026-09" } užrakintam apskaitos laikotarpiui). Pranešdami apie problemas, nurodykite requestId.

Idempotentiškumas

Prie bet kurio pakeitimo užklausos pridėkite antraštę Idempotency-Key: <bet koks tekstas ≤255 simbolių>:

  • Pakartojus užklausą su tuo pačiu raktu ir duomenimis - išsaugotas atsakymas atkuriamas baitas į baitą su antrašte x-idempotent-replay: true.
  • Tas pats raktas, bet kiti duomenys - grąžinama 422 idempotency_key_reuse klaidą.
  • Lygiagretus dublikatas, kol pirmoji užklausą dar vykdoma - grąžinama 409 idempotency_in_progress klaidą.
  • Raktai priklauso API raktui arba juos siunčiančiam naudotojui įmonės, kurios vardu atliekama užklausa, ribose, todėl dvi vienos įmonės integracijos gali naudoti tą patį raktą. Užklausos, atliktos dar neegzistuojant įmonei, ir account/* užklausos išsaugo raktus kiekvienam naudotojui, todėl pakartota account/companies/create užklausa sukuria tik vieną įmonę.
  • Išsaugotas atsakymas grąžinamas tik po to, kai siuntėjas iš naujo sėkmingai praeina teisių patikrinimus (sferos, vaidmens, įmonės ir atsiskaitymo statuso); kitu atveju užklausai grąžinama dabartinė klaida.
  • Raktai nustoja galioti po 24 valandų. Klaidinami atsakymai (4xx) taip pat atkuriami; 5xx atsakymai nesaugomi, todėl pakartotinės užklausos vykdomos iš naujo.

Užklausų dažnio limitai (Rate limits)

300 užklausų per minutę vienam API raktui (pateiktiems kredencialams; neautentifikuotoms užklausoms taikomi limitai pagal IP adresą). Gavę 429 klaidą, laikykitės retry-after antraštės nurodymų. x-ratelimit-* antraštės informuoja apie jūsų limitų likutį.

Žiniatinklio kabliukai (Webhooks)

Įvykiai įrašomi į operacinę išsiuntimo eilę (outbox) toje pačioje duomenų bazės operancijoje kaip ir pakeitimas - atšauktas dokumentas niekada nesukuria įvykio, o joks įvykis nepasimeta. Pristatymas:

  • POST užklausa jūsų URL adresu su įvykio JSON duomenimis
  • x-nordlet-timestamp: <unix seconds> - laikas, kada pristatymas buvo pasirašytas
  • x-nordlet-signature-v2: t=<timestamp>,v1=<šešioliktainis HMAC-SHA256 iš "<timestamp>.<raw body>">, naudojant jūsų prenumeratos paslaptį (secret)
  • x-nordlet-signature: sha256=<šešioliktainis neapdoroto turinio HMAC-SHA256>, paliekamas nepakeistas esamiems imtuvams
  • x-nordlet-delivery nurodo pristatymo ID, kuris yra vienodas kiekvieno to paties pristatymo bandymo metu
  • Ne 2xx atsakymas arba peradresavimas bandomas pakartoti po 30 sekundžių, 2 minučių, 10 minučių, 30 minučių, 1 valandos, 3 valandų, 6 valandų ir 12 valandų (iš viso maždaug per 24 valandas), kol pristatymas pažymimas kaip nepavykęs
  • Kiekvienas pristatymas siunčiamas tik per vieną serverį vienu metu, todėl kelių API egzempliorių paleidimas neišsiųs jo dukart

Prieš pasitikėdami duomenimis, patikrinkite x-nordlet-signature-v2 naudodami trukmės atžvilgiu pastovų palyginimą (constant-time comparison) ir atmeskite pristatymą, kurio laiko žyma nuo jūsų laikrodžio skiriasi daugiau nei 5 minutėmis. Laiko žyma yra pasirašyto teksto dalis, todėl perimto pristatymo negalima vėliau pakartoti su nauja laiko žyma. Išsaugokite apdorotus x-nordlet-delivery ID, kad ignoruotumėte pasikartojimus tuo pačiu laikotarpiu. Nepavykusį pristatymą galima išsiųsti iš naujo per webhooks/deliveries/redeliver.

Auditas

Kiekvienas pakeitimas yra įregistruojamas (actor, action, entity, diff) ir jo užklausas galima pateikti per audit/list.

Apskaitos garantijos

  • Žurnalo įrašai yra suderinti - tai užtikrinama atidėtu duomenų bazės trigeriu įrašymo (commit) metu, o ne vien programinės įrangos kodu.
  • Dokumentų numeriai serijoje/metais neturi jokių spragų; numerių priskirtimas yra saugus lygiagriečio vykdymo atveju.
  • Užrakinti apskaitos laikotarpiai atmeta bet kokius įrašus, kurių data patenka į jų laikotarpį (409).
  • Mėlynai ištrinti (soft-deleted) dokumentai išlaiko savo audito seką; išduotų arba užregistruotų dokumentų ištrinti negalima.

D.U.K.

(Šiame skyriuje kol kas nėra klausimų)