Sindh IT Portal — Facilitation DeskSpecification documents
Englishاردوسنڌي
← All documents

API معاهدو

سنڌ آءِ ٽي پورٽل — سهولت ڊيسڪ (SITP) جي مستند REST API معاهدي جي دستاويز: بيس URL، ورزننگ، تصديق ۽ اجازت، ريٽ لمٽنگ، صفحہ بندي، لفافو، خاميون، idempotency، OpenAPI 3.1 خاڪو، مڪمل وسائل جي فهرست، ٻاهر نڪرندڙ ويب هوڪ جو معاهدو، SDK/codegen منصوبو، deprecation، سينڊ باكس، ۽ مشاهدگي۔

فيلڊ قدر
دستاويز آءِ ڊي 12
حيثيت مسودو
مالڪ S&ITD / MAAHIR
زبانون EN (مرجع) · UR · SD
API انداز REST (NestJS)، JSON، OpenAPI 3.1
بيس URL https://sindhitportal.maahir.io/api/v1
متعلقه دستاويزون /specs/sd/08-integrations-spec/ · /specs/sd/05-data-model/ · /specs/sd/04-roles-permissions/ · /specs/sd/11-security-compliance/ · 03-non-functional-requirements/en.md · /specs/sd/15-tech-architecture/

1. دائرو ۽ هن دستاويز کي پڙهڻ جو طريقو

هي دستاويز SITP جي عوامي REST API جو انجنيئرنگ معاهدو آهي. انهي کي هيٺيان استعمال ڪن ٿا:

هي دستاويز API جي شڪل لاءِ مستند ماخذ آهي. اها /specs/sd/08-integrations-spec/ جي §8 (عوامي API) کي هڪ مڪمل معاهدي ۾ وڌائي ٿي. انضمام جي تفصيلي دستاويز انفرادي انضمام ايڊاپٽرز (NADRA، SECP، Mailjet وغيره) لاءِ مستند ماخذ رهي ٿي؛ هي دستاويز رڳو ان سطح جو احاطو ڪري ٿي جيڪا SITP پاڻ ظاهر ڪري ٿي. جتي ٻئي ڪنهن عوامي-API تفصيل تي متفق نه هجن، هي دستاويز غالب آهي.

هر وسيلي پٺيان ڊيٽا ماڊل /specs/sd/05-data-model/ ۾ مقرر ٿيل آهي؛ API فيلڊ جا نالا اتي دستاويز ٿيل snake_case ڪالمن جا camelCase عڪس آهن.


2. بيس URL، ورزننگ ۽ ميڊيا قسمون

2.1 بيس URL

ماحول بيس URL
پروڊڪشن https://sindhitportal.maahir.io/api/v1
سينڊ باكس https://sandbox.sindhitportal.maahir.io/api/v1 (ڏسو §15)
OpenAPI دستاويز GET /api/v1/openapi.json
انٽرايڪٽو دستاويزون (Swagger UI) https://sindhitportal.maahir.io/docs/api

هن دستاويز جا سڀ رستا مڪمل طرح لکڻ کان سواءِ بيس URL جي نسبت سان آهن.

2.2 ورزننگ جي حڪمت عملي

SITP URL سيگمنٽ ميجر ورزننگ (/api/v1، /api/v2) استعمال ڪري ٿو. قاعدا:

اهو ته ڀڃندڙ ڪهڙو آهي §14.2 ۾ دستاويز ٿيل آهي ۽ /api/v1/openapi.json تي پيش ڪيل چينج لاگ ۾ ظاهر آهي (OpenAPI جو info.version هڪ ميجر اندر SemVer تي قائم آهي).

2.3 ميڊيا قسمون

پهلو قاعدو
درخواست باڊي Content-Type: application/json (UTF-8). Multipart صرف براهِ راست فائل اپ لوڊ لاءِ استعمال ٿئي ٿو جڏهن ڪو پارٽنر presigned-URL فلو استعمال ناهي ڪري سگهندو (ڏسو §10 Attachments)، SITP جي ملڪيت واري endپوائنٽ تي.
جواب باڊي سڀني وسائل لاءِ application/json. خاميون application/problem+json آهن (§7).
لوڪيل Accept-Language: en | ur | sd انسان جي پڙهڻ جي قابل فيلڊز (title، displayName، message) جي زبان ڪنٽرول ڪري ٿو. نامعلوم قدرون en تي موٽن ٿيون.
ڪيلينڊر Prefer: calendar=hijri تاريخ رکندڙ فيلڊز ۾ ٻٽي گريگورين+هجري تاريخون موٽائي ٿو (_context.md §2 مطابق).
ڪمپريشن gzip ۽ br Accept-Encoding ذريعي معاون آهن.

2.4 عام هيڊرز (هر درخواست)

هيڊر ضروري مقصد
Authorization هائي (عوامي + ٽوڪن ايڪسچينج endپوائنٽس کان سواءِ) Bearer <access_token> — OAuth2 يا OIDC (§3).
Accept-Language ناهي (ڊفالٽ en) انسان جي پڙهڻ جي قابل فيلڊز جي لوڪيل.
X-Request-Id ناهي ڪلائنٽ جي فراهم ڪيل correlation آءِ ڊي؛ جواب ۾ موٽاي ويندي آهي (§16). جي غير موجود هجي ته SITP هڪ تيار ڪري ٿو.
Idempotency-Key تحريرن تي لازم (§8) UUID v4/v7؛ 24 ڪلاڪن اندر duplicate هٽائي ٿو.
User-Agent تجويز ڪيل تشخيص لاءِ پارٽنر سڃاڻپ ڪندڙ.

3. تصديق ۽ اجازت

SITP ٻن تصديقي انداز ظاهر ڪري ٿو، ٻئي پنهنجي ميزبان Keycloak مثال تي ختم ٿين ٿا (/specs/sd/08-integrations-spec/ §7 مطابق):

  1. OAuth 2.0 client-credentialsپارٽنر ائپس لاءِ (مشين کان مشين تائين). ڪو آخري صارف عمل ۾ ناهي.
  2. OIDC bearer (Authorization Code + PKCE)انٽرايڪٽو صارفين لاءِ (ڪمپني نمائندا، حڪومتي عملو) جيڪي SITP UI يا ڪنهن فيڊرل حڪومتي IdP ذريعي لاگ اِن ٿين ٿا.

ٻئي مختصر مدت جا bearer رسائي ٽوکنز (JWTs) پيدا ڪن ٿا جيڪي Authorization: Bearer <token> هيڊر ۾ موڪليا وڃن ٿا. ٽوڪنز ڪڏهن به query پيٽاميٽرز جي طور تي موڪليا ناهن وڃدا.

3.1 OAuth 2.0 client-credentials (پارٽنر ائپس)

پارٽنر ائپس SITP پارٽنر ڪنسول ۾ رجسٽرڊ ٿين ٿيون ۽ هڪ client_id ۽ client_secret وصول ڪن ٿيون. هر پارٽنر هڪ يا وڌيڪ companyId قدرن سان ٻڌل آهي جنهن لاءِ هو مجاز آهي (ڪمپني پارٽنر کي پورٽل ۾ OAuth انداز جي رضامندگيءَ سان اجازت ڏئي ٿي). فلو:

ٽوڪن درخواست

POST /api/v1/partners/tokens
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "partner_acmeintegrator",
  "client_secret": "••••••••••••••••",
  "scope": "tickets:write tickets:read kb:read"
}

ٽوڪن جواب

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "tickets:write tickets:read kb:read",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}

ٽوڪن منسوخي

POST /api/v1/partners/tokens/revoke
Authorization: Bearer <partner admin token>
Content-Type: application/json

{ "token": "eyJhbGciOi...", "token_type_hint": "access_token" }

