Nordlet

← Dokumentācija / Ceļveži

API konvencijas

Pieprasījuma struktūra, autorizācijas tvērumi, sarakstu vaicājumi, naudas summas, kļūdas, idempotence, pieprasījumu limiti.

Pieprasījuma struktūra

Katra operācija ir RPC stila POST pieprasījums:

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

Moduļi: reference, partners, catalog, sales, purchases, ledger, bank, declarations, files, webhooks, audit. Darbības ir darbības vārdi: create, get, update, delete, list, kā arī domēna darbības, piemēram, issue, register, match, apply-advance, generate.

Autentifikācija un tvērumi

Authorization: Bearer <api key>. Atslēgām ir tvērumi, kas tiek pārbaudīti katrai darbībai:

  • {module}:read - iegūšanas/saraksta darbības (get/list)
  • {module}:write - datu izmaiņas
  • {module}:* vai * - aizstājējzīmes (wildcards)

Trūkstošs tvērums rada kļūdu 403 forbidden. Trūkstanta vai nederīga atslēga rada kļūdu 401 unauthorized.

Sarakstu vaicājumi

Visām list darbībām ir kopīgs līgums:

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

Filtra operatori: eq (vienāds), ne (nav vienāds), contains (teksta sakritība, neņemot vērā reģistru, tikai teksta laukiem), gte (lielāks vai vienāds), lte (mazāks vai vienāds), in (jebkura vērtība no saraksta, kurā ir līdz 500 vērtībām). Lauki, pēc kuriem var kārtot un filtrēt, ir norādīti baltajā sarakstā katram galapunktam (skatīt OpenAPI specifikāciju); par nezināmiem laukiem tiek atgriezts 400. Pievienojiet pieprasījumam totals: ["field", …], lai summētu skaitliskos laukus visās atbilstošajās rindās; ja ierakstiem ir norādīta valūta, totalsByCurrency sniedz tās pašas summas, sadalītas pa valūtu kodiem. Atbildes: { rows, total, page, pageSize, totals?, totalsByCurrency? }.

Naudas summas un datumi

Naudas summas ir decimālskaitļu virknes ar līdz 4 zīmēm aiz komata ("121.0000") - nekad plūstošā komata skaitļi (floats). PVN tiek aprēķināts katrai rindai atsevišķi, izmantojot noapaļošanu uz augšu līdz tuvākajai centu daļai (half-up rounding). Datumi ir formātā YYYY-MM-DD; laika zīmes atbilst ISO 8601 UTC standartam.

Kļūdas

Visur tiek izmantots viens kļūdu ietvars:

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

Kodi: validation (400/422, un 413, ja augšupielādētais fails vai pieprasījuma pamatteksts ir pārāk liels), unauthorized (401), payment_required (402, izmēģinājuma periods vai priekšapmaksas kredīts ir beidzies; ziņojumā norādīts, kā turpināt), forbidden (403), not_found (404), conflict (409), idempotency_key_reuse (422), idempotency_in_progress (409), rate_limited (429), internal (5xx). Ja ziņojums ir viens no fiksētajiem ziņojumiem, lauks key norāda tā nosaukumu, lai klients varētu attēlot savu tulkojumu, savukārt params satur tajā ietveramās vērtības (piemēram, { "period": "2026-09" } slēgtam grāmatvedības periodam). Ziņojot par problēmām, iekļaujiet requestId.

Idempotence

