Nordlet

← Dokumentacija / Vodiči

Konvencije API-ja

Oblika zahtev, obsegi overitve, poizvedbe za sezname, denarne vrednosti, napake, idempotenca, omejitve števila zahtev.

Oblika zahtev

Vsaka operacija je klic POST v slogu RPC:

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

Moduli: reference, partners, catalog, sales, purchases, ledger, bank, declarations, files, webhooks, audit. Dejanja so glagoli: create, get, update, delete, list ter domenska dejanja, kot so issue, register, match, apply-advance, generate.

Overitve in obsegi

Authorization: Bearer <api key>. Ključi vključujejo obsege, ki se preverjajo za vsako dejanje posebej:

  • {module}:read - dejanja za pridobivanje in seznam
  • {module}:write - spremembe
  • {module}:* ali * - nadomestni znaki (wildcards)

Manjkajoč obseg -> 403 forbidden. Manjkajoč ali neveljaven ključ -> 401 unauthorized.

Poizvedbe za sezname

Vsa dejanja list delijo enotno strukturo:

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

Operatorji filtrov: eq (enako), ne (ni enako), contains (besedilno ujemanje neobčutljivo na velike in male črke, samo za besedilna polja), gte (večje ali enako), lte (manjše ali enako), in (katera koli vrednost s seznama do 500 vrednosti). Polja, po katerih je mogoče razvrščati in filtrirati, so vnaprej določena za vsako končno točko (glejte specifikacijo OpenAPI); neznana polja vrnejo napako 400. Če želite sešteti številska polja vseh ustreznih vrstic, zahtevi dodajte totals: ["field", ...]; ko zapisi vključujejo valuto, totalsByCurrency vrne iste vsote, razdeljene po kodah valut. Odgovori: { rows, total, page, pageSize, totals?, totalsByCurrency? }.

Denarne vrednosti in datumi

Denarne vrednosti so decimalni nizi z do 4 decimalkami ("121.0000") - nikoli plavajoče vejice (floats). DDV se izračuna za vsako postavko posebej z zaokroževanjem navzgor na polovico (half-up rounding). Datumi so v formatu YYYY-MM-DD; časovne oznake so v formatu ISO 8601 UTC.

Napake

Enotna ovojnica povsod:

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

Kode: validation (400/422 in 413, ko je naložena datoteka ali telo zahteve preveliko), unauthorized (401), payment_required (402, preizkusno obdobje ali predplačniško dobroimetje se je izteklo; sporočilo pojasnjuje, kako nadaljevati), forbidden (403), not_found (404), conflict (409), idempotency_key_reuse (422), idempotency_in_progress (409), rate_limited (429), internal (5xx). Kadar je sporočilo eno od določenih sporočil, ga ključ key poimenuje, da lahko odjemalec prikaže svoj prevod, polje params pa vsebuje vrednosti zanj (na primer { "period": "2026-09" }}" za zaklenjeno obračunsko obdobje). Pri poročanju o težavah vključite requestId`.

Idempotenca

Vsakemu klicu, ki spreminja podatke, dodajte glavo Idempotency-Key: <poljuben niz ≤255 znakov>:

  • Ponovitev z istim ključem in podatki zahteve -> shranjen odgovor se predvaja bajt za bajtom z glavo x-idempotent-replay: true.
  • Isti ključ, drugačni podatki zahteve -> 422 idempotency_key_reuse.
  • Sočasna podlaga, medtem ko se prvi klic še izvaja -> 409 idempotency_in_progress.
  • Ključi pripadajo ključu API ali uporabniku, ki jih pošlje, znotraj podjetja, za katero se klic izvaja, tako da lahko dve integraciji istega podjetja uporabljata isti ključ. Klici, izvedeni preden podjetje obstaja, in klici account/* ohranjajo ključe na uporabnika, zato ponovljeni klic account/companies/create ustvari samo eno podjetje.
  • Shranjen odgovor se vrne šele, ko klicatelj ponovno prestane preverjanja dovoljenj (obseg, vloga, podjetje in stanje obračuna); v nasprotnem primeru klic prejme trenutno napako.
  • Ključi potečejo po 24 urah. Odgovori z napakami (4xx) se prav tako ponovno predvajajo; odgovori 5xx se ne shranijo, zato se ponovitve ponovno izvedejo.

Omejitve števila zahtev (rate limits)

300 zahtev na minuto na ključ API (glede na predloženo overitev; neoverjene zahteve so omejene glede na IP). Ob napaki 429 upoštevajte glavo retry-after. Glave x-ratelimit-* prikazujejo porabo vaše kvote.

Spletni kljuke (webhooks)

Dogodki se zapisujejo v transakcijsko odtočno mizo (outbox) znotraj iste bazične transakcije kot sprememba - preklican dokument nikoli ne sproži dogodka in noben dogodek se ne izgubi. Dostava:

  • POST na vaš URL s podatki dogodka v formatu JSON
  • x-nordlet-timestamp: <unix seconds>, čas, ko je bila dostava podpisana
  • x-nordlet-signature-v2: t=<timestamp>,v1=<hex HMAC-SHA256 of "<timestamp>.<raw body>">, z uporabo vaše skrivnosti naročnine
  • x-nordlet-signature: sha256=<hex HMAC-SHA256 of the raw body>, nespremenjeno za obstoječe prejemnike
  • x-nordlet-delivery vsebuje ID dostave, ki je enak pri vsakem ponovnem poskusu iste dostave
  • Odgovor, ki ni v območju 2xx, ali preusmeritev se ponovi po 30 sekundah, 2 minutah, 10 minutah, 30 minutah, 1 uri, 3 urah, 6 urah in 12 urah, skupno po približno 24 urah, preden se dostava označi kot neuspešna
  • Vsako dostavo pošilja posamezen strežnik naenkrat, zato delovanje več primerkov API-ja ne povzroči dvojnega pošiljanja

Preden zaupate vsebini, preverite x-nordlet-signature-v2 s primerjavo, ki je odporna proti časovnim napadom (constant-time comparison), in zavrnite dostavo, katere časovna oznaka se od vaše ure razlikuje za več kot 5 minut. Časovna oznaka je del podpisanega besedila, zato zajete dostave ni mogoče kasneje ponoviti z novo časovno oznako. Shranite ID-je x-nordlet-delivery, ki ste jih že obdelali, da prezrete ponovitve znotraj tega časovnega okna. Neuspešno dostavo je mogoče ponovno poslati prek webhooks/deliveries/redeliver.

Revizija (audit)

Vsaka sprememba se zabeleži (actor, action, entity, diff) in jo je mogoče poizvedovati preko audit/list.

Računovodska zagotovila

  • Knjižbe v dnevniku so uravnotežene - to uveljavlja zakasnjen sprožilec baze podatkov ob potrditvi (commit), ne le programska koda.
  • Številke dokumentov nimajo vrzeli znotraj serije/leta; dodeljevanje je varno pred sočasnostjo (concurrency-safe).
  • Zaklenjena obračunska obdobja zavračajo vse knjižbe z datumi znotraj njih (409).
  • Logično izbrisani dokumenti ohranjajo svojo revizijsko sled; izdanih/registriranih dokumentov ni mogoče izbrisati.