اها 204 No Content موٽائي ٿي. هڪ denylist کي Redis ۾ عكس بند ڪيو ويندو آهي ته جيئن منسوخي چند سيڪنڊن اندر اثر انداز ٿئي.

3.2 OIDC bearer (انٽرايڪٽو صارفين)

ڪمپني نمائندا ۽ حڪومتي عملو SITP UI ذريعي تصديق ڪن ٿا، جيڪو Keycloak جي خلاف PKCE سان گڏ OIDC Authorization Code فلو سرانجام ڏئي ٿو. نتيجي جو رسائي ٽوڪن هڪ bearer طور API کي بالڪل پارٽنر ٽوڪن وانگر موڪليو ويندو آهي. Claims ۾ sub، email، realm (gov-staff | companyroles[]، deptCode، ۽ 2fa_verified شامل آهن (/specs/sd/08-integrations-spec/ §7 مطابق). حڪومتي عملي جا ٽوڪنز اضافي طور هڪ SITP ڪردار (Staff، POC، DG، Secretary، SuperAdmin) رکن ٿا جيڪو RolesGuard/PermissionsGuard استعمال ڪندو آهي.

SITP جي پنهنجي فرنٽ اينڊ لاءِ، هي شفاف آهي — SPA ٽوکن کي محفوظ سيسن ۾ رکي ٿو. ٽين پارٽي UI لاءِ جيڪي ساڳئي Keycloak realm سان فيڊرل ٿين ٿيون، ساڳيو طريقو عمل ۾ اچي ٿو.

3.3 اسڪوپس

اسڪوپس پارٽنر ائپس لاءِ اجازت جي اڪائي آهن. انٽرايڪٽو صارفين کي ڪردار + صلاحيت ذريعي اجازت ڏني ويندي آهي (/specs/sd/04-roles-permissions/ مطابق)، اسڪوپ ذريعي ناهي؛ تنهن هوندي به انهن جي ٽوڪن کي endپوائنٽ جي گهربل صلاحيت پوري ڪرڻ گهرجي.

اسڪوپ اجازتون
tickets:read مجاز ڪمپنين جا ٽِڪيٽ، پيغام، ۽ منسلڪات پڙهڻ.
tickets:write ٽِڪيٽ بنائڻ، پيغام شامل ڪرڻ، قبول/بند ڪرڻ، منسلڪات اپ لوڊ ڪرڻ.
orgs:read مجاز ڪمپنين جا تنظيمي + نمائندو رڪارڊ پڙهڻ.
orgs:write تنظيم رجسٽر ڪرڻ، نمائندن کي مدعو/اپڊيٽ ڪرڻ.
reps:write نمائندن جو انتظام (orgs:write جو ذيلي سيٽ).
kb:read شائع ٿيل KB مضمون ۽ SOPs پڙهڻ.
stats:read غير عوامي تجزياتي حصا پڙهڻ (عوامي stats endپوائنٽ کي ڪابه اسڪوپ گهربل ناهي).
files:read presigned URL ذريعي منسلڪه مواد ڊائون لوڊ ڪرڻ.
files:write اپ لوڊ شروع ڪرڻ / فائلون منسلڪ ڪرڻ.
webhooks:manage ويب هوڪ سبسڪرپشنز بنائڻ، فهرست، حذف، ٻيهر هلائڻ.
* سپر-اسڪوپ؛ رڳو فرسٽ پارٽي SITP ڪلائنٽس لاءِ محفوظ آهي.

هڪ endپوائنٽ جو گهربل اسڪوپ وسائل جي فهرست (§10) ۽ OpenAPI جي security بلاڪ (§9) ۾ درج آهي. اسڪوپ جي کوٽ → SITP-AUTH-004 (§7.3).

3.4 عوامي (no-auth) endپوائنٽس

هڪ ننڍڙو سيٽ صرف پڙهڻ جا endپوائنٽس عوامي آهن — ڪابه ٽوڪن گهربل ناهي — ته جيئن شهري ۽ محقق رجسٽريشن کان سواءِ انهن کي استعمال ڪري سگهن:

عوامي endپوائنٽس پوءِ به ريٽ لمٽنگ (§4) جا تابع آهن هڪ سخت تر ڊفالٽ درجي تي.


4. ريٽ لمٽنگ

ريٽ لمٽس پليٽ فارم کي غلط استعمال ڪندڙ يا ڀڄي ويندڙ ڪلائنٽس کان محفوظ رکن ٿا. لمٽس في پارٽنر (client_id/ٽوڪن سان سڃاڻپ ٿيل) تصديق ٿيل ڪالز لاءِ ۽ في ماخذ IP عوامي ڪالز لاءِ آهن. لمٽس int_ratelimit جدول ۾ تشڪيل جوڳا آهن (/specs/sd/05-data-model/ §3.10 مطابق) ۽ پارٽنر درجي ۽ آپريشن ڪلاس جي لحاظ کان مختلف آهن.

4.1 درجو بندي ماڊل

درجو پڙهڻ جو بجيٽ لکڻ جو بجيٽ (ٽِڪيٽ بنائڻ) ڪير
public 120 درخواست/منٽ في IP n/a (ڪابه تحرير ناهي) عوامي endپوائنٽس جا گمنام ڪالرز.
standard 600 درخواست/منٽ 60 درخواست/منٽ رجسٽرڊ پارٽنرز لاءِ ڊفالٽ.
premium 3 000 درخواست/منٽ 300 درخواست/منٽ معاهدو ٿيل اعليٰ حجم وارا پارٽنرز (تجارتي درجو — TBD، ڏسو §18).
first-party 10 000 درخواست/منٽ 1 000 درخواست/منٽ SITP جو پنهنجو فرنٽ اينڊ، موبائل، ۽ اندروني سروسز.

لکڻ جون لمٽس هر آپريشن ڪلاس لاءِ الگ آهن (ٽِڪيٽ بنائڻ، پيغام شامل ڪرڻ، اپ لوڊ) ته جيئن پڙهڻ جو اچار لکڻ جي گنجائش ختم ناهي ڪري سگهندو. اچارڻ وارن ڪلائنٽس کي throttle ڪيو ويندو آهي (HTTP 429)، اڳ ۾ اطلاع کان سواءِ خاموشيءَ سان ڪڏهن به banned ناهي ڪيو ويندو.

4.2 ريٽ لمٽ هيڊرز

هر جواب — ڪامياب جواب سميت — هي هيڊرز رکي ٿو ته جيئن ڪلائنٽس پاڻ کي منظم ڪري سگهن:

هيڊر معنيٰ
X-RateLimit-Limit موجوده ونڊو لاءِ بجيٽ (مثال طور، 600).
X-RateLimit-Remaining موجوده ونڊو ۾ باقي درخواستون.
X-RateLimit-Reset Unix ٽائم اسٽيمپ جنهن تي ونڊو ري سيٽ ٿيندي آهي.
X-RateLimit-Tier اهو درجو جيڪو لاگو ٿيو (public/standard/premium/first-party).

جڏهن تجاوز ڪري وڃي:

HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 28
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1752752522

{
  "type": "https://sindhitportal.maahir.io/docs/errors/rate-limited",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "You have exceeded 600 requests per minute. Retry after the Retry-After window.",
  "instance": "/api/v1/tickets",
  "code": "SITP-RATELIMIT-001",
  "retryAfterSeconds": 28
}

Retry-After هميشه 429 تي موجود هوندو آهي ۽ سيڪنڊن ۾ ڏنو ويندو آهي.


5. صفحہ بندي، فلٽرنگ، ترتيب ڏيڻ ۽ Sparse Fieldsets

5.1 صفحہ بندي (cursor + page)

SITP فهرست endپوائنٽس لاءِ ٻن صفحہ بندي انداز معاون آهن. Cursor اعليٰ حجم، ترتيب ڏنل فهرستن لاءِ ترجيحی آهي؛ page سهولت ۽ ايڊمن UIs لاءِ معاون آهي.

انداز پيٽاميٽرز ڪڏهن استعمال ڪجي
Cursor (ڊفالٽ) ?cursor=<opaque>&limit=50 /tickets، /tickets/{id}/messages، /kb/articles لاءِ ڊفالٽ. داخلن/حذف تي مستحکم؛ وڌ ۾ وڌ limit=100، ڊفالٽ 50.
Page ?page=1&pageSize=50 /departments، /service-catalog، /stats/public تي اجازت. آسان UIs لاءِ آسان؛ page 1-اشاري ٿيل آهي؛ وڌ ۾ وڌ pageSize=100.

Cursor ٽوڪنز ڪلائنٽ لاءِ opaque آهن (هڪ base64url-encoded signed اسٽرنگ)؛ ڪلائنٽس کي انهن کي black box سمجهڻ گهرجن ۽ رڳو واپس موڪلڻ گهرجن. جواب هميشه links بلاڪ (§6) ذريعي ڪلائنٽ کي جاري رکڻ جو طريقو ٻڌائي ٿو.

5.2 فلٽرنگ

فلٽرز في endپوائنٽ whitelist-ٿيل تصديق ٿيل query پيٽاميٽرز آهن. نامعلوم فلٽرز SITP-VALIDATION-005 سان مسترد ڪيا ويندا آهن. عام فلٽرز:

فلٽر مثال نوٽس
حيثيت ?status=assigned,in_progress ڪامي سان الگ multi-value؛ اندر OR.
محڪمو ?dept=SRB محڪمي ڪوڊ.
قسم ?category=SRB-REFUND قسم ڪوڊ.
تاريخ جي حد ?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z ISO-8601، UTC.
تلاش ?q=refund سرور Meilisearch ڏانهن تفويض ڪري ٿو؛ گهڻ لساني (/specs/sd/05-data-model/ §2.7 مطابق).
KB تي full-text ?q=tax&locale=ur KB تلاش لوڪيل جي احترام ڪري ٿي.

5.3 ترتيب ڏيڻ

?sort=<field> چڙهندڙ؛ ?sort=-<field> لهندڙ (شروعاتي -). multi-sort: ?sort=-createdAt,priority. ترتيب ڏيڻ جوڳا فيلڊز في endپوائنٽ OpenAPI ۾ درج آهن؛ غير ترتيب ڏيڻ جوڳي فيلڊ مان ترتيب ڏيڻ تي SITP-VALIDATION-006 موٽي ٿو.

5.4 Sparse fieldsets

ڪلائنٽس رڳو اهي فيلڊز گهر ڪري سگهن ٿا جيڪي کين گهربل آهن ته جيئن payload سائز گهٽ رهي، جيڪو موبائل ۽ ميٽرڊ نيٽ ورڪن لاءِ ڪارآمد آهي:

GET /api/v1/tickets/SITP-2026-SRB-000128?fields=ticketId,status,sla
Authorization: Bearer <token>

رڳو data اندر گهرايل اعليٰ سطحي فيلڊز موٽائي ٿو. نامعلوم يا غير مجاز فيلڊز خاموشيءَ سان ڇڏي ويندا آهن (خامي ناهي) ته جيئن ڪلائنٽس forward-compatible رهن. Nested sparse selection dot-paths استعمال ڪري ٿو: ?fields=ticketId,sla.responseBy.


6. جواب جو لفافو

هر ڪامياب جواب ساڳيو لفافو استعمال ڪري ٿو: { data, meta, links }. واحد وسيلي جوابون وسيلي کي data ۾ رکن ٿيون ۽ خالي هجڻ تي meta/links کي ڇڏي ڏين ٿيون؛ فهرست جوابون ٽيئي ڀرين ٿيون.

فيلڊ هميشه موجود؟ معنيٰ
data هائي وسيلو (آبجيڪٽ) يا وسيل (array). رڳو 204 جوابن لاءِ null.
meta ناهي Out-of-band ميٽا ڊيٽا: requestId، صفحہ بندي شمار، ريٽ لمٽ ecو، سرور گهڙي، استعمال ٿيل لوڪيل.
links ناهي صفحہ بندي/نيويگيشن لنڪس: self، next، prev، first، last.

لفافو مثال (cursor صفحہ بندي سان فهرست)

HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
X-SITP-API-Version: v1

{
  "data": [
    { "ticketId": "SITP-2026-SRB-000127", "status": "assigned" },
    { "ticketId": "SITP-2026-SRB-000128", "status": "new" }
  ],
  "meta": {
    "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB",
    "locale": "en",
    "serverTime": "2026-07-17T09:18:42.117Z",
    "page": { "limit": 50, "returned": 2, "hasMore": true }
  },
  "links": {
    "self":  "/api/v1/tickets?cursor=eyJpZCI6MTI3fQ&limit=50",
    "next":  "/api/v1/tickets?cursor=eyJpZCI6MTIyOH0&limit=50",
    "prev":  null,
    "first": "/api/v1/tickets?limit=50"
  }
}

لفافو مثال (واحد وسيلو)

{
  "data": {
    "ticketId": "SITP-2026-SRB-000128",
    "status": "new"
  },
  "meta": { "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB" }
}

خاميون انهي لفافي جو استعمال ناهن ڪنديون — هو RFC 7807 (§7) استعمال ڪن ٿيون.


7. خاميون (RFC 7807 Problem Details)

سڀ خاميون RFC 7807 (application/problem+json) استعمال ڪن ٿيون. هر خامي معياري فيلڊز کان علاوه هڪ SITP مخصوص code (مستحکم، مشين جي پڙهڻ جوڳو) رکي ٿي. ڪلائنٽس کي code تي branch ڪرڻ گهرجي، ڪڏهن detail تي ناهي (جيڪو انسان جي پڙهڻ جوڳو ۽ localized آهي).

7.1 معياري فيلڊز

فيلڊ قسم معنيٰ
type URI خامي جي قسم بندي لاءِ هڪ دستاويزي صفحو (dereferenceable).
title اسٽرنگ مختصر، مستحکم، انگريزي خلاصو.
status int HTTP اسٽيٽس (echoed).
detail اسٽرنگ انسان جي پڙهڻ جوڳي وضاحت، Accept-Language ذريعي localized.
instance URI اها درخواست رستو جيڪا ناڪام ٿي.
code اسٽرنگ SITP خامي ڪوڊ، مثال طور، SITP-VALIDATION-042.
errors[] array (رڳو validation) في فيلڊ تفصيل field ۽ code سان.
requestId اسٽرنگ correlation آءِ ڊي (§16)، هميشه موجود.

7.2 Validation خامي جو مثال

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAC

{
  "type": "https://sindhitportal.maahir.io/docs/errors/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "companyId does not match the partner's authorized scope.",
  "instance": "/api/v1/tickets",
  "code": "SITP-VALIDATION-042",
  "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAC",
  "errors": [
    { "field": "companyId", "code": "SCOPE_MISMATCH" },
    { "field": "attachments[0].size", "code": "MAX_SIZE_EXCEEDED" }
  ]
}

7.3 خامي ڪوڊ جي فهرست

اسٽيٽس ڪوڊز HTTP تي قائم آهن. SITP خامي ڪوڊز خاندان جي لحاظ کان گروهه بند آهن. هي فهرست https://sindhitportal.maahir.io/docs/errors تي live پيش ڪئي ويندي آهي ۽ OpenAPI دستاويز ۾ versioned آهي.

code HTTP خاندان معنيٰ
SITP-AUTH-001 401 Auth Authorization هيڊر غير موجود.
SITP-AUTH-002 401 Auth ٽوڪن ختم يا malformed.
SITP-AUTH-003 400 Auth گهربل اسڪوپ ڪلائنٽ کي ڏنل ناهي.
SITP-AUTH-004 403 Auth ٽوڪن درست مگر هن endپوائنٽ لاءِ گهربل اسڪوپ غائب.
SITP-AUTH-005 403 Auth هن عمل لاءِ 2FA لازم (حساس/VIP).
SITP-AUTH-006 403 Auth ڪمپني نمائندو certified ناهي (Module O گیٽ).
SITP-RATELIMIT-001 429 Rate limit ريٽ لمٽ تجاوز (ڏسو §4).
SITP-VALIDATION-001 400 Validation Malformed JSON باڊي.
SITP-VALIDATION-002 400 Validation لازم فيلڊ غير موجود.
SITP-VALIDATION-003 400 Validation غلط فيلڊ قدر (format/range).
SITP-VALIDATION-004 422 Validation ڪاروباري اصول جي خلاف ورزي (مثال طور، proof گیٽ پورو ناهي).
SITP-VALIDATION-005 400 Validation نامعلوم فلٽر پيٽاميٽر.
SITP-VALIDATION-006 400 Validation غير ترتيب ڏيڻ جوڳو فيلڊ.
SITP-VALIDATION-042 422 Validation companyId تي اسڪوپ عدمِ مطابقت.
SITP-NOTFOUND-001 404 Not found وسيلو موجود ناهي.
SITP-NOTFOUND-002 404 Not found وسيلو موجود مگر ڪالر جي visibility ناهي (001 جهڙو شڪل ته جيئن موجودگي leak ناهي ٿيندي).
SITP-CONFLICT-001 409 Conflict موجوده حيثيت مان اسٽيٽ ٽرانزيشن جي اجازت ناهي.
SITP-CONFLICT-002 409 Conflict idempotency ڪنجي duplicate مگر مختلف payload.
SITP-CONFLICT-003 409 Conflict ٽِڪيٽ اڳ ۾ ئي ضم/بند ٿي چڪو.
SITP-UPLOAD-001 413 Upload منسلڪه في فائل سائز لمٽ کان تجاوز.
SITP-UPLOAD-002 415 Upload غير معاون MIME قسم.
SITP-UPLOAD-003 422 Upload AV اسڪين فائل کي متاثر قرار ڏنو.
SITP-DEPENDENCY-001 502 Dependency Upstream انضمام (NADRA/SECP/…) دستياب ناهي؛ پوءِ ٻيهر ڪوشش ڪريو.
SITP-DEPENDENCY-002 503 Dependency هڪ گهربل ايڊاپٽر لاءِ سرڪٽ بريڪر کُليو.
SITP-INTERNAL-001 500 Internal Unhandled سرور خامي؛ correlation آءِ ڊي requestId ۾.

4xx خاميون (429 کان سواءِ) ڪلائنٽس پاران ڪڏهن به ٻيهر ڪوشش ناهن ٿينديون. 5xx ۽ 429 کي exponential backoff سان ٻيهر ڪوشش ڪري سگهجي ٿو (ڏسو §8 ۽ /specs/sd/08-integrations-spec/ §11.2).


8. Idempotency

هر تحرير (POST، PUT، PATCH، DELETE جيڪا state بدلائي) Idempotency-Key هيڊر قبول ڪندي آهي. هيڊر ڪلائنٽ جو پيدا ڪيل UUID v4 يا v7 آهي. 24 ڪلاڪن جي idempotency ونڊو اندر (/specs/sd/08-integrations-spec/ §11 ۾ NFR-INT-004 مطابق):

تحرير تي Idempotency-Key جي کوٽ SITP-VALIDATION-001 موٽائي ٿي جنهن ۾ هيڊر ڏانهن اشارو هوندو آهي. هي هيڊر audit_logs.request_id correlation ۾ به ظاهر ٿيندو آهي (/specs/sd/05-data-model/ §3.10 مطابق) ته جيئن هڪ تحرير ۽ ان جي نتيجي ۾ ٿيندڙ انضمام ڪالز هڪ thread ۾ شريڪ ٿين.

POST /api/v1/tickets
Authorization: Bearer <token>
Idempotency-Key: 9a2c4e6b-1f3d-4a2c-9e8b-7d6c5b4a3f2e
Content-Type: application/json

{ "companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ", "title": "..." }

24 ڪلاڪن اندر مماثل درخواست ٻيهر هلائڻ اصل 201 Created ساڳئي ticketId سان موٽائي ٿو، نه ته duplicate ٽِڪيٽ.


9. OpenAPI 3.1 خاڪو

مڪمل OpenAPI 3.1 دستاويز NestJS ڪنٽرولرز مان @nestjs/swagger ذريعي پيدا ٿيندي آهي ۽ /api/v1/openapi.json تي پيش ڪئي ويندي آهي، پوءِ /docs/api تي render ٿيندي آهي. هيٺ ڏنل خاڪو اعليٰ سطحي دستاويزي شڪل ۽ ٽي نمائندگي ڪندڙ آپريشنز (POST /partners/tokens، POST /tickets، GET /tickets/{ticketId}) ڏيکاري ٿو. اهو مثالي آهي، مڪمل ناهي.

openapi: 3.1.0
info:
  title: Sindh IT Portal — Facilitation Desk Public API
  version: 1.4.0
  description: >
    REST API for partner apps and interactive clients of the Sindh IT Portal.
    Base URL: https://sindhitportal.maahir.io/api/v1
  contact:
    name: SITP API Support
    email: api-support@sindhitportal.maahir.io
  license:
    name: Proprietary — Government of Sindh
servers:
  - url: https://sindhitportal.maahir.io/api/v1
    description: Production
  - url: https://sandbox.sindhitportal.maahir.io/api/v1
    description: Sandbox
tags:
  - name: Auth
  - name: Tickets
  - name: TicketMessages
  - name: Attachments
  - name: Organizations
  - name: Representatives
  - name: Departments
  - name: ServiceCatalog
  - name: KnowledgeBase
  - name: PublicStats
  - name: Webhooks
security:
  - bearerAuth: []
  - oauth2: [tickets:read]
paths:
  /partners/tokens:
    post:
      tags: [Auth]
      summary: Exchange client credentials for a bearer token (OAuth2 client-credentials)
      operationId: createPartnerToken
      security: []            # public endpoint
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TokenRequest' }
      responses:
        '200':
          description: Token issued
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TokenResponse' }
        '400': { $ref: '#/components/responses/Problem' }
        '401': { $ref: '#/components/responses/Problem' }
  /tickets:
    post:
      tags: [Tickets]
      summary: Create a ticket on behalf of a company
      operationId: createTicket
      security:
        - bearerAuth: []
        - oauth2: [tickets:write]
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/AcceptLanguage'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TicketCreateRequest' }
      responses:
        '201':
          description: Ticket created
          headers:
            Location: { schema: { type: string } }
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TicketEnvelope' }
        '400': { $ref: '#/components/responses/Problem' }
        '401': { $ref: '#/components/responses/Problem' }
        '403': { $ref: '#/components/responses/Problem' }
        '422': { $ref: '#/components/responses/Problem' }
        '429': { $ref: '#/components/responses/Problem' }
    get:
      tags: [Tickets]
      summary: List tickets for the authorized company (cursor pagination)
      operationId: listTickets
      security:
        - bearerAuth: []
        - oauth2: [tickets:read]
      parameters:
        - in: query
          name: cursor
          schema: { type: string }
        - in: query
          name: limit
          schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
        - in: query
          name: status
          schema: { type: array, items: { type: string } }
        - in: query
          name: dept
          schema: { type: string }
        - in: query
          name: since
          schema: { type: string, format: date-time }
      responses:
        '200':
          description: A page of tickets
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TicketListEnvelope' }
        '401': { $ref: '#/components/responses/Problem' }
        '429': { $ref: '#/components/responses/Problem' }
  /tickets/{ticketId}:
    get:
      tags: [Tickets]
      summary: Get a single ticket by tracking id
      operationId: getTicket
      security:
        - bearerAuth: []
        - oauth2: [tickets:read]
      parameters:
        - in: path
          name: ticketId
          required: true
          schema: { type: string, example: SITP-2026-SRB-000128 }
        - in: query
          name: fields
          description: Sparse fieldset
          schema: { type: string, example: ticketId,status,sla }
      responses:
        '200':
          description: The ticket
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TicketEnvelope' }
        '404': { $ref: '#/components/responses/Problem' }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: /api/v1/partners/tokens
          scopes:
            tickets:read:  Read tickets, messages, attachments
            tickets:write: Create and mutate tickets
            orgs:read:     Read organization records
            orgs:write:    Register and manage organizations
            reps:write:    Manage representatives
            kb:read:       Read published KB articles
            stats:read:    Read non-public analytics slices
            files:read:    Download attachments
            files:write:   Upload and attach files
            webhooks:manage: Manage webhook subscriptions
  parameters:
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: true
      schema: { type: string, format: uuid }
    AcceptLanguage:
      in: header
      name: Accept-Language
      required: false
      schema: { type: string, enum: [en, ur, sd], default: en }
  responses:
    Problem:
      description: An RFC 7807 problem document
      content:
        application/problem+json:
          schema: { $ref: '#/components/schemas/Problem' }
  schemas:
    Problem:
      type: object
      required: [type, title, status, code]
      properties:
        type:     { type: string, format: uri }
        title:    { type: string }
        status:   { type: integer }
        detail:   { type: string }
        instance: { type: string }
        code:     { type: string, example: SITP-VALIDATION-042 }
        requestId:{ type: string }
        errors:
          type: array
          items:
            type: object
            properties:
              field: { type: string }
              code:  { type: string }