Jebkuram datu izmaiņu pieprasījumam pievienojiet galveni Idempotency-Key: <jebkura virkne ≤255 rakstzīmes>:

  • Atkārtojot pieprasījumu ar to pašu atslēgu un datiem, saglabātā atbilde tiek atgriezta baits pret baitu ar galveni x-idempotent-replay: true.
  • Tā pati atslēga, bet citi dati - tiek atgriezts 422 idempotency_key_reuse.
  • Vienlaicīgs dublēts pieprasījums, kamēr pirmais vēl tiek apstrādāts - tiek atgriezts 409 idempotency_in_progress.
  • Atslēgas pieder API atslēgai vai lietotājam, kas tās nosūta, uzņēmuma ietvaros, kurā pieprasījums tiek veikts, tāpēc vienas kompānijas divas integrācijas var izmantot vienu un to pašu atslēgu. Pieprasījumi, kas veikti pirms uzņēmuma izveides, un account/* pieprasījumi saglabā atslēgas katram lietotājam, tāpēc atkārtots account/companies/create izveido tikai vienu uzņēmumu.
  • Saglabātā atbilde tiek atgriezta tikai tad, kad zvanītājs atkārtoti iziet tās pašas piekļuves pārbaudes (tvērums, loma, uzņēmums un norēķinu statuss); pretējā gadījumā pieprasījums saņem pašreizējo kļūdu.
  • Atslēgas derīguma termiņš beidzas pēc 24 stundām. Kļūdu atbildes (4xx) arī tiek atskaņotas atkārtoti; 5xx atbildes netiek saglabātas, tāpēc atkārtoti pieprasījumi tiek izpildīti no jauna.

Pieprasījumu limiti (Rate limits)

300 pieprasījumi minūtē vienai API atslēgai (katram iesniegtajam pilnvarojumam; neautentificētiem pieprasījumiem limiti tiek piemēroti pēc IP adreses). Saņemot 429 kļūdu, ievērojiet galveni retry-after. Galvenes x-ratelimit-* informē par jūsu atlikumu.

Tīmekļa āķi (Webhooks)

Notikumi tiek ierakstīti darījumu izvedrindē (transactional outbox) tajā pašā datu bāzes darījumā, kurā notiek izmaiņas, tāpēc atcelts dokuments nekad neizģenerē notikumu un neviens notikums nepazūd. Piegāde:

  • POST pieprasījums uz jūsu URL ar notikuma JSON datiem
  • x-nordlet-timestamp: <unix seconds> – laiks, kad tika parakstīta piegāde
  • x-nordlet-signature-v2: t=<timestamp>,v1=<raw body "<timestamp>.<raw body>" heksadecimāls HMAC-SHA256>, izmantojot jūsu abonēšanas seltētu (secret)
  • x-nordlet-signature: sha256=<raw body heksadecimāls HMAC-SHA256>, saglabāts nemainīgs esošajiem saņēmējiem
  • x-nordlet-delivery satur piegādes ID, kas nemainās nevienā vienas piegādes atkārtotā mēģinājumā
  • Ja atbilde nav 2xx vai tiek saņemts pāradresācijas pieprasījums, tas tiek atkārtots pēc 30 sekundēm, 2 minūtēm, 10 minūtēm, 30 minūtēm, 1 stundas, 3 stundām, 6 stundām un 12 stundām (kopumā aptuveni 24 stundas), pirms piegāde tiek atzīmēta kā neizdevusies
  • Katru piegādi vienlaikus sūta tikai viens serveris, tāpēc vairāku API instancšu darbināšana nenosūtīs to divreiz

Pirms uzticaties datu pamattekstam, pārbaudiet x-nordlet-signature-v2, izmantojot salīdzinājumu ar konstantu laiku (constant-time comparison), un noraidiet piegādi, kuras laika zīme atšķiras no jūsu pulksteņa vairāk nekā par 5 minūtēm. Laika zīme ir daļa no parakstītā teksta, tāpēc pārtvertu piegādi nevar vēlāk atkārtoti nosūtīt ar jaunu laika zīmi. Saglabājiet apstrādāto x-nordlet-delivery ID, lai ignorētu atkārtojumus šajā logā. Neizdevušos piegādi var nosūtīt atkārtoti, izmantojot webhooks/deliveries/redeliver.

Audits

Katra datu izmaiņa tiek reģistrēta (actor, action, entity, diff), un tai var veikt vaicājumus, izmantojot audit/list.

Grāmatvedības garantijas

  • Žurnāla ieraksti ir sabalansēti - to nodrošina atliktais datu bāzes trigeris (database trigger) datu bāzes darījuma apstiprināšanas brīdī (commit time), nevis tikai lietotnes kods.
  • Dokumentu numuri sērijas vai gada ietvaros ir nepārtraukti (gapless); numuru piešķiršana ir droša pret vienlaicīgu piekļuvi (concurrency-safe).
  • Slēgti grāmatvedības periodi noraida jebkuru ierakstu, kura datums iekrīt šajā periodā (409).
  • Mīksti dzēstie dokumenti (soft-deleted) saglabā savu audita izsekojamību; izsniegtos vai reģistrētos dokumentus nevar dzēst.