Nordlet

← दस्तावेज़ / मार्गदर्शिकाएँ

एपीआई परंपराएँ (API conventions)

अनुरोध संरचना, प्रमाणीकरण दायरे (auth scopes), सूची क्वेरी, राशि, त्रुटियाँ, समरूपता (idempotency), और दर सीमाएँ (rate limits)।

अनुरोध संरचना (Request shape)

प्रत्येक ऑपरेशन RPC-शैली का एक POST अनुरोध होता है:

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

मॉड्यूल: reference, partners, catalog, sales, purchases, ledger, bank, declarations, files, webhooks, audit। क्रियाएँ (actions) वर्ब होती हैं: create, get, update, delete, list, साथ ही डोमेन क्रियाएँ जैसे issue, register, match, apply-advance, generate।

प्रमाणीकरण और दायरे (Authentication and scopes)

Authorization: Bearer <api key>। कुंजियों में ऐसे दायरे (scopes) होते हैं जिनकी प्रत्येक क्रिया के लिए जाँच की जाती है:

  • {module}:read - प्राप्त करने/सूचीबद्ध करने (get/list) की क्रियाएँ
  • {module}:write - परिवर्तन (mutations) से जुड़ी क्रियाएँ
  • {module}:* या * - वाइल्डकार्ड (wildcards)

दायरा न होने पर → 403 forbidden (वर्जित)। कुंजी गायब या अमान्य होने पर → 401 unauthorized (अनधिकृत)।

सूची क्वेरी (List queries)

सभी list क्रियाएँ एक ही अनुबंध (contract) का पालन करती हैं:

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

फ़िल्टर ऑपरेटर: eq (बराबर), ne (बराबर नहीं), contains (केस-असंवेदनशील टेक्स्ट मिलान, केवल टेक्स्ट फ़ील्ड के लिए), gte (से अधिक या बराबर), lte (से कम या बराबर), in (अधिकतम 500 मानों की सूची में से कोई भी)। क्रमबद्ध (sortable) और फ़िल्टर किए जाने योग्य फ़ील्ड प्रत्येक एंडपॉइंट के लिए श्वेत-सूचीबद्ध (whitelisted) होते हैं (OpenAPI स्पेक देखें); अज्ञात फ़ील्ड 400 त्रुटि लौटाते हैं। प्रत्येक मिलान वाली पंक्ति (row) पर संख्यात्मक फ़ील्ड का योग करने के लिए अनुरोध में totals: ["field", …] जोड़ें; जब रिकॉर्ड में कोई मुद्रा (currency) शामिल होती है, तो totalsByCurrency मुद्रा कोड के अनुसार विभाजित करके वही योग प्रदान करता है। प्रतिक्रियाएँ: { rows, total, page, pageSize, totals?, totalsByCurrency? }।

राशि और तिथियाँ (Money and dates)

मौद्रिक मूल्य (monetary values) अधिकतम 4 दशमलव स्थानों वाले दशमलव स्ट्रिंग होते हैं ("121.0000") - इन्हें कभी भी फ़्लोट (floats) के रूप में नहीं दर्शाया जाता। वैट (VAT) की गणना हाफ़-अप (half-up) राउंडिंग के साथ प्रति पंक्ति की जाती है। तिथियाँ YYYY-MM-DD प्रारूप में होती हैं; टाइमस्टैम्प ISO 8601 UTC प्रारूप में होते हैं।

त्रुटियाँ (Errors)

हर जगह एक ही एनवेलप (envelope) का उपयोग होता है:

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

कोड: validation (400/422, और अपलोड की गई फ़ाइल या अनुरोध बॉडी के बहुत बड़ा होने पर 413), unauthorized (401), payment_required (402, निःशुल्क परीक्षण या प्रीपेड क्रेडिट समाप्त हो गया है; संदेश में बताया गया है कि आगे कैसे बढ़ें), forbidden (403), not_found (404), conflict (409), idempotency_key_reuse (422), idempotency_in_progress (409), rate_limited (429), internal (5xx)। जब संदेश निश्चित संदेशों में से एक होता है, तो key उसका नाम बताता है ताकि क्लाइंट अपना खुद का अनुवाद दिखा सके, और params इसमें जाने वाले मानों को रखता है (उदाहरण के लिए लॉक की गई लेखांकन अवधि के लिए { "period": "2026-09" })। समस्याओं की रिपोर्ट करते समय requestId को अवश्य शामिल करें।

समरूपता (Idempotency)