مڪمل دستاويز §10 جي هر آپريشن لاءِ هيئن pattern ورجائي ٿي، بشمول request-body schemas، response envelopes، هر دستاويزي status لاءِ problem-details، ۽ §12 جي واقعن لاءِ webhooks: ايڪسٽينشن (OpenAPI 3.1 native webhooks جي معاونت رکي ٿو).


10. وسائل جي فهرست

هيٺ ڏنل فهرست v1 جو هر endپوائنٽ درج ڪري ٿي. فيلڊ نالا مستحکم آهن؛ مڪمل schemas /api/v1/openapi.json ۾ آهن. هر قطار رکي ٿي: HTTP ميٿڊ، رستو، مقصد، گهربل auth اسڪوپ (يا public)، ۽ آيا تحرير idempotent آهي (Idempotency-Key قبول ڪري ٿي).

ضابطا: GET/HEAD ڪڏهن به idempotent-keyed ناهن. {ticketId} صارف جي سامهون جو ٽريڪنگ آءِ ڊي SITP-YYYY-DEPT-NNNNNN آهي. سڀ {orgId}/{repId} opaque SITP ids آهن.

10.1 Auth

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
POST /partners/tokens client credentials جو bearer ٽوڪن سان ڏي وٺي. — (public) هائي
POST /partners/tokens/revoke ٽوڪن منسوخ ڪرڻ. * (partner admin) هائي

