API — integratorlar uchun
*English: README.en.md*
O'z tizimingizdan (skript, ERP, EDO) Muhrdor serverida ERI bilan imzolang — bitta hujjat yoki 200 tagacha partiya. Kalit HSM dan chiqmaydi va sizga berilmaydi: sizning xizmat akkauntingiz kalit egasi imzolagan huquq akti doirasida, aktda nomlangan saytlar va hujjat turlari uchun imzolaydi. Har imzo kalit egasining audit jurnalida «API» belgisi bilan.
- Mashina o'qiydigan shartnoma:
GET https://muhrdor.uz/api/v1/openapi.json(repo dadocs/api/openapi-integrators.json) - To'liq ma'lumotnoma (har endpoint, maydonlar): reference.md
- Xatolar katalogi: errors.md
- Tayyor misol (faqat Python stdlib):
examples/muhrdor_sign.py - Sim formati batafsil:
docs/protocols/api-v1-service-account.md
1. Tayyorgarlik (bir marta)
- Xizmat akkaunti. Muhrdor panelida (ERI bilan tasdiqlangan akkaunt) → «API kalitlari» → nom yozing → «Yaratish».
client_id(sa_…) vaclient_secretchiqadi — secret faqat shu oynada, bir marta. Uni skript sozlamasiga (muhit o'zgaruvchisi) saqlang, kodga emas. - Akt.
client_idni kalit egasiga yuboring (masalan, mijoz korxona rahbariga). U panelda «Huquqlar → Huquq berish → Xizmat akkaunti (client_id)» → «Topish» (sizning akkaunt nomingiz va ismingizni ko'radi) → sayt(lar) va hujjat turlari → muddat → «Aktni imzolash». Xizmat akkauntiga «barcha saytlar» berilmaydi: har sayt aktda nomlanadi. - Tekshiring:
GET /api/v1/client/credentialskalitniaccess: "grant"va akt doirasi bilan ko'rsatadi.
2. Tez boshlash
export MUHRDOR_CLIENT_ID=sa_... export MUHRDOR_CLIENT_SECRET=... python examples/muhrdor_sign.py --site my.soliq.uz --credential <credential_id> hisobot.xml # -> hisobot.xml.p7b va "hisobot.xml: <audit_ref>"
curl bilan:
TOKEN=$(curl -s https://muhrdor.uz/api/v1/token -H 'Content-Type: application/json' \
-d "{\"grant_type\":\"client_credentials\",\"client_id\":\"$MUHRDOR_CLIENT_ID\",\"client_secret\":\"$MUHRDOR_CLIENT_SECRET\"}" \
| jq -r .access_token)
curl -s https://muhrdor.uz/api/v1/client/credentials -H "Authorization: Bearer $TOKEN"
curl -s https://muhrdor.uz/api/v1/signatures/sign -H "Authorization: Bearer $TOKEN" \
-H 'Idempotency-Key: hisobot-2026-09-0001' -H 'Content-Type: application/json' \
-d '{"credential_id":"…","site":"my.soliq.uz","documents":[{"content_b64":"…","external_ref":"hisobot-9"}]}'3. Qadamlar
- Token —
POST /api/v1/token{grant_type: "client_credentials", client_id, client_secret}→access_token, 1 soat. Refresh yo'q: 401 kelsa yangisini oling. Har so'rovga yangi token olmang (soatiga 30 ta chegara). - Kalitlar —
GET /api/v1/client/credentials:credential_idva akt doirasi. - Imzolash —
POST /api/v1/signatures/sign:site— hujjat qaysi sayt uchun (aktda bo'lishi shart);documents[]— 1..200, jami 5 MiB;content_b64,detached(sukuttrue— PKCS#7 da kontent yo'q;false— kontent ichida),external_ref— sizning hujjat raqamingiz (≤64,A-Z a-z 0-9 . _ : / -), javobda qaytadi va jurnalda saqlanadi;Idempotency-Keymajburiy — har yangi so'rovga yangi kalit (masalan UUID). Javob:results[i]—pkcs7_b64(DER PKCS#7, E-IMZO shakli),audit_ref,doc_class,external_ref; rad etilgan hujjatdaerror.
- Natija keyin —
GET /api/v1/signatures/{audit_ref}?credential_id=<kalit>: imzo qismlari va PKCS#7 xeshi (PKCS#7 ning o'zi serverda saqlanmaydi —.p7bni o'zingiz saqlang).
4. Qayta yuborish — ikki marta imzolamaslik
Tarmoq uzildi, javob kelmadi — xuddi shu Idempotency-Key va xuddi shu tana bilan qayta yuboring: 10 daqiqa ichida server birinchi javobni qaytaradi, ikkinchi imzo bo'lmaydi.
409 request_in_progress— birinchisi hali ishlayapti: bir soniyadan keyin shu kalit bilan.422 idempotency_mismatch— bu kalit boshqa tana uchun ishlatilgan: yangi so'rov — yangi kalit.429 too_many_requests—Retry-Aftersoniya kuting.502 signing_failed+retryable: true— shu kalit bilan bir marta qayta.403 policy_denied— qayta yubormang: akt yetmaydi (reason— sabab).
5. Saytlar va hujjat turlari
Hujjat turi (doc_class) kontentdan aniqlanadi. Akt doc_kinds da nomlagan turlar o'tadi.
| Sayt | Turlar |
|---|---|
my.soliq.uz | hisobot, login |
didox.uz | factura, qabul, hujjat, login |
xt-xarid.uz | hash32 |
my.it-park.uz | login |
Boshqa XML/JSON — tuzilma turi (xml:<ildiz element>, json:<xesh>): kalit egasi uni aktda aniq yozsa o'tadi. Tanilmagan kontent — UNCLASSIFIED_CONTENT. Qaysi tur kerakligini bilish: rad javobining detail i va kalit egasining panelidagi «Rad etilgan so'rovlar» turini ko'rsatadi — egasi uni aktga qo'shadi. Yangi sayt — Muhrdor adapteri kerak (bizga yozing).
6. Chegaralar
| Nima | Chegara |
|---|---|
| Token | 1 soat; soatiga 30 ta (har client_id) |
| Bitta so'rov | 200 hujjat, jami 5 MiB |
| Imzo tezligi | daqiqasiga 600 hujjat (har xizmat akkaunti; server sozlamasi) |
| Idempotentlik oynasi | 10 daqiqa |
| Faol xizmat akkauntlari | 10 ta (har shaxs) |
7. Maxfiylik va jurnal
Hujjat mazmuni saqlanmaydi. Jurnalda: kontent va imzolangan atributlar xeshi, hujjat turi, sayt, page_url (query siz), hujjat raqami/davri (sayt maydonlari xaritasidan, summasiz), sizning external_ref, akt havolasi, client: "api". external_ref ga shaxsiy ma'lumot (JSHSHIR, ism) yozmang — bu identifikator.
8. Xavfsizlik
- Secret faqat yaratish yoki «Secretni yangilash» paytida ko'rinadi; yo'qolsa — yangilang (eski secret va tokenlar darhol o'ladi).
- Akkaunt keraksiz bo'lsa — «O'chirish» (qaytarilmas). Kalit egasi aktni istalgan vaqt bekor qiladi — keyingi so'rov rad etiladi.
- API tokeni odam endpointlarini ochmaydi: faqat token,
client/*vasignatures/*.