किसी भी परिवर्तनकारी (mutating) कॉल में Idempotency-Key: <any string ≤255 chars> जोड़ें:

  • समान कुंजी और पेलोड के साथ पुनः प्रयास (retry) → संग्रहीत प्रतिक्रिया को x-idempotent-replay: true के साथ बाइट-दर-बाइट पुनः चलाया (replay) जाता है।
  • समान कुंजी, भिन्न पेलोड → 422 idempotency_key_reuse।
  • समवर्ती डुप्लीकेट (concurrent duplicate) जबकि पहला अनुरोध प्रक्रिया में है → 409 idempotency_in_progress।
  • कुंजियाँ उस एपीआई कुंजी या उपयोगकर्ता से संबंधित होती हैं जो उन्हें भेजती हैं, उस कंपनी के भीतर जिसके लिए कॉल की जाती है, इसलिए एक कंपनी के दो इंटीग्रेशन एक ही कुंजी का उपयोग कर सकते हैं। कंपनी के अस्तित्व में आने से पहले किए गए कॉल, और account/* कॉल, प्रत्येक उपयोगकर्ता के लिए कुंजियाँ रखते हैं, इसलिए बार-बार किया जाने वाला account/companies/create कॉल केवल एक कंपनी बनाता है।
  • संग्रहीत प्रतिक्रिया केवल तभी लौटाई जाती है जब कॉलर दोबारा वही अनुमति जाँच (दायरा, भूमिका, कंपनी और बिलिंग स्थिति) पास कर लेता है; अन्यथा कॉल को वर्तमान त्रुटि प्राप्त होती है।
  • कुंजियाँ 24 घंटे के बाद समाप्त हो जाती हैं। त्रुटि प्रतिक्रियाएँ (4xx) भी पुनः चलाई जाती हैं; 5xx प्रतिक्रियाओं को संग्रहीत नहीं किया जाता है ताकि पुनः प्रयास (retries) फिर से निष्पादित हो सकें।

दर सीमाएँ (Rate limits)

प्रति एपीआई कुंजी 300 अनुरोध प्रति मिनट (प्रस्तुत क्रेडेंशियल के अनुसार; प्रमाणीकरण रहित अनुरोधों की सीमा प्रति आईपी होती है)। 429 मिलने पर, retry-after हेडर का सम्मान करें। x-ratelimit-* हेडर आपकी सीमा (budget) की रिपोर्ट करते हैं।

वेबहुक (Webhooks)

इवेंट्स को परिवर्तन के साथ ही डेटाबेस लेनदेन में एक ट्रांजैक्शनल आउटबॉक्स में लिखा जाता है - रोल-बैक किए गए दस्तावेज़ से कभी कोई इवेंट उत्सर्जित नहीं होता, और कोई भी इवेंट खोता नहीं है। डिलीवरी:

  • इवेंट JSON के साथ आपके URL पर POST अनुरोध
  • x-nordlet-timestamp: <unix seconds>, वह समय जब डिलीवरी पर हस्ताक्षर किए गए थे
  • x-nordlet-signature-v2: t=<timestamp>,v1=<hex HMAC-SHA256 of "<timestamp>.<raw body>">, जो आपके सब्सक्रिप्शन सीक्रेट का उपयोग करता है
  • x-nordlet-signature: sha256=<hex HMAC-SHA256 of the raw body>, मौजूदा प्राप्तकर्ताओं (receivers) के लिए इसे अपरिवर्तित रखा गया है
  • x-nordlet-delivery में डिलीवरी आईडी होती है, जो एक ही डिलीवरी के हर पुनः प्रयास पर समान रहती है
  • गैर-2xx प्रतिक्रिया या रीडायरेक्ट होने पर 30 सेकंड, 2 मिनट, 10 मिनट, 30 मिनट, 1 घंटे, 3 hours, 6 घंटे और 12 घंटे के बाद (कुल मिलाकर लगभग 24 घंटे तक) पुनः प्रयास किया जाता है, इससे पहले कि डिलीवरी को विफल चिह्नित किया जाए
  • प्रत्येक डिलीवरी एक समय में एक ही सर्वर द्वारा भेजी जाती है, इसलिए कई एपीआई इंस्टेंस चलाने से यह दो बार नहीं भेजी जाएगी

पेलोड पर भरोसा करने से पहले निरंतर-समय (constant-time) तुलना के साथ x-nordlet-signature-v2 को सत्यापित करें, और ऐसी डिलीवरी को अस्वीकार करें जिसका टाइमस्टैम्प आपकी घड़ी से 5 मिनट से अधिक दूर है। टाइमस्टैम्प हस्ताक्षरित पाठ (signed text) का हिस्सा है, इसलिए पकड़ी गई डिलीवरी को बाद में नए टाइमस्टैम्प के साथ दोबारा नहीं चलाया जा सकता है। उस समय-सीमा के भीतर पुनरावृत्ति की अनदेखी करने के लिए आपके द्वारा संसाधित की गई x-nordlet-delivery आईडी को सहेज कर रखें। विफल डिलीवरी को webhooks/deliveries/redeliver के साथ फिर से भेजा जा सकता है।

ऑडिट (Audit)

प्रत्येक परिवर्तन को रिकॉर्ड किया जाता है (actor, action, entity, diff) और audit/list के माध्यम से क्वेरी किया जा सकता है।

लेखांकन की गारंटी (Accounting guarantees)

  • जर्नल पोस्टिंग संतुलित होती हैं - इसे केवल एप्लिकेशन कोड द्वारा नहीं, बल्कि कमिट (commit) के समय एक विलंबित डेटाबेस ट्रिगर द्वारा लागू किया जाता है।
  • दस्तावेज़ संख्याएँ श्रृंखला/वर्ष के अनुसार अंतराल-रहित (gapless) होती हैं; आवंटन समवर्ती-सुरक्षित (concurrency-safe) होता है।
  • लॉक की गई लेखांकन अवधि के भीतर दिनांकित किसी भी पोस्टिंग को अस्वीकार कर दिया जाता है (409)।
  • सॉफ्ट-डिलीट किए गए दस्तावेज़ अपना ऑडिट ट्रेल बनाए रखते हैं; जारी किए गए/पंजीकृत दस्तावेज़ों को हटाया नहीं जा सकता।