10.2 Tickets

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
POST /tickets ڪنهن ڪمپني جي پاران ٽِڪيٽ بنائڻ. tickets:write هائي
GET /tickets مجاز ڪمپني جي ٽِڪيٽن جي فهرست. tickets:read ناهي
GET /tickets/{ticketId} حيثيت، SLA، تاريخ سان گڏ هڪ ٽِڪيٽ حاصل ڪريو. tickets:read ناهي
PATCH /tickets/{ticketId} قابلِ ترميم ٽِڪيٽ فيلڊز (ترجيح، قسم) اپڊيٽ ڪريو. tickets:write هائي
POST /tickets/{ticketId}/accept ڪمپني حل قبول ڪري ٿي → آٽو ڪلوز ٽرگر. tickets:write هائي

10.3 TicketMessages

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /tickets/{ticketId}/messages عوامي-thread پيغامن جي فهرست. tickets:read ناهي
POST /tickets/{ticketId}/messages هڪ عوامي پيغام شامل ڪرڻ. tickets:write هائي

10.4 Attachments

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
POST /uploads اپ لوڊ شروع ڪرڻ؛ presigned URL + uploadId موٽائي ٿو. files:write هائي
GET /tickets/{ticketId}/attachments ٽِڪيٽ تي منسلڪات جي فهرست. tickets:read ناهي
GET /attachments/{attachmentId} منسلڪه ميٽا ڊيٽا + مختصر مدت جو ڊائون لوڊ URL حاصل ڪريو. files:read ناهي

تجويز ڪيل پارٽنر فلو MinIO تائين presigned-URL اپ لوڊ آهي (پارٽنر bytes براهِ راست آبجيڪٽ اسٽوريج ڏانهن PUT ڪري ٿو؛ SITP bytes ڪڏهن proxy ناهي ڪندو). PUT مڪمل ٿيڻ کان پوءِ، پارٽنر uploadId کي POST /tickets ۾ refer ڪري ٿو (/specs/sd/08-integrations-spec/ جو §11.3 ڏسو). هر اپ لوڊ قابلِ اتصال ٿيڻ کان اڳ ClamAV ذريعي AV-scan ٿيندو آهي (متاثر هجي ته SITP-UPLOAD-003/specs/sd/05-data-model/ §4.4 media_library.av_status مطابق).

10.5 Organizations

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
POST /organizations نئين تنظيم رجسٽر ڪرڻ (file-first → عارضي). orgs:write هائي
GET /organizations/{orgId} تنظيم رڪارڊ + تصديقي حيثيت حاصل ڪريو. orgs:read ناهي
GET /organizations/me ڪالر جي پنهنجي تنظيم حاصل ڪريو (ٽوڪن مان). orgs:read ناهي

10.6 Representatives

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /organizations/{orgId}/representatives نمائندن جي فهرست. orgs:read ناهي
POST /organizations/{orgId}/representatives هڪ نمائندو مدعو ڪرڻ. reps:write هائي
PATCH /representatives/{repId} نمائندو اپڊيٽ ڪرڻ (ڪردار، رابطو، حيثيت). reps:write هائي

10.7 Departments

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /departments محڪمن جي فهرست (وڻ). public ناهي
GET /departments/{deptId} شعبن، ڪلاڪن، موڪلن سان گڏ هڪ محڪمو حاصل ڪريو. public ناهي

10.8 ServiceCatalog

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /service-catalog قسمن ۽ SLAs سان گڏ پيش ڪيل سروسز جي فهرست. public ناهي
GET /service-catalog/{serviceId} لازم فيلڊز ۽ ڊفالٽ SLA سان گڏ هڪ سروس حاصل ڪريو. public ناهي

10.9 KnowledgeBase

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /kb/articles شائع ٿيل KB مضمونن جي فهرست/تلاش (گهڻ لساني). public (subset) / kb:read (full) ناهي
GET /kb/articles/{articleId} گهربل لوڪيل ۾ هڪ KB مضمون حاصل ڪريو. public / kb:read ناهي

10.10 PublicStats

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /stats/public عوامي شفافيت ڊيش بورڊ مجموعات (گمنام ٿيل). public ناهي
GET /stats/public/summary سرخيون KPIs (ڪل، محڪمي جي لحاظ کان، حيثيت جي لحاظ کان). public ناهي

عوامي-stats payloads /specs/sd/17-analytics-kpis/ ۾ تجزياتي ماڊل مان اخذ ٿيل گمنام ٿيل مجموعات آهن. ڪو به انفرادي ٽِڪيٽ يا ڪمپني سڃاڻپ جوڳو ناهي.

10.11 Webhooks

ميٿڊ رستو مقصد اسڪوپ Idempotent؟
GET /webhooks/subscriptions ڪالر جي ويب هوڪ سبسڪرپشنز جي فهرست. webhooks:manage ناهي
POST /webhooks/subscriptions هڪ ويب هوڪ سبسڪرپشن بنائڻ (URL + events + secret). webhooks:manage هائي
DELETE /webhooks/subscriptions/{subId} هڪ سبسڪرپشن حذف ڪرڻ. webhooks:manage هائي
POST /webhooks/subscriptions/{subId}/replay ماضي جي واقعن جي هڪ ونڊو ٻيهر هلائڻ. webhooks:manage هائي

ڪل v1 endپوائنٽس: 30.


11. نموني درخواست/جواب Flows

ٽي end-to-end flows جيڪي لفافو، idempotency، خاميون، ۽ صفحہ بندي کي استعمال ڪن ٿا. فيلڊ نالا /specs/sd/05-data-model/ جو عڪس آهن (API لاءِ camelCased).

11.1 ٽِڪيٽ بنائڻ (پارٽنر، ڪنهن ڪمپني جي پاران)

هڪ پارٽنر اپ مجاز ڪمپني جي پاران ٽِڪيٽ درج ڪري ٿي، اڳ ۾ ئي اپ لوڊ ٿيل فائل منسلڪ ڪندي. ڪال idempotent آهي؛ ساڳيو Idempotency-Key 24 ڪلاڪن اندر ورجائڻ مماثل 201 جواب موٽائي ٿو (ڪابه duplicate ٽِڪيٽ ناهي).

درخواست

POST /api/v1/tickets
Host: sindhitportal.maahir.io
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIs...
Idempotency-Key: 9a2c4e6b-1f3d-4a2c-9e8b-7d6c5b4a3f2e
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
Accept-Language: en
Content-Type: application/json

{
  "companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ",
  "title": "Pending sales tax refund for Q4 2025",
  "description": "Our company filed the Q4 2025 SRB refund on 15 Jan 2026; no acknowledgment received.",
  "category": "SRB-REFUND",
  "targetDept": "SRB",
  "priority": "normal",
  "language": "en",
  "attachments": [
    {
      "filename": "SRB-Q4-2025-filing.pdf",
      "mimeType": "application/pdf",
      "size": 482310,
      "uploadId": "fil_upl_01HZX9F8K7P4N2Q3R6STV8WXY"
    }
  ],
  "requestedBy": { "repId": "rep_01HZX7K4P9N2Q3R6STV8WXYPJ" }
}

جواب

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/tickets/SITP-2026-SRB-000128
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
X-SITP-API-Version: v1
X-RateLimit-Tier: standard
X-RateLimit-Remaining: 599

{
  "data": {
    "ticketId": "SITP-2026-SRB-000128",
    "status": "new",
    "state": "triage-pending",
    "category": "SRB-REFUND",
    "targetDept": "SRB",
    "priority": "normal",
    "sla": {
      "responseBy": "2026-07-19T09:00:00Z",
      "resolveBy": "2026-07-27T09:00:00Z",
      "paused": false
    },
    "createdAt": "2026-07-17T09:18:42.117Z",
    "portalUrl": "https://sindhitportal.maahir.io/tickets/SITP-2026-SRB-000128",
    "attachments": [
      {
        "filename": "SRB-Q4-2025-filing.pdf",
        "attachmentId": "fil_att_01HZX9F8K7P4N2Q3R6STV8WXZ",
        "size": 482310,
        "isEvidence": false
      }
    ]
  },
  "meta": {
    "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB",
    "locale": "en",
    "serverTime": "2026-07-17T09:18:42.117Z"
  }
}

ساڳئي Idempotency-Key ۽ مماثل باڊي سان duplicate POST ساڳيو 201 (ساڳئي ticketId سان) موٽائي ٿو، 409/duplicate جي بدران؛ ساڳئي ڪنجي سان مختلف باڊي 409 SITP-CONFLICT-002 موٽائي ٿي (§8).

11.2 ٽِڪيٽ حيثيت حاصل ڪرڻ (پڙهڻ، sparse fieldset)

هڪ پارٽنر هڪ ٽِڪيٽ poll ڪري ٿو ۽ رڳو حيثيت + SLA فيلڊز گهرُي ٿو ته جيئن ميٽرڊ موبائل لنڪ تي payload گهٽ ۾ گهٽ رهي. اهو sparse-fieldset query (§5.4) استعمال ڪري ٿو.

درخواست

GET /api/v1/tickets/SITP-2026-SRB-000128?fields=ticketId,status,sla,assignedTo
Host: sindhitportal.maahir.io
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIs...
Accept-Language: en
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAE

جواب

HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAE
X-SITP-API-Version: v1
X-RateLimit-Remaining: 587

{
  "data": {
    "ticketId": "SITP-2026-SRB-000128",
    "status": "assigned",
    "assignedTo": { "dept": "SRB", "section": "Refunds" },
    "sla": {
      "responseBy": "2026-07-19T09:00:00Z",
      "resolveBy": "2026-07-27T09:00:00Z",
      "paused": false,
      "firstResponseAt": null
    }
  },
  "meta": {
    "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAE",
    "locale": "en",
    "serverTime": "2026-07-17T10:02:13.004Z",
    "requestedFields": ["ticketId", "status", "sla", "assignedTo"]
  }
}

جن فيلڊز جي درخواست ناهي ٿي (title، description، attachments، createdAt، …) انهن کي ڇڏي ويندو آهي. جيڪڏهن ٽِڪيٽ موجود ناهي يا ڪالر جي visibility ناهي ته جواب 404 SITP-NOTFOUND-001 (§7.3) آهي — ٻنهي لاءِ هڪ ئي شڪل، ته جيئن موجودگي leak ناهي ٿيندي.

11.3 عوامي stats جي فهرست (گمنام، ڪابه auth ناهي)

هڪ شهري يا محقق گمنام ٿيل عوامي-شفافيت مجموعات آڻي ٿو. ڪابه ٽوڪن گهربل ناهي؛ public ريٽ لمٽ درجي (§4.1) جو تابع.

درخواست

GET /api/v1/stats/public?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z&limit=20
Host: sindhitportal.maahir.io
Accept-Language: en
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAF

جواب

HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAF
X-SITP-API-Version: v1
X-RateLimit-Tier: public
X-RateLimit-Remaining: 118

{
  "data": {
    "window": { "since": "2026-07-01T00:00:00Z", "until": "2026-07-31T23:59:59Z" },
    "totals": {
      "ticketsReceived": 4821,
      "ticketsResolved": 3104,
      "ticketsClosed": 2877,
      "avgResolutionHours": 53.2,
      "medianResolutionHours": 38.0,
      "csatAverage": 4.2,
      "withinSlaPercent": 87.4
    },
    "byDepartment": [
      { "dept": "SRB",  "received": 1210, "resolved": 902, "withinSlaPercent": 91.1 },
      { "dept": "SITD", "received": 988,  "resolved": 741, "withinSlaPercent": 89.0 },
      { "dept": "LBR",  "received": 612,  "resolved": 388, "withinSlaPercent": 81.3 },
      { "dept": "FIN",  "received": 457,  "resolved": 290, "withinSlaPercent": 84.6 }
    ],
    "byStatus": {
      "new": 612, "triaged": 233, "assigned": 410,
      "in_progress": 374, "resolved": 227, "closed": 2877, "reopened": 88
    },
    "generatedAt": "2026-07-17T10:05:00.000Z"
  },
  "meta": {
    "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAF",
    "locale": "en",
    "serverTime": "2026-07-17T10:05:11.882Z",
    "anonymized": true,
    "page": { "limit": 20, "returned": 4, "hasMore": false }
  },
  "links": {
    "self": "/api/v1/stats/public?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z&limit=20"
  }
}

byDepartment ۽ byStatus تفصيلون nightly pre-aggregate ٿين ٿيون (/specs/sd/17-analytics-kpis/ مطابق) ۽ cache ٿين ٿيون؛ meta.anonymized: true flag عوامي-stats جوابن تي هميشه موجود هوندو آهي. ڪنهن به عوامي-stats payload ۾ ڪو به انفرادي ٽِڪيٽ، ڪمپني، يا نمائندو سڃاڻپ جوڳو ناهي.


12. ويب هوڪ معاهدو

ويب هوڪس پارٽنر ائپس کي polling کان سواءِ real time ۾ SITP واقعن تي ردعمل ظاهر ڪرڻ جي سهولت ڏين ٿا. هي سيڪشن پارٽنر جو سامهون وارو معاهدو آهي؛ وصول ڪندڙ طرف جا ميڪنزم (دستخط verify، replay protect، enqueue) /specs/sd/08-integrations-spec/ §9 ۾ بيان ٿيل آهن.

12.1 واقعا

واقعو ٽرگر عام صارف
ticket.created ڪنهن پارٽنر جي ڪمپني جي پاران/لاءِ نئون ٽِڪيٽ درج. پارٽنر CRM.
ticket.assigned ٽِڪيٽ ڪنهن محڪمي/شعبي کي تفويض. پارٽنر.
ticket.status_changed ڪابه به حيثيت ٽرانزيشن (triaged، in_progress، resolved، closed، reopened، appealed). پارٽنر.
ticket.escalated اِسڪيليشن ليڊر درجو فائر ٿيو. پارٽنر + نگراني ڊيش بورڊ.
ticket.resolved Resolution-proof گیٽ پورو ٿيو. پارٽنر.
ticket.closed آٽو ڪلوز يا ڪمپني قبول. پارٽنر.
ticket.message_appended عوامي پيغام شامل ڪيو ويو (ڪمپني يا محڪمي پاران). پارٽنر.
mom.published ٽِڪيٽ تي MoM شائع ٿيو. پارٽنر.
organization.verified بڪ گرائونڊ چيڪس ڪامياب → تصديق ٿيل بيچ. پارٽنر.
organization.on_hold بڪ گرائونڊ چيڪ ناڪام → on hold + اپيل. پارٽنر.

12.2 ترسيل جو معاهدو

12.3 HMAC-signed payload نمونو

POST https://partner.example.org/sitp/webhook
Content-Type: application/json
X-SITP-Event: ticket.status_changed
X-SITP-Signature: t=1752752322,v1=5b1c3729d4f8a2e6b0c1d9e7f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2
X-SITP-Delivery: dlv_01HZX9F8K7P4N2Q3R6STV8WXZ
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAD

{
  "eventId": "evt_01HZX9F8K7P4N2Q3R6STV8WXAB",
  "eventType": "ticket.status_changed",
  "occurredAt": "2026-07-17T09:38:42.000Z",
  "version": "1",
  "data": {
    "ticketId": "SITP-2026-SRB-000128",
    "companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ",
    "previousStatus": "new",
    "status": "assigned",
    "assignedTo": { "dept": "SRB", "section": "Refunds" },
    "sla": { "responseBy": "2026-07-19T09:00:00Z" },
    "portalUrl": "https://sindhitportal.maahir.io/tickets/SITP-2026-SRB-000128"
  },
  "delivery": { "deliveryId": "dlv_01HZX9F8K7P4N2Q3R6STV8WXZ", "attempt": 1 }
}

Verify ڪرڻ جو pseudocode (پارٽنر طرف):

t, v1 = parse(X-SITP-Signature)            # "1752752322", "5b1c..."
if abs(now() - t) > 300: reject            # replay window
expected = HMAC_SHA256(secret, t + "." + raw_request_body)
if not constant_time_eq(expected, v1): reject
event = JSON.parse(raw_request_body)
if seen(event.eventId): ignore              # idempotency
handle(event)

دستخط SITP پاران HMAC_SHA256(secret, "<t>.<rawRequestBody>") جي طور تي compute ٿيندو آهي ۽ v1 جي طور تي hex-encode ٿيندو آهي.


13. SDK ۽ Codegen منصوبو

SITP جي OpenAPI 3.1 دستاويز ڪلائنٽ SDK پيدا ڪرڻ جو واحد input آهي. منصوبو:

چينل جنريٽر آئوٽ پُٽ حيثيت
TypeScript / browser openapi-typescript + openapi-fetch Type-safe fetch ڪلائنٽ جيڪو Next.js پورٽل استعمال ڪري ٿو. Phase 1.
TypeScript / Node @hey-api/openapi-ts (يا openapi-generator-cli typescript-axios) پارٽنر SDK جيڪو private npm scope تي شائع ٿئي. Phase 1.
Python openapi-generator-cli python پارٽنر SDK (PyPI) — تحقيق/ڊيٽا پارٽنرز جي ترجيح. Phase 2.
React Native TS ڪلائنٽ کي ٻيهر استعمال ڪري ٿو. Phase 4.
Postman / Bruno OpenAPI مان auto-پيدا ٿيل collection. پارٽنر آن بورڊنگ پيڪ. Phase 1.
Mock server OpenAPI دستاويز مان prism (Stoplight). سينڊ باڪس معاهدي ٽيسٽنگ (§15). Phase 1.

ضابطا:


14. Deprecation پاليسي

14.1 Lifecycle

هر API عنصر (endپوائنٽ، فيلڊ، پيٽاميٽر، enum قدر، واقعو) انهن مرحلن مان گذري ٿو:

experimental → current → deprecated → sunset → removed

14.2 ڇا ڀڃندڙ آهي (نئون ميجر لازمي)

14.3 ڇا غير ڀڃندڙ آهي (in-version جاري)

14.4 Timelines


15. سينڊ باڪس ۽ ٽيسٽ ماحول

هڪ مخصوص سينڊ باڪس ماحول پارٽنرز کي پروڊڪشن ڊيٽا کي ڇهه کان سواءِ بنائڻ ۽ ٽيسٽ ڪرڻ جي سهولت ڏئي ٿو.

پهلو سينڊ باڪس پروڊڪشن
بيس URL https://sandbox.sindhitportal.maahir.io/api/v1 https://sindhitportal.maahir.io/api/v1
ڊيٽا الڳ ڊيٽابيس؛ synthetic ڪمپنين، ٽِڪيٽن، محڪمن سان seeded. حقيقي.
Integrations Mocked. NADRA/SECP/FBR/SRB/PSEB canned جواب موٽائين ٿا (ايڊاپٽر mock موڊ مطابق). Mailjet/SMS/WhatsApp هڪ اندروني mailbox ڏانهن divert ٿين ٿا — سينڊ باڪس مان ڪابه حقيقي اي ميل/SMS ناهي نڪرندو. Live.
ٽوڪنز Self-service پارٽنر ڪنسول؛ client secrets آزاديءَ سان rotated. Vetted.
ريٽ لمٽس ساڳئيا درجا، گهٽ ceilings (tunable). §4.1 مطابق.
ويب هوڪس پارٽنر endپوائنٽس سينڊ باڪس مان واقعا وصول ڪن ٿا؛ پارٽنرز offline معاهدي ٽيسٽنگ لاءِ mock server (prism) به استعمال ڪري سگهن ٿا. Live.
OpenAPI سينڊ باڪس host تي /api/v1/openapi.json. /api/v1/openapi.json.

15.1 ٽيسٽ ڊيٽا

15.2 معاهدي ٽيسٽنگ


16. مشاهدگي — correlation IDs

هر درخواست — ڪامياب يا ناڪام — هڪ correlation آءِ ڊي ذريعي end-to-end قابلِ سراغ آهي.

هيڊر طرف مقصد
X-Request-Id In (optional) / Out (هميشه) ڪلائنٽ جي فراهم ڪيل يا SITP جو پيدا ڪيل؛ جواب تي echoed ۽ هر log لائن، OTel span، ۽ audit_logs.request_id ۾ thread ٿيل (/specs/sd/05-data-model/ §3.10 مطابق).
X-Correlation-Id In (optional) / Out (جي فراهم ڪئي وڃي) هڪ upstream آءِ ڊي carry ڪري ٿو جڏهن SITP پاڻ کي ڪنهن ٻئي نظام (مثال طور، هڪ والده حڪومتي پورٽل) سان ڪيو وڃي.
Traceparent (W3C) In/Out معياري W3C trace context؛ SITP هڪ OTel participant آهي ۽ trace کي انضمام ايڊاپٽرز تائين propagate ڪري ٿو (/specs/sd/08-integrations-spec/ §11 ۾ NFR-INT-008 مطابق).

رويو:


17. درخواست Lifecycle (end-to-end)

ڊاياگرام هڪ واحد تصديق ٿيل تحرير — POST /tickets — جو مڪمل lifecycle ڏيکاري ٿو، پارٽنر جي HTTP ڪال کان هر cross-cutting تشوش ذريعي آخري جواب تائين.

sequenceDiagram autonumber participant P as Partner app participant GW as nginx / API gateway participant API as NestJS API (controller) participant MW as Cross-cutting middleware<br/>(cors · ratelimit · auth · idempotency · audit · otel) participant DOM as Domain module<br/>(TicketsService) participant INT as Integration layer<br/>(adapters · resilience · DLQ) participant DB as MariaDB participant Q as BullMQ participant WH as Webhook dispatcher P->>GW: POST /api/v1/tickets\nAuthorization, Idempotency-Key, X-Request-Id GW->>API: forward (+ mints traceparent if absent) API->>MW: enter middleware chain MW->>MW: ratelimit check (429 → problem+json) MW->>MW: verify bearer token + scope (401/403 → problem+json) MW->>MW: idempotency lookup (cache hit → replay original response) MW->>MW: validate body (422 → problem+json) MW->>DOM: createTicket(dto, actor) DOM->>DB: BEGIN; insert ticket (tracking_id generated) DOM->>INT: route/notification calls (queued, idempotent) INT->>Q: enqueue (SLA timer, notifications, e-Office push) DOM->>DB: COMMIT; write audit_logs + ticket_history DOM-->>API: Ticket entity API->>WH: enqueue ticket.created event API-->>MW: build envelope {data, meta, links} MW-->>GW: 201 Created (+ X-Request-Id, rate-limit headers) GW-->>P: 201 Created, Location header Note over WH,INT: Async fan-out (after response):<br/>notifications, webhooks, SLA clock, registry checks WH->>P: POST <partner webhook URL> (signed, retried)

تحريري وضاحت. هڪ پارٽنر POST /tickets هڪ Authorization bearer، هڪ Idempotency-Key، ۽ (اختياري طور تي) هڪ X-Request-Id سان جاري ڪري ٿو. nginx گیٽ وي ڪال forward ڪري ٿو، ۽ ڪابه traceparent موجود ناهي ته W3C traceparent تيار ڪري ٿو. NestJS اندر، cross-cutting middleware chain هڪ مقرر ترتيب ۾ هلندو آهي: CORS → rate limit → authentication → authorization (scope/role) → idempotency lookup → request validation → audit/OTel span open. ڪابه به ناڪامي اصل X-Request-Id رکندڙ RFC 7807 problem دستاويز سان short-circuit ٿي ويندي آهي. جيڪڏهن idempotency ڪنجي 24 ڪلاڪن اندر ڏٺي وئي هجي ۽ payload مطابقت رکي، ته اصل جواب verbatim ٻيهر هلائي ويندو آهي ۽ ڪابه ڊومين ڪم ناهي هلندو. cache miss تي، ڪنٽرولر validated DTO کي TicketsService حواله ڪري ٿو، جيڪو هڪ MariaDB ٽرانزيڪشن کولي ٿو، SITP-YYYY-DEPT-NNNNNN ٽريڪنگ آءِ ڊي پيدا ڪري ٿو، ٽِڪيٽ insert ڪري ٿو، هڪ ticket_history قطار ۽ هڪ audit_logs قطار لکي ٿو، ۽ side-effects (SLA ڪلاڪ start، notifications، اختياري e-Office فائل push، registry تصديقي jobs) کي BullMQ ۾ enqueue ڪري ٿو — هي ٽرانزيڪشن commit ٿيڻ کان پوءِ هلن ٿا ته جيئن جواب ڪڏهن به بيروني latency کان block ناهي ٿيندو. ٽرانزيڪشن commit ٿئي ٿو، ڪنٽرولر نئون ٽِڪيٽ {data, meta, links} لفافي ۾ ويڙهي ٿو، middleware ريٽ لمٽ ۽ version هيڊرز attach ڪري ٿو، ۽ گیٽ وي نئين وسيلي ڏانهن اشارو ڪندڙ Location هيڊر سان 201 Created موٽائي ٿو. ان دوران، BullMQ workers fan out ٿين ٿا: notifications communications ايڊاپٽرز ذريعي موڪليا ويندا آهن، ticket.created ويب هوڪ HMAC-signed ۽ deliver (۽ §12.2 مطابق retry) ٿيندو آهي، ۽ SLA ڪلاڪ محڪمي جي ڪاروباري ڪلاڪن اندر هلڻ شروع ڪندو آهي. هر قدم — گیٽ وي، middleware، ڊومين، انضمام، قطار — هڪ OTel span emit ڪري ٿو جيڪو ساڳئي X-Request-Id سان tag ٿيل آهي، ان لاءِ پارٽنر جي آءِ ڊي report ڪرڻ سان ops کي Grafana/Loki ۾ پورو trace reconstruct ملندو آهي.


18. کليل سوالات / TBD

# شئي حيثيت
1 Premium پارٽنر درجو ceilings ۽ تجارتي شرطون. TBD (procurement).
2 آيا سينڊ باڪس high-trust flows جي ٽيسٽنگ لاءِ synthetic NADRA بائيو ميٽرڪ ٽوڪنز ظاهر ڪري. NADRA mock spec سان TBD.
3 TS ۽ Python کان علاوه final SDK زبانون (Go؟ Java؟). TBD (پارٽنر طلب).
4 Analytics-heavy پارٽنرز لاءِ GraphQL facet، يا رڳو REST. TBD (Phase 2 evaluation).
5 عوامي read API ڪنجي پروگرام (صرف پڙهڻ جي عوامي ڊيٽا صارفين لاءِ OAuth جو هلڪو متبادل). TBD.
6 آيا POST /sandbox/reset سڀني پارٽنرز کي ظاهر ٿئي يا gated. TBD.
7 NestJS ↔ AI مائڪروسروس boundary لاءِ gRPC / protobuf اندروني معاهدو (هن عوامي REST دستاويز جي دائري کان ٻاهر). /specs/sd/15-tech-architecture/ ڏسو.

دستاويز جو خاتمو.