Sotishni boshlashIlovani olish

OpenAPI 3.1REST · v1

Dona API

Doʻkoningizni oʻz tizimingizga ulang: mahsulotlar, zaxira va narxlar, buyurtmalar, hisob holati va hodisalar — bitta REST API orqali. 1C, MoySklad, BILLZ, SmartUp, Linko va AI-agentlar uchun.

Kalitni doʻkon egasi sotuvchi kabinetida yaratadi: Sozlamalar › API. Kalit faqat bir marta koʻrsatiladi.

Asosiy manzil
https://api.dona.im/seller-api/v1
Kalit turlari
  • dona_sk_live_…integratsiya kaliti — ERP, 1C, POS va oʻz tizimingiz uchun
  • dona_ak_live_…AI-agent kaliti — faqat MCP orqali
  • dona_it_live_…dastur oʻrnatish tokeni — tez orada

API bosqichma-bosqich ochilmoqda. Qaysi qismlar hozir ishlayotganini «Holat» sahifasi, nima qoʻshilganini «Oʻzgarishlar» koʻrsatadi.

Birinchi soʻrovget/me
curl
curl -sS https://api.dona.im/seller-api/v1/me \
  -H "Authorization: Bearer $DONA_KEY"
200Javob misoli
{
  "key": { … },
  "shop": { … },
  "tier": "basic",
  "api_access": { … },
  "writes_enabled": false,
  "limits": {
    "requests_per_min": 300,
    "burst": 60,
    "requests_per_day": 100000,
    "writes_per_min": 60,
    "writes_per_day": 20000,
    "in_flight": 4,
    "seller_requests_per_min": 900,
    "remaining": { … }
  },
  "attention": { … },
  "docs_url": "https://dona.uz/uz/developers"
}
Mundarija

0108

Tezkor boshlash

4 qadam

Toʻrt qadam: kalit, birinchi soʻrov, xavfsiz sinov yozuvi va hodisalar oqimi.

  1. Kalit yarating

    Sotuvchi kabineti › Sozlamalar › API › Yangi kalit yaratish. Faqat kerakli ruxsatlarni (scope) belgilang. Birinchi kalitni yaratishdan oldin doʻkon egasi sotuvchi kabinetida 2-ilova (API va avtomatlashtirilgan kirish) shartlarini qabul qilishi shart.

    Doʻkon egasi amaldagi 2-ilovani qabul qilmaguncha har bir kirish yoʻli — REST, MCP va OAuth — 403 agreement_required javobini accept_url bilan qaytaradi: bu ilova qabul qilinadigan kabinet sahifasi.

  2. Kim ekaningizni tekshiring

    GET /me kalit, doʻkon, daraja (Asosiy/Kengaytirilgan), ruxsatlar va joriy chegaralarni qaytaradi.

    GET /me
    curl -sS https://api.dona.im/seller-api/v1/me \
      -H "Authorization: Bearer $DONA_KEY"
    GET /me javobi (spetsifikatsiyadagi misol)
    200
    {
      "key": {
        "id": "0199760c-2f4b-7a3e-9d21-5c8e4b1f0a37",
        "name": "billz-prod",
        "kind": "sk",
        "prefix": "dona_sk_live_3fK",
        "scopes": [
          "catalog:read",
          "catalog:stock",
          "orders:read"
        ],
        "expires_at": "2027-09-24T00:00:00+05:00",
        "ip_allow": []
      },
      "shop": {
        "id": "0198f3a2-6c1d-7b40-8e55-2a9c3d4e5f60",
        "name": "Bahor Textile",
        "status": "approved",
        "documents_status": "approved",
        "kyc_status": "approved",
        "can_sell": true
      },
      "tier": "basic",
      "api_access": {
        "state": "enabled",
        "reason": null
      },
      "writes_enabled": false,
      "limits": {
        "requests_per_min": 300,
        "burst": 60,
        "requests_per_day": 100000,
        "writes_per_min": 60,
        "writes_per_day": 20000,
        "in_flight": 4,
        "seller_requests_per_min": 900,
        "remaining": {
          "requests_per_min": 287,
          "requests_per_day": 99412,
          "writes_per_min": 60,
          "writes_per_day": 20000
        }
      },
      "attention": {
        "open": 3,
        "action_required": 2
      },
      "docs_url": "https://dona.uz/uz/developers"
    }
  3. Zaxirani sinab yozing

    Dona-Dry-Run: true bilan har bir yozuv tekshiriladi, natija hisoblanadi va hech narsa saqlanmaydi.

    Yozuvlar hali yopiq boʻlsa (writes_enabled), server 503 limits_unavailable qaytaradi — bu kalit xatosi emas.

    POST /stock
    curl -sS -X POST https://api.dona.im/seller-api/v1/stock \
      -H "Authorization: Bearer $DONA_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Dona-Dry-Run: true" \
      -H "Content-Type: application/json" \
      -d '{"items":[{"seller_sku":"A-100","quantity":12}]}'
  4. Oʻzgarishlarni oling

    GET /events?cursor=… — asosiy kanal. Webhooklar shu hodisalarni sizga yuboradi.

    GET /events
    curl -sS "https://api.dona.im/seller-api/v1/events?cursor=$LAST_EVENT_ID&limit=200" \
      -H "Authorization: Bearer $DONA_KEY"

0208

Maʼlumotnoma

14 guruh · 61 amal

Har bir amal OpenAPI shartnomasidan sayt yigʻilayotganda chizilgan. Belgi amalga qaysi darajadagi kalit va qaysi ruxsat kerakligini koʻrsatadi.

Maʼlumotnoma shartnomaning oʻzi kabi ingliz tilida.

Asosiy
Har qanday amaldagi kalit
Kengaytirilgan
Shaxs, hujjatlar va doʻkon tasdiqlangan, jazo yoʻq
Ochiq
Kalitsiz
Umumiy parametrlar (har bir amalda nomi bilan koʻrsatilgan)11
  • Idempotency-Keyheader · string

    1–255 chars. Scope = this key × route. Terminal 2xx/4xx replayed byte-identical for 24 h; a 5xx is never stored. Missing ⇒ 400 invalid_body with details[{field:"Idempotency-Key",code:"required"}].

  • Accept-Languageheader · string

    Localises message in error bodies and single-language renderings. Default uz.

  • X-Dona-Integrationheader · string

    name/version of the calling integration; stored (≤ 128 chars) and searchable in the request journal.

  • Dona-Dry-Runheader · string

    true ⇒ validate + guard + compute the effect, then roll back. Zero side-effect rows (no events, no activity, no counters). Same as ?dry_run=true. Only the literal true / false; any other value ⇒ 400 invalid_body + details[{field:"Dona-Dry-Run", code:"invalid"}] (C51).

  • dry_runquery · string

    Alias of the Dona-Dry-Run header. Only the literal strings true / false — 1, 0, TRUE, yes, an empty value ⇒ 400 invalid_body + details[{field:"dry_run", code:"invalid"}] (C51). A string enum, not a boolean, so no SDK generator serialises it as 1/0.

  • Dona-Sellerheader · string (uuid)

    Vendor-app install keys only (dona_it_live_…, S6) — and then REQUIRED on every request, public routes included: the id of the shop the install key belongs to. Missing ⇒ 400 invalid_body + details[{field:"Dona-Seller", code:"required"}]; sent more than once, or not ONE id in the canonical form the API prints (lower-case, 36 characters — no braces, no urn:uuid:, no padding) ⇒ 400 invalid_body + details[{field:"Dona-Seller", code:"invalid"}]; naming any other shop — even one that installed the same app ⇒ 404 not_found (never 403; nothing is read). Ignored on a seller key (dona_sk_).

  • If-None-Matchheader · string

    An ETag from a previous identical request ⇒ 304 with rate headers (cost 0.5).

  • cursorquery · string

    Opaque keyset cursor from next_cursor.

  • limitquery · integer

    Page size, default 50, max 100 (clamped, with Dona-API-Warn). limit > 50 costs 1 + ceil(limit/50).

  • updated_sincequery · string

    ISO 8601 with offset, or epoch milliseconds. The visible high-water mark is capped at now() − 10 s so a slow transaction is never skipped.

  • pagequery · integer

    0-based page alias (Uzum parity) — slower than cursor, ≤ 1 000 pages; mutually exclusive with cursor.

Account

1 amal

The key's own view of itself and its shop.

get/meAsosiy

Who am I — key, shop, tier, limits

AsosiyRuxsat: anyNarx: key-rate · 1

The first call of every integration: the key's own row, the shop's three verdicts, the derived tier, the live limits with remaining budget, and the open attention counts. Fails closed: a DB error answers 503 auth_unavailable.

Parametrlar (3)
Javob 200 · Me
  • keyobjectmajburiy
  • shopobjectmajburiy
  • tierstringmajburiy

    Key tier, derived per request (never cached): ADVANCED = kyc approved AND documents approved (a waiver never counts) AND shop approved AND no active punishment; seller_api_access.tier_override may lower or raise it but never lifts a sanction.

    basic · advanced

  • api_accessobjectmajburiy
  • writes_enabledbooleanmajburiy

    app_config.seller_api.writes_enabled (seeded false until D5).

  • limitsLimitsmajburiy
  • attentionobjectmajburiy
  • docs_urlstring (uri)majburiy

    The developer docs home in the key owner's language (https://dona.uz/<uz|ru|en>/developers; the owner's users.language, else Accept-Language, else uz).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/me" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "key": {
    "id": "0199760c-2f4b-7a3e-9d21-5c8e4b1f0a37",
    "name": "billz-prod",
    "kind": "sk",
    "prefix": "dona_sk_live_3fK",
    "scopes": [
      "catalog:read",
      "catalog:stock",
      "orders:read"
    ],
    "expires_at": "2027-09-24T00:00:00+05:00",
    "ip_allow": []
  },
  "shop": {
    "id": "0198f3a2-6c1d-7b40-8e55-2a9c3d4e5f60",
    "name": "Bahor Textile",
    "status": "approved",
    "documents_status": "approved",
    "kyc_status": "approved",
    "can_sell": true
  },
  "tier": "basic",
  "api_access": {
    "state": "enabled",
    "reason": null
  },
  "writes_enabled": false,
  "limits": {
    "requests_per_min": 300,
    "burst": 60,
    "requests_per_day": 100000,
    "writes_per_min": 60,
    "writes_per_day": 20000,
    "in_flight": 4,
    "seller_requests_per_min": 900,
    "remaining": {
      "requests_per_min": 287,
      "requests_per_day": 99412,
      "writes_per_min": 60,
      "writes_per_day": 20000
    }
  },
  "attention": {
    "open": 3,
    "action_required": 2
  },
  "docs_url": "https://dona.uz/uz/developers"
}

Catalog

10 amal

Products, variants, media, publish/delist. Writes go through the shared guarded seams.

get/productsAsosiy

List products

AsosiyRuxsat: catalog:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Keyset list of the shop's products (deleted_at IS NULL). Deletions never appear in a delta — read /products/deleted.

Parametrlar (12)
Javob 200 · ProductPage
  • itemsProduct[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/products" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "title": {
        "uz": "Erkaklar futbolkasi, paxta",
        "ru": "Футболка мужская, хлопок"
      },
      "description": {
        "uz": "100% paxta, Oʻzbekistonda tikilgan."
      },
      "status": "active",
      "category_id": "01972a10-1111-7aaa-8bbb-0123456789ab",
      "brand": "Bahor",
      "seller_sku": "A-200",
      "barcode": "4780000000012",
      "external_id": "1c:0f2a9b",
      "price_uzs": 189000,
      "compare_at_uzs": 229000,
      "stock": 10,
      "has_variants": true,
      "variants": [
        {
          "id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
          "options": {
            "color": "Qizil",
            "size": "M"
          },
          "sku": "A-200-R-M",
          "barcode": "4780000000029",
          "price_uzs": 189000,
          "compare_at_uzs": null,
          "stock": 4,
          "status": "active",
          "version": "2026-09-24T13:59:41.120318+05:00"
        }
      ],
      "ikpu": "06109100001000000",
      "package_code": "1520227",
      "image_urls": [
        "https://media.dona.im/p/0199612e/1.webp"
      ],
      "video_url": null,
      "attributes": {
        "material": "paxta"
      },
      "created_via": "api",
      "hold": null,
      "open_issues": 0,
      "version": "2026-09-24T13:59:41.120318+05:00",
      "created_at": "2026-09-20T10:11:12+05:00",
      "updated_at": "2026-09-24T13:59:41+05:00"
    }
  ],
  "next_cursor": "eyJ1IjoiMjAyNi0wOS0yNFQwODo1OTo0MSJ9",
  "has_more": true
}
post/productsAsosiy

Create a product (lands as draft / ai_review)

AsosiyRuxsat: catalog:writeNarx: write-rate · 1

UpsertExternalProduct with created_via='api'. Lands draft/ai_review; publish:true asks to publish, and a pending shop's publish waits in product_shop_holds (hold.reason=shop_not_activated). The plausibility guard may answer 202 held_for_review (e.g. price_floor). Kill switch: writes_enabled.

Parametrlar (6)
Soʻrov tanasi · ProductCreate
  • titleLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

    LocalizedText
    • uzstring
    • rustring
    • enstring
  • descriptionLocalizedText

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

    LocalizedText
    • uzstring
    • rustring
    • enstring
  • category_idstring (uuid)majburiy
  • brandstring
  • seller_skustringmajburiy
  • barcodestring
  • external_idstring

    Your system's id, e.g. 1c:0f2a….

  • price_uzsinteger (int64)majburiy
  • compare_at_uzsinteger | null
  • stockintegermajburiy
  • ikpustring
  • package_codestring
  • image_urlsstring (uri)[]
  • video_urlstring (uri)
  • attributesobject
  • variantsVariantInput[]
    VariantInput[]
    • optionsobjectmajburiy
    • skustring
    • barcodestring
    • price_uzsinteger (int64)majburiy
    • compare_at_uzsinteger | null
    • stockintegermajburiy
  • publishboolean

    Ask to publish after create; a pending shop's product is held until documents approval.

Javob 201 · ProductCreated
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • holdobject | nullmajburiy
  • issuesIssue[]majburiy
  • created_via"api"majburiy
Javob kodlari
  • 201Created
  • 202Held for review — nothing written.
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/products" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"title":{"uz":"uz","ru":"string","en":"string"},"category_id":"0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e","seller_sku":"A-100","price_uzs":1,"stock":12}'
Javob misoli
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "draft",
  "hold": {
    "reason": "shop_not_activated"
  },
  "issues": [],
  "created_via": "api"
}
get/products/{id}Asosiy

Get a product

AsosiyRuxsat: catalog:readNarx: key-rate · 1

One product with its variants.

Parametrlar (4)
Javob 200 · Product
  • idstring (uuid)majburiy
  • titleLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • descriptionLocalizedText | nullmajburiy
  • statusstringmajburiy

    draft, ai_review, active, hidden today; tolerate new values.

  • category_idstring | nullmajburiy
  • brandstring | nullmajburiy
  • seller_skustring | nullmajburiy
  • barcodestring | nullmajburiy
  • external_idstring | nullmajburiy
  • price_uzsinteger (int64)majburiy

    Integer soʻm (no decimals).

  • compare_at_uzsinteger | nullmajburiy

    Must exceed price_uzs (0020 CHECK).

  • stockintegermajburiy

    Sum over variants when has_variants.

  • has_variantsbooleanmajburiy
  • variantsVariant[]majburiy
  • ikpustring | nullmajburiy
  • package_codestring | nullmajburiy
  • image_urlsstring (uri)[]majburiy
  • video_urlstring | nullmajburiy
  • attributesobjectmajburiy
  • created_viastringmajburiy

    manual, mass_upload, api, … (products_created_via_check).

  • holdobject | nullmajburiy
  • open_issuesintegermajburiy

    Open listing_issues + product_violations.

  • versionstringmajburiy

    Opaque (today the full-precision updated_at); echo verbatim.

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "title": {
    "uz": "Erkaklar futbolkasi, paxta",
    "ru": "Футболка мужская, хлопок"
  },
  "description": {
    "uz": "100% paxta, Oʻzbekistonda tikilgan."
  },
  "status": "active",
  "category_id": "01972a10-1111-7aaa-8bbb-0123456789ab",
  "brand": "Bahor",
  "seller_sku": "A-200",
  "barcode": "4780000000012",
  "external_id": "1c:0f2a9b",
  "price_uzs": 189000,
  "compare_at_uzs": 229000,
  "stock": 10,
  "has_variants": true,
  "variants": [
    {
      "id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
      "options": {
        "color": "Qizil",
        "size": "M"
      },
      "sku": "A-200-R-M",
      "barcode": "4780000000029",
      "price_uzs": 189000,
      "compare_at_uzs": null,
      "stock": 4,
      "status": "active",
      "version": "2026-09-24T13:59:41.120318+05:00"
    }
  ],
  "ikpu": "06109100001000000",
  "package_code": "1520227",
  "image_urls": [
    "https://media.dona.im/p/0199612e/1.webp"
  ],
  "video_url": null,
  "attributes": {
    "material": "paxta"
  },
  "created_via": "api",
  "hold": null,
  "open_issues": 0,
  "version": "2026-09-24T13:59:41.120318+05:00",
  "created_at": "2026-09-20T10:11:12+05:00",
  "updated_at": "2026-09-24T13:59:41+05:00"
}
patch/products/{id}Asosiy

Update a product

AsosiyRuxsat: catalog:writeNarx: write-rate · 1

ApplyExternalFields → gateEditActivation. A price change runs the plausibility guard (may 202). Kill switch: writes_enabled.

Parametrlar (7)
Soʻrov tanasi · ProductUpdate
  • titleLocalizedText

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

    LocalizedText
    • uzstring
    • rustring
    • enstring
  • descriptionLocalizedText

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

    LocalizedText
    • uzstring
    • rustring
    • enstring
  • category_idstring (uuid)
  • brandstring
  • barcodestring
  • external_idstring
  • price_uzsinteger (int64)
  • compare_at_uzsinteger | null
  • stockinteger

    Refused (details[].code=stock_not_editable) when the product has variants — use POST /stock with variant_id.

  • ikpustring
  • package_codestring
  • image_urlsstring (uri)[]
  • video_urlstring | null
  • attributesobject
  • versionstring

    Optional optimistic lock; stale ⇒ 409 version_conflict.

Javob 200 · Product
  • idstring (uuid)majburiy
  • titleLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • descriptionLocalizedText | nullmajburiy
  • statusstringmajburiy

    draft, ai_review, active, hidden today; tolerate new values.

  • category_idstring | nullmajburiy
  • brandstring | nullmajburiy
  • seller_skustring | nullmajburiy
  • barcodestring | nullmajburiy
  • external_idstring | nullmajburiy
  • price_uzsinteger (int64)majburiy

    Integer soʻm (no decimals).

  • compare_at_uzsinteger | nullmajburiy

    Must exceed price_uzs (0020 CHECK).

  • stockintegermajburiy

    Sum over variants when has_variants.

  • has_variantsbooleanmajburiy
  • variantsVariant[]majburiy
  • ikpustring | nullmajburiy
  • package_codestring | nullmajburiy
  • image_urlsstring (uri)[]majburiy
  • video_urlstring | nullmajburiy
  • attributesobjectmajburiy
  • created_viastringmajburiy

    manual, mass_upload, api, … (products_created_via_check).

  • holdobject | nullmajburiy
  • open_issuesintegermajburiy

    Open listing_issues + product_violations.

  • versionstringmajburiy

    Opaque (today the full-precision updated_at); echo verbatim.

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
  • 202Held for review — nothing written.
Soʻrov
curl -sS -X PATCH "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"title":{"uz":"uz","ru":"string","en":"string"},"description":{"uz":"uz","ru":"string","en":"string"},"category_id":"0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e"}'
Javob misoli
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "title": {
    "uz": "Erkaklar futbolkasi, paxta",
    "ru": "Футболка мужская, хлопок"
  },
  "description": {
    "uz": "100% paxta, Oʻzbekistonda tikilgan."
  },
  "status": "active",
  "category_id": "01972a10-1111-7aaa-8bbb-0123456789ab",
  "brand": "Bahor",
  "seller_sku": "A-200",
  "barcode": "4780000000012",
  "external_id": "1c:0f2a9b",
  "price_uzs": 189000,
  "compare_at_uzs": 229000,
  "stock": 10,
  "has_variants": true,
  "variants": [
    {
      "id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
      "options": {
        "color": "Qizil",
        "size": "M"
      },
      "sku": "A-200-R-M",
      "barcode": "4780000000029",
      "price_uzs": 189000,
      "compare_at_uzs": null,
      "stock": 4,
      "status": "active",
      "version": "2026-09-24T13:59:41.120318+05:00"
    }
  ],
  "ikpu": "06109100001000000",
  "package_code": "1520227",
  "image_urls": [
    "https://media.dona.im/p/0199612e/1.webp"
  ],
  "video_url": null,
  "attributes": {
    "material": "paxta"
  },
  "created_via": "api",
  "hold": null,
  "open_issues": 0,
  "version": "2026-09-24T13:59:41.120318+05:00",
  "created_at": "2026-09-20T10:11:12+05:00",
  "updated_at": "2026-09-24T13:59:41+05:00"
}
get/products/{id}/issuesAsosiy

Why a product is held, rejected or flagged

AsosiyRuxsat: catalog:readNarx: key-rate · 1

Open listing_issues, product_shop_holds and product_violations for one product.

Parametrlar (4)
Javob 200 · ProductIssues
  • product_idstring (uuid)majburiy
  • itemsIssue[]majburiy
Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/issues" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "items": [
    {
      "id": "01996200-aaaa-7bbb-8ccc-0123456789ef",
      "source": "listing_issue",
      "severity": "error",
      "type": "missing_field",
      "field": "ikpu",
      "detail": "IKPU kodi kiritilmagan",
      "created_at": "2026-09-24T10:00:00+05:00"
    }
  ]
}
get/products/deletedAsosiy

Tombstones since a time

AsosiyRuxsat: catalog:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Soft-deleted products (deleted_at) since since — deltas never carry deletions.

Parametrlar (6)
Javob 200 · TombstonePage
  • itemsTombstone[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/products/deleted?since=<since>" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "seller_sku": "A-199",
      "external_id": null,
      "deleted_at": "2026-09-23T18:00:00+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
post/products/{id}/publishAsosiy

Publish

AsosiyRuxsat: catalog:writeNarx: write-rate · 1

gateBlocksActivation. Pending shop ⇒ 200 with hold.reason=shop_not_activated (goes live on documents approval). A gate failure ⇒ 400 invalid_body with details[] (the same issues /issues lists). A price below the catalogue floor ⇒ 202 held_for_review (price_floor; activation waits for an approver). Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · ProductState
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • holdobject | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
  • 202Held for review — nothing written.
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/publish" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "active",
  "hold": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/products/{id}/delistAsosiy

Delist (hide) — never a hard delete

AsosiyRuxsat: catalog:writeNarx: write-rate · 1

Sets the product delisted (the portal's delist). Delisting more than 30 % of the shop's live products at once ⇒ 202 held_for_review (delist_30pct). There is no hard delete on this API. Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · ProductState
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • holdobject | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
  • 202Held for review — nothing written.
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/delist" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "delisted",
  "hold": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/products/batchAsosiy

Batch create/update (async job)

AsosiyRuxsat: catalog:writeNarx: write-rate · 10

≤ 100 commands ⇒ 202 + a job; poll GET /jobs/{id} (≥ 5 s; Retry-After set). ≤ 2 running jobs per key, ≤ 20/day per shop. Results use the per-line shape. Kill switch: writes_enabled.

Parametrlar (6)
Soʻrov tanasi · BatchRequest
  • itemsBatchCommand[]majburiy
    BatchCommand[]
    • opstringmajburiy

      create · update

    • product_idstring (uuid)

      Required when op=update.

    • createProductCreate
      ProductCreate
      • titleLocalizedTextmajburiy

        jsonb {uz,ru,en}; readers fall back uz → ru → en.

      • descriptionLocalizedText

        jsonb {uz,ru,en}; readers fall back uz → ru → en.

      • category_idstring (uuid)majburiy
      • brandstring
      • seller_skustringmajburiy
      • barcodestring
      • external_idstring

        Your system's id, e.g. 1c:0f2a….

      • price_uzsinteger (int64)majburiy
      • compare_at_uzsinteger | null
      • stockintegermajburiy
      • ikpustring
      • package_codestring
      • image_urlsstring (uri)[]
      • video_urlstring (uri)
      • attributesobject
      • variantsVariantInput[]
      • publishboolean

        Ask to publish after create; a pending shop's product is held until documents approval.

    • updateProductUpdate

      Partial update: an absent field is unchanged.

      ProductUpdate
      • titleLocalizedText

        jsonb {uz,ru,en}; readers fall back uz → ru → en.

      • descriptionLocalizedText

        jsonb {uz,ru,en}; readers fall back uz → ru → en.

      • category_idstring (uuid)
      • brandstring
      • barcodestring
      • external_idstring
      • price_uzsinteger (int64)
      • compare_at_uzsinteger | null
      • stockinteger

        Refused (details[].code=stock_not_editable) when the product has variants — use POST /stock with variant_id.

      • ikpustring
      • package_codestring
      • image_urlsstring (uri)[]
      • video_urlstring | null
      • attributesobject
      • versionstring

        Optional optimistic lock; stale ⇒ 409 version_conflict.

Javob 202 · JobAccepted
  • job_idstring (uuid)majburiy
  • status"pending"majburiy
  • linksobjectmajburiy
Javob kodlari
  • 202Accepted
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/products/batch" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"op":"create"}]}'
Javob misoli
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
post/media/upload-urlAsosiy

Presigned media upload

AsosiyRuxsat: catalog:writeNarx: write-rate · 1

Presigned R2 PUT (≤ 60/min, ≤ 20 MB). No Idempotency-Key: a second call just mints another URL. Kill switch: writes_enabled.

Parametrlar (3)
Soʻrov tanasi · MediaUploadRequest
  • content_typestringmajburiy

    image/jpeg · image/png · image/webp · video/mp4

  • size_bytesintegermajburiy

    ≤ 20 MB; signed into the PUT so storage enforces it.

Javob 200 · MediaUploadUrl
  • keystringmajburiy
  • upload_urlstring (uri)majburiy

    Presigned PUT — send the exact bytes, no Authorization header.

  • public_urlstring (uri)majburiy

    Use this in image_urls.

  • expires_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/media/upload-url" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content_type":"image/jpeg","size_bytes":1}'
Javob misoli
{
  "key": "p/0198f3a2/01997b40.webp",
  "upload_url": "https://r2.dona.im/ozb-media/p/0198f3a2/01997b40.webp?X-Amz-Expires=900&X-Amz-Signature=3f9a0c",
  "public_url": "https://media.dona.im/p/0198f3a2/01997b40.webp",
  "expires_at": "2026-09-24T14:20:12+05:00"
}

Stock & prices

3 amal

Absolute, bulk, guarded (catalog.ApplyGuardedStockPrice).

get/stockAsosiy

Stock, SKU-level

AsosiyRuxsat: catalog:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

One row per product without variants, one per variant otherwise. cursor or 0-based page (slower).

Parametrlar (9)
Javob 200 · StockLineViewPage
  • itemsStockLineView[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/stock" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "variant_id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
      "seller_sku": "A-200-R-M",
      "barcode": "4780000000029",
      "external_id": null,
      "quantity": 4,
      "version": "2026-09-24T13:59:41.120318+05:00",
      "updated_at": "2026-09-24T13:59:41+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
post/stockAsosiy

Set absolute stock (≤ 1 000 lines)

AsosiyRuxsat: catalog:stockNarx: write-rate · ceil(lines/10)

Synchronous, through catalog.ApplyGuardedStockPrice. 200 with per-line results — the request is refused whole only for shape/budget (400/413/422). ?atomic=true = all-or-nothing (any held line ⇒ 202 for the batch). |Δ| > 10× and > 1 000, or zeroing > 50 % of lines ⇒ held. One object ≤ 1 write / 10 s ⇒ line error: object_cooldown. Kill switch: writes_enabled.

Parametrlar (7)
Soʻrov tanasi · StockRequest
  • itemsStockLine[]majburiy
    StockLine[]
    • product_idstring (uuid)
    • seller_skustring
    • barcodestring
    • external_idstring
    • variant_idstring (uuid)
    • quantityintegermajburiy

      ABSOLUTE stock (not a delta).

    • versionstring

      Optional; stale ⇒ line error: version_conflict.

    • warehousestring

      Reserved — one stock location per shop. Any value ⇒ the whole request 422 warehouse_unsupported.

Javob 200 · BulkResult
  • resultsLineResult[]majburiy
  • summaryobjectmajburiy
  • dry_runbooleanmajburiy
Javob kodlari
  • 200OK
  • 202<code>atomic=true</code> and a line was held — nothing written.
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/stock" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"product_id":"0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e","quantity":12}]}'
Javob misoli
{
  "results": [
    {
      "index": 0,
      "status": "ok",
      "seller_sku": "A-100",
      "quantity": 12,
      "version": "2026-09-24T14:05:12.004211+05:00"
    },
    {
      "index": 1,
      "status": "error",
      "barcode": "4780000000012",
      "variant_id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
      "error": "version_conflict",
      "message": "Mahsulot boshqa yozuv bilan oʻzgargan."
    },
    {
      "index": 2,
      "status": "held",
      "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "approval_id": "01997b31-1b2c-7d3e-8f4a-5b6c7d8e9f0a",
      "rule": "stock_jump_10x"
    }
  ],
  "summary": {
    "ok": 1,
    "error": 1,
    "held": 1
  },
  "dry_run": false
}
post/pricesAsosiy

Set absolute prices (≤ 1 000 lines)

AsosiyRuxsat: catalog:stockNarx: write-rate · ceil(lines/10)

As POST /stock. Price < catalog.price_floor_uzs (1 000) or > 100× drop vs current/last-sold ⇒ held; compare_at_uzs must exceed price_uzs. Kill switch: writes_enabled.

Parametrlar (7)
Soʻrov tanasi · PriceRequest
  • itemsPriceLine[]majburiy
    PriceLine[]
    • product_idstring (uuid)
    • seller_skustring
    • barcodestring
    • external_idstring
    • variant_idstring (uuid)
    • price_uzsinteger (int64)majburiy

      ABSOLUTE price.

    • compare_at_uzsinteger | null

      Must exceed price_uzs; null clears.

    • versionstring
Javob 200 · BulkResult
  • resultsLineResult[]majburiy
  • summaryobjectmajburiy
  • dry_runbooleanmajburiy
Javob kodlari
  • 200OK
  • 202<code>atomic=true</code> and a line was held — nothing written.
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/prices" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"product_id":"0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e","price_uzs":1}]}'
Javob misoli
{
  "results": [
    {
      "index": 0,
      "status": "ok",
      "seller_sku": "A-100",
      "price_uzs": 189000,
      "compare_at_uzs": 229000,
      "version": "2026-09-24T14:05:12.004211+05:00"
    },
    {
      "index": 1,
      "status": "held",
      "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "approval_id": "01997b31-1b2c-7d3e-8f4a-5b6c7d8e9f0a",
      "rule": "price_floor"
    }
  ],
  "summary": {
    "ok": 1,
    "error": 0,
    "held": 1
  },
  "dry_run": false
}

Orders

13 amal

The orders:read projection has no buyer PII; orders:pii (ADVANCED, sk) adds it.

get/ordersAsosiy

List orders (no buyer PII)

AsosiyRuxsat: orders:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1; unfiltered (no updated_since) above 2/min ×3

The orders:read projection. status takes the portal buckets (all, pending, paid, ready_to_ship, to_ship, shipped, delivered, cancelled, return_refund). from/to span ≤ 90 d, to exclusive.

Parametrlar (11)
  • cursorquery · string
  • pagequery · integer
  • limitquery · integer
  • updated_sincequery · string
  • statusquery · string

    Portal bucket.

  • schemequery · string

    Derived fulfilment scheme.

  • fromquery · string (date-time)

    created_at ≥ from.

  • toquery · string (date-time)

    created_at < to.

  • Accept-Languageheader · string
  • Dona-Sellerheader · string (uuid)
  • X-Dona-Integrationheader · string
Javob 200 · OrderPage
  • itemsOrder[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/orders" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
      "order_code": "AB1758704000XZ",
      "status": "paid",
      "payment_status": "paid",
      "payment_method": "cod",
      "scheme": "third_party",
      "total_uzs": 259000,
      "accepted_at": null,
      "declined_at": null,
      "shipped_at": null,
      "delivered_at": null,
      "cancelled_by": null,
      "decline_reason_code": null,
      "accept_deadline": "2026-09-25T09:12:00+05:00",
      "ship_by_deadline": null,
      "items": [
        {
          "id": "01997b2e-41c1-7a22-9b3c-4d5e6f7a8b9c",
          "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
          "variant_id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
          "seller_sku": "A-200-R-M",
          "title": {
            "uz": "Erkaklar futbolkasi, paxta",
            "ru": "Футболка мужская, хлопок"
          },
          "quantity": 2,
          "cancelled_quantity": 0,
          "unit_price_uzs": 129500
        }
      ],
      "meta": {
        "uzum_status": "CREATED"
      },
      "created_at": "2026-09-24T09:12:00+05:00",
      "updated_at": "2026-09-24T09:12:31+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/orders/{id}Asosiy

Get an order (PII only with orders:pii)

AsosiyRuxsat: orders:readNarx: key-rate · 1

orders:read ⇒ Order. A key that ALSO holds orders:pii (ADVANCED, sk only, S4) gets OrderWithPii (adds recipient) and the call is logged pii=true. When the orders:pii door would refuse this request (the shop is not ADVANCED now, or the key's recipient is third-party — D7) the ORDER is still answered, without recipient, and Dona-API-Warn: recipient withheld: <tier_required|pii_third_party_pending_counsel|…> says why (C59).

Parametrlar (4)
Javob 200 · Order | OrderWithPii

Quyidagilardan biri: Order · OrderWithPii

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "order_code": "AB1758704000XZ",
  "status": "paid",
  "payment_status": "paid",
  "payment_method": "cod",
  "scheme": "third_party",
  "total_uzs": 259000,
  "accepted_at": null,
  "declined_at": null,
  "shipped_at": null,
  "delivered_at": null,
  "cancelled_by": null,
  "decline_reason_code": null,
  "accept_deadline": "2026-09-25T09:12:00+05:00",
  "ship_by_deadline": null,
  "items": [
    {
      "id": "01997b2e-41c1-7a22-9b3c-4d5e6f7a8b9c",
      "product_id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
      "variant_id": "0199612e-8a0c-7d11-a0b2-9e8f7a6b5c4d",
      "seller_sku": "A-200-R-M",
      "title": {
        "uz": "Erkaklar futbolkasi, paxta",
        "ru": "Футболка мужская, хлопок"
      },
      "quantity": 2,
      "cancelled_quantity": 0,
      "unit_price_uzs": 129500
    }
  ],
  "meta": {
    "uzum_status": "CREATED"
  },
  "created_at": "2026-09-24T09:12:00+05:00",
  "updated_at": "2026-09-24T09:12:31+05:00",
  "recipient": {
    "name": "Dilnoza K.",
    "phone": "+998901234567",
    "address": "Toshkent sh., Yunusobod t., 11-kvartal, 5-uy, 23-xonadon"
  }
}
get/orders/{id}/timelineAsosiy

Order timeline

AsosiyRuxsat: orders:readNarx: key-rate · 1

order_events in order.

Parametrlar (4)
Javob 200 · OrderTimeline
  • order_idstring (uuid)majburiy
  • itemsOrderTimelineEntry[]majburiy
Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/timeline" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "items": [
    {
      "id": "01997b2e-7f00-7123-8456-789abcdef012",
      "type": "placed",
      "actor": "buyer",
      "note": null,
      "occurred_at": "2026-09-24T09:12:00+05:00"
    },
    {
      "id": "01997b2f-0102-7345-9678-9abcdef01234",
      "type": "paid",
      "actor": "system",
      "note": null,
      "occurred_at": "2026-09-24T09:12:31+05:00"
    }
  ]
}
post/orders/{id}/acceptAsosiy

Accept

AsosiyRuxsat: orders:writeNarx: write-rate · 1

The intake.go accept body, extracted. Needs a pickup address. 409: order_not_acceptable, no_pickup_address. Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/accept" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "paid",
  "payment_status": "paid",
  "accepted_at": "2026-09-24T14:05:12+05:00",
  "shipped_at": null,
  "cancelled_by": null,
  "decline_reason_code": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/readyAsosiy

Mark ready to ship

AsosiyRuxsat: orders:writeNarx: write-rate · 1

Sets ready_to_ship. 409: order_not_shippable. Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ready" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "ready_to_ship",
  "payment_status": "paid",
  "accepted_at": "2026-09-24T14:05:12+05:00",
  "shipped_at": null,
  "cancelled_by": null,
  "decline_reason_code": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/shipAsosiy

Ship

AsosiyRuxsat: orders:writeNarx: write-rate · 1

409: order_not_shippable, order_awaiting_courier. Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ship" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "shipped",
  "payment_status": "paid",
  "accepted_at": "2026-09-24T14:05:12+05:00",
  "shipped_at": "2026-09-24T14:05:12+05:00",
  "cancelled_by": null,
  "decline_reason_code": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/handoverAsosiy

Hand over to the courier

AsosiyRuxsat: orders:writeNarx: write-rate · 1

sellerMayTransitionSQL rules. 409: order_not_shippable. Kill switch: writes_enabled.

Parametrlar (7)
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/handover" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true"
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "shipped",
  "payment_status": "paid",
  "accepted_at": "2026-09-24T14:05:12+05:00",
  "shipped_at": "2026-09-24T14:05:12+05:00",
  "cancelled_by": null,
  "decline_reason_code": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/notesAsosiy

Add a seller note

AsosiyRuxsat: orders:writeNarx: write-rate · 1

Appends to order_notes. Kill switch: writes_enabled.

Parametrlar (7)
Soʻrov tanasi · NoteRequest
  • textstringmajburiy
Javob 201 · NoteCreated
  • idstring (uuid)majburiy
  • order_idstring (uuid)majburiy
  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 201Created
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/notes" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"text":"string"}'
Javob misoli
{
  "id": "01997b2f-0102-7345-9678-9abcdef01234",
  "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "created_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/declineKengaytirilgan

Decline (before acceptance) — money-reversing

KengaytirilganRuxsat: orders:cancelNarx: write-rate · 1

An order NOT YET ACCEPTED. The portal decline's own body (order.DeclineOrderInTx) on the marketplace pool, in the write pipeline (stamped transaction, wallet-cutover fence): restock, the buyer's kiwi/vouchers/delivery money back, the declined/seller timeline row; the card refund at the provider and the buyer notice run after the commit (never on a dry run). The reason is stored in decline_reason_code. ADVANCED, derived on THIS request (a documents-waived or downgraded shop is 403 tier_required). 400 invalid_decline_reason (details[comment: required] for other without words); 409 order_not_acceptable (an accepted or closed order — the portal names it order_not_decidable; cancel an accepted one), order_has_active_return. Another shop's order ⇒ 404. Kill switch: writes_enabled. Served by the marketplace process only: a SERVER_ROLE=seller-api server answers 503 role_unavailable (after the key, scope and tier; before the dry-run flag, the switch, the body and the idempotency claim — nothing changes; D3).

Parametrlar (7)
Soʻrov tanasi · DeclineRequest
  • reasonstringmajburiy

    Uzum subset (OUT_OF_STOCK, OUT_OF_PACKAGE, OUT_OF_TIME, OTHER) mapped onto the native declineReasons, OR a native lowercase code. OTHER/other needs comment. Unknown ⇒ 400 invalid_decline_reason.

    OUT_OF_STOCK · OUT_OF_PACKAGE · OUT_OF_TIME · OTHER · out_of_stock · inventory_mismatch · product_damaged · store_unavailable · cannot_fulfill_in_time · duplicate_order · fraud_suspected · other

  • commentstring
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/decline" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"reason":"OUT_OF_STOCK"}'
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "cancelled",
  "payment_status": "paid",
  "accepted_at": null,
  "shipped_at": null,
  "cancelled_by": "seller",
  "decline_reason_code": "out_of_stock",
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/orders/{id}/cancelKengaytirilgan

Cancel (after acceptance) — money-reversing

KengaytirilganRuxsat: orders:cancelNarx: write-rate · 1

An ACCEPTED order: the portal seller-cancel's own statements (order.SellerCancelOrderTx) — same reasons (C15) and money effects as decline. The reason is stored in the order's cancel_reason (with the comment), NOT in decline_reason_code, which stays null (C52); the cancelled/seller timeline row, the card refund and the buyer notice run after the commit. 409 order_not_cancellable — a delivered or cancelled order, or one NOT YET ACCEPTED (details[{field:"status", code:"not_accepted"}]: decline it) — and order_has_active_return. Kill switch: writes_enabled. 503 role_unavailable from a SERVER_ROLE=seller-api server, as decline.

Parametrlar (7)
Soʻrov tanasi · DeclineRequest
  • reasonstringmajburiy

    Uzum subset (OUT_OF_STOCK, OUT_OF_PACKAGE, OUT_OF_TIME, OTHER) mapped onto the native declineReasons, OR a native lowercase code. OTHER/other needs comment. Unknown ⇒ 400 invalid_decline_reason.

    OUT_OF_STOCK · OUT_OF_PACKAGE · OUT_OF_TIME · OTHER · out_of_stock · inventory_mismatch · product_damaged · store_unavailable · cannot_fulfill_in_time · duplicate_order · fraud_suspected · other

  • commentstring
Javob 200 · OrderTransition
  • idstring (uuid)majburiy
  • statusstringmajburiy
  • payment_statusstringmajburiy
  • accepted_atstring | nullmajburiy
  • shipped_atstring | nullmajburiy
  • cancelled_bystring | nullmajburiy

    seller · buyer · system

  • decline_reason_codestring | nullmajburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/cancel" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Dona-Dry-Run: true" \
  -H "Content-Type: application/json" \
  -d '{"reason":"OUT_OF_STOCK"}'
Javob misoli
{
  "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "cancelled",
  "payment_status": "paid",
  "accepted_at": "2026-09-24T14:05:12+05:00",
  "shipped_at": null,
  "cancelled_by": "seller",
  "decline_reason_code": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
get/orders/{id}/label.pdfKengaytirilgan

Shipping label (PDF, contains PII)

KengaytirilganRuxsat: orders:piiNarx: key-rate · 1

The portal's sticker for one order: prints the buyer's name, phone and address. sk keys only (orders:pii on any other kind ⇒ 403 insufficient_scope + details[scope_not_allowed_for_kind]); ADVANCED now (403 tier_required); a key minted for a THIRD-PARTY recipient ⇒ 403 tier_required + details[pii_recipient: pii_third_party_pending_counsel] (D7). Logged pii=true (always journaled, never sampled); never stored by the API. Normal key-rate bucket (C54). 409 no_tracking_number (+ orders: the order codes without a carrier number yet — print later), no_items_selected, all_items_delayed (nothing left to put in the parcel) (C53). A server draws at most 2 documents at once: past that 429 api_busy (Dona-Rate-Limited-Reason: global, Retry-After: 2) before any read, and a batch is not charged.

Parametrlar (4)
Javob 200

Javob turi: application/pdf

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/label.pdf" \
  -H "Authorization: Bearer $DONA_KEY"
get/orders/{id}/invoice.pdfKengaytirilgan

Invoice (PDF, contains PII)

KengaytirilganRuxsat: orders:piiNarx: key-rate · 1

The invoice for one order, drawn as a PDF from the SAME figures as the portal's invoice page (one loader). Doors, 409s and the 429 api_busy bound as label.pdf (C53, C54). ⚠ PII set WIDER than the label's: like the portal's invoice it prints the PURCHASER's account name and phone (the buyer who is invoiced) — on a gift order that is not the recipient the label and the recipient block name (Form A Q12 states both).

Parametrlar (4)
Javob 200

Javob turi: application/pdf

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/invoice.pdf" \
  -H "Authorization: Bearer $DONA_KEY"
post/orders/labelsKengaytirilgan

Labels for ≤ 100 orders (one PDF)

KengaytirilganRuxsat: orders:piiNarx: key-rate · 10

A read with a body — no Idempotency-Key. Any foreign/missing id ⇒ 404 not_found for the whole call. Doors and 409s as label.pdf (C53); no_tracking_number names every offending order. Cost 10 on the key-rate bucket (C54), charged only once the batch holds a drawing slot (429 api_busy as label.pdf).

Parametrlar (3)
Soʻrov tanasi · LabelsRequest
  • order_idsstring (uuid)[]majburiy
Javob 200

Javob turi: application/pdf

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/orders/labels" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order_ids":["0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e"]}'

Returns

2 amal

Read-only in v1.

get/returnsAsosiy

List returns

AsosiyRuxsat: returns:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Read-only in v1 — approving a return is orders.refund, never issuable.

Parametrlar (7)
Javob 200 · ReturnPage
  • itemsReturn[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/returns" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997c10-5d2e-7f30-8c41-5a6b7c8d9e0f",
      "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
      "status": "requested",
      "type": "return",
      "reason_code": "wrong_size",
      "refund_uzs": 129500,
      "due_at": "2026-09-27T12:00:00+05:00",
      "items": [
        {
          "order_item_id": "01997b2e-41c1-7a22-9b3c-4d5e6f7a8b9c",
          "quantity": 1
        }
      ],
      "reason_text": null,
      "created_at": "2026-09-24T12:00:00+05:00",
      "updated_at": "2026-09-24T12:00:00+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/returns/{id}Asosiy

Get a return

AsosiyRuxsat: returns:readNarx: key-rate · 1

Includes the buyer's reason_text (detail only).

Parametrlar (4)
Javob 200 · Return
  • idstring (uuid)majburiy
  • order_idstring (uuid)majburiy
  • statusstringmajburiy

    requested · approved · refunded · rejected · disputed · closed

  • typestringmajburiy
  • reason_codestringmajburiy
  • refund_uzsinteger (int64)majburiy

    Integer soʻm (no decimals).

  • due_atstring | nullmajburiy
  • itemsobject[]majburiy
  • reason_textstring | nullmajburiy

    Buyer-authored; detail only (null on lists).

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/returns/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997c10-5d2e-7f30-8c41-5a6b7c8d9e0f",
  "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "status": "requested",
  "type": "return",
  "reason_code": "wrong_size",
  "refund_uzs": 129500,
  "due_at": "2026-09-27T12:00:00+05:00",
  "items": [
    {
      "order_item_id": "01997b2e-41c1-7a22-9b3c-4d5e6f7a8b9c",
      "quantity": 1
    }
  ],
  "reason_text": "Oʻlcham kichik keldi.",
  "created_at": "2026-09-24T12:00:00+05:00",
  "updated_at": "2026-09-24T12:00:00+05:00"
}

Health

3 amal

Account health, metrics, verification verdicts.

get/account/healthAsosiy

Account health summary

AsosiyRuxsat: health:readNarx: key-rate · 1

accounthealth.BuildSummary projection.

Parametrlar (3)
Javob 200 · HealthSummary
  • health_labelstringmajburiy

    good · fair · poor

  • reputation_scorenumber | nullmajburiy
  • penalty_pointsintegermajburiy
  • penalty_maxintegermajburiy
  • punishment_activebooleanmajburiy
  • suppressionobject | nullmajburiy
  • metricsMetric[]majburiy
  • open_attentionintegermajburiy
  • computed_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/account/health" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "health_label": "good",
  "reputation_score": 87.4,
  "penalty_points": 0,
  "penalty_max": 12,
  "punishment_active": false,
  "suppression": null,
  "metrics": [
    {
      "id": "late_shipment_rate",
      "group": "fulfilment",
      "current_value": "3.1%",
      "target": "< 10%",
      "applied_to": [
        "own_fleet",
        "third_party"
      ],
      "passing": true,
      "has_detail": true
    }
  ],
  "open_attention": 3,
  "computed_at": "2026-09-24T14:05:12+05:00"
}
get/account/metrics/{metric_id}Asosiy

One metric with weekly history

AsosiyRuxsat: health:readNarx: key-rate · 1

Unknown metric id ⇒ 404 not_found.

Parametrlar (4)
Javob 200 · MetricDetail

Javob turi: application/json

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/account/metrics/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "late_shipment_rate",
  "group": "fulfilment",
  "current_value": "3.1%",
  "target": "< 10%",
  "applied_to": [
    "own_fleet",
    "third_party"
  ],
  "passing": true,
  "has_detail": true,
  "history": [
    {
      "week_start": "2026-09-14",
      "value": 0.031
    }
  ]
}
get/account/verificationAsosiy

The three verdicts and what ADVANCED still needs

AsosiyRuxsat: health:readNarx: key-rate · 1

From seller_api_shop_v.

Parametrlar (3)
Javob 200 · Verification
  • statusstringmajburiy

    pending · approved · suspended · blocked · restricted · closed

  • documents_statusstringmajburiy
  • kyc_statusstringmajburiy
  • documents_waivedbooleanmajburiy
  • bank_confirmedbooleanmajburiy
  • can_sellbooleanmajburiy
  • tierstringmajburiy

    Key tier, derived per request (never cached): ADVANCED = kyc approved AND documents approved (a waiver never counts) AND shop approved AND no active punishment; seller_api_access.tier_override may lower or raise it but never lifts a sanction.

    basic · advanced

  • tier_missingstring[]majburiy

    Empty when ADVANCED. A waiver never satisfies documents_approved.

    kyc_approved · documents_approved · shop_approved · no_active_punishment

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/account/verification" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "status": "approved",
  "documents_status": "waived",
  "kyc_status": "approved",
  "documents_waived": true,
  "bank_confirmed": true,
  "can_sell": true,
  "tier": "basic",
  "tier_missing": [
    "documents_approved"
  ]
}

Attention

3 amal

The seller-keyed "errors, warnings, attention required" channel (seller_attention_items).

get/attentionAsosiy

Errors, warnings, attention required

AsosiyRuxsat: attention:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Sorted action_required desc, severity desc, deadline_at nulls last, opened_at desc. Array filters repeat the key (kind=stock_out&kind=stock_low).

Parametrlar (12)
Javob 200 · AttentionPage
  • itemsAttentionItem[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

  • countsAttentionCountsmajburiy
Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/attention" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997b30-0a1b-7c2d-9e3f-4a5b6c7d8e9f",
      "kind": "order_accept_due",
      "severity": "high",
      "action_required": true,
      "resolves_by": "deadline",
      "subject": {
        "type": "order",
        "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b"
      },
      "title": {
        "uz": "Buyurtmani qabul qiling",
        "ru": "Примите заказ",
        "en": "Accept the order"
      },
      "body": {
        "uz": "Qabul muddati 2 soatdan kam qoldi.",
        "ru": "До срока принятия меньше 2 часов.",
        "en": "Less than 2 h left to accept."
      },
      "deadline_at": "2026-09-25T09:12:00+05:00",
      "action_url": "/orders/01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
      "opened_at": "2026-09-25T07:12:05+05:00",
      "updated_at": "2026-09-25T07:12:05+05:00",
      "acked_at": null,
      "acked_via": null,
      "resolved_at": null,
      "resolved_reason": null
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "counts": {
    "open": 3,
    "action_required": 2,
    "by_severity": {
      "low": 1,
      "medium": 0,
      "high": 2,
      "critical": 0
    }
  }
}
get/attention/{id}Asosiy

One attention item

AsosiyRuxsat: attention:readNarx: key-rate · 1

—

Parametrlar (4)
Javob 200 · AttentionItem
  • idstring (uuid)majburiy
  • kindstringmajburiy

    documents_pending · documents_rejected · kyc_reopened · bank_pending · agreement_owed · shop_suspended · shop_restricted · shop_blocked · suppressed · penalty_points · product_held · product_rejected · product_violation · listing_issue · order_accept_due · order_ship_overdue · return_decision_due · stock_out · stock_low · health_warning · health_suppressed · live_ban · live_strike · write_held · key_expiring · key_suspended · key_dormant · ip_blocked · webhook_failing · api_anomaly

  • severitystringmajburiy

    low · medium · high · critical

  • action_requiredbooleanmajburiy

    True only when the SELLER can clear it.

  • resolves_bystringmajburiy

    condition · decision · deadline · expiry · ack

  • subjectobject | nullmajburiy
  • titleLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • bodyLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • deadline_atstring | nullmajburiy
  • action_urlstring | nullmajburiy

    Portal deep link.

  • opened_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • acked_atstring | nullmajburiy
  • acked_viastring | nullmajburiy

    portal · api · mcp

  • resolved_atstring | nullmajburiy
  • resolved_reasonstring | nullmajburiy

    condition_cleared · decided · deadline_passed · expired · acked

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/attention/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997b30-0a1b-7c2d-9e3f-4a5b6c7d8e9f",
  "kind": "order_accept_due",
  "severity": "high",
  "action_required": true,
  "resolves_by": "deadline",
  "subject": {
    "type": "order",
    "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b"
  },
  "title": {
    "uz": "Buyurtmani qabul qiling",
    "ru": "Примите заказ",
    "en": "Accept the order"
  },
  "body": {
    "uz": "Qabul muddati 2 soatdan kam qoldi.",
    "ru": "До срока принятия меньше 2 часов.",
    "en": "Less than 2 h left to accept."
  },
  "deadline_at": "2026-09-25T09:12:00+05:00",
  "action_url": "/orders/01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "opened_at": "2026-09-25T07:12:05+05:00",
  "updated_at": "2026-09-25T07:12:05+05:00",
  "acked_at": null,
  "acked_via": null,
  "resolved_at": null,
  "resolved_reason": null
}
post/attention/{id}/ackAsosiy

Acknowledge

AsosiyRuxsat: attention:readNarx: write-rate · 1

Idempotent by nature (no Idempotency-Key). Ack never clears a condition; only ip_blocked and api_anomaly resolve on ack (resolved_reason=acked). Counts against the writes/min bucket; not gated by writes_enabled.

Parametrlar (4)
Javob 200 · AttentionItem
  • idstring (uuid)majburiy
  • kindstringmajburiy

    documents_pending · documents_rejected · kyc_reopened · bank_pending · agreement_owed · shop_suspended · shop_restricted · shop_blocked · suppressed · penalty_points · product_held · product_rejected · product_violation · listing_issue · order_accept_due · order_ship_overdue · return_decision_due · stock_out · stock_low · health_warning · health_suppressed · live_ban · live_strike · write_held · key_expiring · key_suspended · key_dormant · ip_blocked · webhook_failing · api_anomaly

  • severitystringmajburiy

    low · medium · high · critical

  • action_requiredbooleanmajburiy

    True only when the SELLER can clear it.

  • resolves_bystringmajburiy

    condition · decision · deadline · expiry · ack

  • subjectobject | nullmajburiy
  • titleLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • bodyLocalizedTextmajburiy

    jsonb {uz,ru,en}; readers fall back uz → ru → en.

  • deadline_atstring | nullmajburiy
  • action_urlstring | nullmajburiy

    Portal deep link.

  • opened_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • acked_atstring | nullmajburiy
  • acked_viastring | nullmajburiy

    portal · api · mcp

  • resolved_atstring | nullmajburiy
  • resolved_reasonstring | nullmajburiy

    condition_cleared · decided · deadline_passed · expired · acked

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/attention/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ack" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997b30-0a1b-7c2d-9e3f-4a5b6c7d8e9f",
  "kind": "order_accept_due",
  "severity": "high",
  "action_required": true,
  "resolves_by": "deadline",
  "subject": {
    "type": "order",
    "id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b"
  },
  "title": {
    "uz": "Buyurtmani qabul qiling",
    "ru": "Примите заказ",
    "en": "Accept the order"
  },
  "body": {
    "uz": "Qabul muddati 2 soatdan kam qoldi.",
    "ru": "До срока принятия меньше 2 часов.",
    "en": "Less than 2 h left to accept."
  },
  "deadline_at": "2026-09-25T09:12:00+05:00",
  "action_url": "/orders/01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
  "opened_at": "2026-09-25T07:12:05+05:00",
  "updated_at": "2026-09-25T07:12:05+05:00",
  "acked_at": "2026-09-24T14:05:12+05:00",
  "acked_via": "api",
  "resolved_at": null,
  "resolved_reason": null
}

Events

1 amal

/events — the primary, pollable change feed.

get/eventsAsosiy

The change feed (primary channel)

AsosiyRuxsat: events:readNarx: key-rate · 1

Poll ?cursor=<last event id>; omit it for the oldest retained event or pass since. Events are readable 30 days from occurred_at. A cursor older than the window ⇒ 400 invalid_body with details[{field:"cursor",code:"cursor_expired"}] and meta.oldest_event_id: full-reconcile via updated_since, then restart there. Ordered by id (near, not exact, occurred_at order). limit ≤ 200.

Parametrlar (8)
  • cursorquery · string (uuid)

    Last event id seen.

  • sincequery · string

    ISO 8601 or epoch-ms; ignored when cursor is set.

  • typesquery · string[]

    Repeatable; exact names or prefixes (order.*).

  • limitquery · integer

    Default 100, max 200.

  • If-None-Matchheader · string
  • Accept-Languageheader · string
  • Dona-Sellerheader · string (uuid)
  • X-Dona-Integrationheader · string
Javob 200 · EventPage
  • itemsEvent[]majburiy
  • next_cursorstring | nullmajburiy

    The id of the LAST event returned (or your own cursor echoed when items is empty). Store it after your batch commits; never null once you have seen an event.

  • has_morebooleanmajburiy

    True ⇒ call again immediately.

  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/events" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997b2e-7f00-7123-8456-789abcdef012",
      "type": "order.paid",
      "occurred_at": "2026-09-24T09:12:31+05:00",
      "seller_id": "0198f3a2-6c1d-7b40-8e55-2a9c3d4e5f60",
      "api_version": "v1",
      "data": {
        "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
        "status": "paid",
        "payment_status": "paid",
        "payment_method": "card",
        "scheme": "own_fleet",
        "total_uzs": 259000,
        "accept_deadline": "2026-09-25T09:12:00+05:00",
        "ship_by_deadline": null,
        "updated_at": "2026-09-24T09:12:31+05:00"
      },
      "links": {
        "self": "/seller-api/v1/orders/01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b"
      }
    }
  ],
  "next_cursor": "01997b2e-7f00-7123-8456-789abcdef012",
  "has_more": false
}

Webhooks

9 amal

Signed push of the same events (Standard Webhooks).

get/webhooksAsosiy

List endpoints (≤ 5)

AsosiyRuxsat: webhooks:manageNarx: key-rate · 1

Never a secret.

Parametrlar (3)
Javob 200 · WebhookPage
  • itemsWebhook[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/webhooks" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
      "url": "https://erp.example.uz/dona/webhooks",
      "event_types": [
        "order.*",
        "attention.opened"
      ],
      "status": "active",
      "failing_since": null,
      "disabled_reason": null,
      "consecutive_failures": 0,
      "last_delivered_at": "2026-09-24T09:12:33+05:00",
      "success_rate_24h": 1,
      "secret_rotating_until": null,
      "created_at": "2026-09-22T10:00:00+05:00",
      "updated_at": "2026-09-24T09:12:33+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
post/webhooksAsosiy

Register an endpoint (secret shown once)

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

Dona sends a signed ping immediately; your endpoint must answer 2xx within 1 s or the create is 422 webhook_url_invalid. ≤ 5 endpoints per shop: a 6th is 422 webhook_url_invalid with details[{field:"url",code:"endpoint_limit"}]. Kill switch: webhooks_enabled.

Parametrlar (4)
Soʻrov tanasi · WebhookCreate
  • urlstring (uri)majburiy

    https:// with a CA-signed certificate; private, loopback, link-local and metadata addresses are refused.

  • event_typesstring[]

    Exact event names or prefixes (order.*); ["*"] (or omitted on create) = every event.

Javob 201 · WebhookWithSecret

Javob turi: application/json

Javob kodlari
  • 201Created
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/webhooks" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.uz/dona-webhook"}'
Javob misoli
{
  "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
  "url": "https://erp.example.uz/dona/webhooks",
  "event_types": [
    "order.*",
    "attention.opened"
  ],
  "status": "active",
  "failing_since": null,
  "disabled_reason": null,
  "consecutive_failures": 0,
  "last_delivered_at": "2026-09-24T09:12:33+05:00",
  "success_rate_24h": 1,
  "secret_rotating_until": null,
  "created_at": "2026-09-22T10:00:00+05:00",
  "updated_at": "2026-09-24T09:12:33+05:00",
  "secret": "whsec_MfKQ9r2ysWbG2xZt8k1r5sFh3Dq0Vv7L"
}
get/webhooks/{id}Asosiy

Get an endpoint

AsosiyRuxsat: webhooks:manageNarx: key-rate · 1

—

Parametrlar (4)
Javob 200 · Webhook
  • idstring (uuid)majburiy
  • urlstring (uri)majburiy
  • event_typesstring[]majburiy

    Exact event names or prefixes (order.*); ["*"] (or omitted on create) = every event.

  • statusstringmajburiy

    active · paused · disabled

  • failing_sincestring | nullmajburiy
  • disabled_reasonstring | nullmajburiy

    ladder_exhausted · success_rate · owner · staff · ssrf_recheck

  • consecutive_failuresintegermajburiy
  • last_delivered_atstring | nullmajburiy
  • success_rate_24hnumber | nullmajburiy
  • secret_rotating_untilstring | nullmajburiy

    While set, deliveries carry two signatures.

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
  "url": "https://erp.example.uz/dona/webhooks",
  "event_types": [
    "order.*",
    "attention.opened"
  ],
  "status": "active",
  "failing_since": null,
  "disabled_reason": null,
  "consecutive_failures": 0,
  "last_delivered_at": "2026-09-24T09:12:33+05:00",
  "success_rate_24h": 1,
  "secret_rotating_until": null,
  "created_at": "2026-09-22T10:00:00+05:00",
  "updated_at": "2026-09-24T09:12:33+05:00"
}
patch/webhooks/{id}Asosiy

Change url / event types / pause

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

A new url is re-verified with a ping (same 1 s rule).

Parametrlar (5)
Soʻrov tanasi · WebhookUpdate
  • urlstring (uri)
  • event_typesstring[]

    Exact event names or prefixes (order.*); ["*"] (or omitted on create) = every event.

  • statusstring

    paused = seller-side pause (deliveries accrue 30 d); active resumes a paused endpoint. A disabled endpoint is re-enabled only by a successful /ping.

    active · paused

Javob 200 · Webhook
  • idstring (uuid)majburiy
  • urlstring (uri)majburiy
  • event_typesstring[]majburiy

    Exact event names or prefixes (order.*); ["*"] (or omitted on create) = every event.

  • statusstringmajburiy

    active · paused · disabled

  • failing_sincestring | nullmajburiy
  • disabled_reasonstring | nullmajburiy

    ladder_exhausted · success_rate · owner · staff · ssrf_recheck

  • consecutive_failuresintegermajburiy
  • last_delivered_atstring | nullmajburiy
  • success_rate_24hnumber | nullmajburiy
  • secret_rotating_untilstring | nullmajburiy

    While set, deliveries carry two signatures.

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X PATCH "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.uz/dona-webhook","event_types":["string"],"status":"active"}'
Javob misoli
{
  "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
  "url": "https://erp.example.uz/dona/webhooks",
  "event_types": [
    "order.*",
    "attention.opened"
  ],
  "status": "paused",
  "failing_since": null,
  "disabled_reason": null,
  "consecutive_failures": 0,
  "last_delivered_at": "2026-09-24T09:12:33+05:00",
  "success_rate_24h": 1,
  "secret_rotating_until": null,
  "created_at": "2026-09-22T10:00:00+05:00",
  "updated_at": "2026-09-24T09:12:33+05:00"
}
delete/webhooks/{id}Asosiy

Remove an endpoint

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

Soft delete (deleted_at); delivery history is kept its 30 days. Repeating it is 404 not_found.

Parametrlar (4)
Javob 204
Javob kodlari
  • 204Deleted
Soʻrov
curl -sS -X DELETE "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
post/webhooks/{id}/pingAsosiy

Re-run the verification ping

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

≤ 10/min per endpoint. A 2xx within 1 s re-enables a disabled or auto-paused endpoint and closes its breaker. No Idempotency-Key.

Parametrlar (4)
Javob 200 · WebhookPing
  • okbooleanmajburiy
  • response_statusinteger | nullmajburiy
  • response_msinteger | nullmajburiy
  • failurestring | nullmajburiy

    timeout · tls · dns · status

  • webhookWebhookmajburiy
Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ping" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "ok": true,
  "response_status": 200,
  "response_ms": 184,
  "failure": null,
  "webhook": {
    "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
    "url": "https://erp.example.uz/dona/webhooks",
    "event_types": [
      "order.*",
      "attention.opened"
    ],
    "status": "active",
    "failing_since": null,
    "disabled_reason": null,
    "consecutive_failures": 0,
    "last_delivered_at": "2026-09-24T09:12:33+05:00",
    "success_rate_24h": 1,
    "secret_rotating_until": null,
    "created_at": "2026-09-22T10:00:00+05:00",
    "updated_at": "2026-09-24T09:12:33+05:00"
  }
}
post/webhooks/{id}/rotate-secretAsosiy

Rotate the signing secret (24 h dual signing)

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

New whsec_ shown once; for 24 h both secrets sign (webhook-signature: v1,<new> v1,<old>).

Parametrlar (5)
Javob 200 · WebhookWithSecret

Javob turi: application/json

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/rotate-secret" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Javob misoli
{
  "id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
  "url": "https://erp.example.uz/dona/webhooks",
  "event_types": [
    "order.*",
    "attention.opened"
  ],
  "status": "active",
  "failing_since": null,
  "disabled_reason": null,
  "consecutive_failures": 0,
  "last_delivered_at": "2026-09-24T09:12:33+05:00",
  "success_rate_24h": 1,
  "secret_rotating_until": "2026-09-25T14:05:12+05:00",
  "created_at": "2026-09-22T10:00:00+05:00",
  "updated_at": "2026-09-24T09:12:33+05:00",
  "secret": "whsec_2b9Lr8QpXw4Tn6Yc1Hs0Kd5Fa3Gm7Ze9"
}
get/webhooks/{id}/deliveriesAsosiy

Delivery log (30 d)

AsosiyRuxsat: webhooks:manageNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Newest first. status=dead is the dead-letter view.

Parametrlar (8)
  • idpath · string (uuid)majburiy

    Resource id (UUIDv7). A foreign or missing id is always 404 not_found.

  • statusquery · string

    Exact.

  • event_idquery · string (uuid)

    Exact.

  • cursorquery · string
  • limitquery · integer
  • Accept-Languageheader · string
  • Dona-Sellerheader · string (uuid)
  • X-Dona-Integrationheader · string
Javob 200 · DeliveryPage
  • itemsDelivery[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/deliveries" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997b33-3d4e-7f5a-8b6c-7d8e9f0a1b2c",
      "webhook_id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
      "event_id": "01997b2e-7f00-7123-8456-789abcdef012",
      "event_type": "order.paid",
      "attempt": 3,
      "status": "failed",
      "next_attempt_at": "2026-09-24T10:12:36+05:00",
      "delivered_at": null,
      "response_status": 502,
      "response_ms": 1840,
      "error": "status_502",
      "occurred_at": "2026-09-24T09:42:31+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
post/webhooks/{id}/deliveries/{delivery_id}/redeliverAsosiy

Redeliver one delivery

AsosiyRuxsat: webhooks:manageNarx: write-rate · 1

Fresh timestamp + signature, same webhook-id; a new attempt chain. ≤ 100/hour/endpoint. An event older than 30 d ⇒ 404 not_found.

Parametrlar (6)
Javob 200 · Delivery
  • idstring (uuid)majburiy
  • webhook_idstring (uuid)majburiy
  • event_idstring (uuid)majburiy
  • event_typestringmajburiy

    The glossary event catalogue. New types are additive.

    order.created · order.paid · order.accepted · order.declined · order.ready · order.shipped · order.delivered · order.cancelled · order.line_cancelled · order.accept_due_soon · order.ship_overdue · return.requested · return.status_changed · product.published · product.held · product.rejected · product.demoted · product.violation · product.deleted · stock.low · stock.out · write.held · write.approved · write.rejected · write.expired · account.status_changed · account.documents_decided · account.kyc_reopened · account.suppressed · account.health_changed · account.agreement_owed · live.access_changed · live.strike · attention.opened · attention.resolved · key.expiring · key.suspended · key.unsuspended · webhook.failing · webhook.disabled · ping

  • attemptintegermajburiy
  • statusstringmajburiy

    queued · delivered · failed · dead

  • next_attempt_atstring | nullmajburiy
  • delivered_atstring | nullmajburiy
  • response_statusinteger | nullmajburiy
  • response_msinteger | nullmajburiy
  • errorstring | nullmajburiy
  • occurred_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/deliveries/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/redeliver" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Javob misoli
{
  "id": "01997b2f-0102-7345-9678-9abcdef01234",
  "webhook_id": "01997b32-2c3d-7e4f-9a5b-6c7d8e9f0a1b",
  "event_id": "01997b2e-7f00-7123-8456-789abcdef012",
  "event_type": "order.paid",
  "attempt": 1,
  "status": "queued",
  "next_attempt_at": "2026-09-24T14:05:12+05:00",
  "delivered_at": null,
  "response_status": null,
  "response_ms": null,
  "error": null,
  "occurred_at": "2026-09-24T09:42:31+05:00"
}

Taxonomy

4 amal

Platform-owned categories, brands, IKPU (T4).

get/categoriesAsosiy

Category tree (platform-owned)

AsosiyRuxsat: anyNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Walk the 5-level tree by parent_id (omit it for the roots).

Parametrlar (6)
Javob 200 · CategoryPage
  • itemsCategory[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/categories" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01972a10-1111-7aaa-8bbb-0123456789ab",
      "parent_id": "01972a10-0000-7aaa-8bbb-0123456789aa",
      "name": {
        "uz": "Futbolkalar",
        "ru": "Футболки",
        "en": "T-shirts"
      },
      "level": 3,
      "is_leaf": true
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/categories/{id}/requirementsAsosiy

What a product in this leaf needs

AsosiyRuxsat: anyNarx: key-rate · 1

Per-category requirements + listing policy.

Parametrlar (4)
Javob 200 · CategoryRequirements
  • category_idstring (uuid)majburiy
  • statusstringmajburiy
  • listing_policystringmajburiy

    open default; approval_required, licensed, restricted, prohibited.

  • is_leafbooleanmajburiy
  • can_listbooleanmajburiy

    status=active AND is_leaf AND listing_policy <> prohibited.

  • min_imagesintegermajburiy
  • requires_dimensionsbooleanmajburiy
  • requires_brandbooleanmajburiy
  • requires_size_chartbooleanmajburiy
  • commission_pctnumber | nullmajburiy
  • attributesCategoryAttribute[]majburiy
Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/categories/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/requirements" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "category_id": "01972a10-1111-7aaa-8bbb-0123456789ab",
  "status": "active",
  "listing_policy": "open",
  "is_leaf": true,
  "can_list": true,
  "min_images": 4,
  "requires_dimensions": false,
  "requires_brand": false,
  "requires_size_chart": true,
  "commission_pct": 12,
  "attributes": [
    {
      "key": "size",
      "label": {
        "uz": "Oʻlcham",
        "ru": "Размер",
        "en": "Size"
      },
      "value_type": "enum",
      "requirement": "required",
      "is_filterable": true,
      "is_variant_axis": true,
      "options": [
        {
          "code": "m",
          "label": {
            "uz": "M",
            "ru": "M",
            "en": "M"
          }
        }
      ]
    }
  ]
}
get/brandsAsosiy

Brand search

AsosiyRuxsat: anyNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Prefix search.

Parametrlar (6)
Javob 200 · BrandPage
  • itemsBrand[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/brands" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01972b20-2222-7ccc-9ddd-0123456789cd",
      "name": "Bahor",
      "protection": "open"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/ikpuAsosiy

IKPU (tax classifier) search

AsosiyRuxsat: anyNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

From the local tasnif copy.

Parametrlar (6)
Javob 200 · IkpuPage
  • itemsIkpu[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/ikpu?q=<q>" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "code": "06109100001000000",
      "name": "Paxtali trikotaj futbolkalar",
      "active": true,
      "packages": [
        {
          "code": "1520227",
          "name": "dona"
        }
      ]
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Jobs

4 amal

Async exports and product batches.

post/exports/productsAsosiy

Export products (async)

AsosiyRuxsat: catalog:readNarx: key-rate · 10

CSV or JSONL. ≤ 2 running jobs per key, ≤ 20/day per shop. Not gated by writes_enabled.

Parametrlar (4)
Soʻrov tanasi · ExportRequest
  • formatstring

    csv · jsonl

  • filtersobject

    Same meaning as the list filters; from/to only on orders (≤ 90 d).

    object
    • statusstring
    • updated_sincestring
    • fromstring (date-time)
    • tostring (date-time)
Javob 202 · JobAccepted
  • job_idstring (uuid)majburiy
  • status"pending"majburiy
  • linksobjectmajburiy
Javob kodlari
  • 202Accepted
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/exports/products" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"format":"jsonl","filters":{"status":"string","updated_since":"string","from":"2026-09-24T09:00:00+05:00"}}'
Javob misoli
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
post/exports/ordersAsosiy

Export orders (async, no PII)

AsosiyRuxsat: orders:readNarx: key-rate · 10

The orders:read projection only — an export never carries recipient.

Parametrlar (4)
Soʻrov tanasi · ExportRequest
  • formatstring

    csv · jsonl

  • filtersobject

    Same meaning as the list filters; from/to only on orders (≤ 90 d).

    object
    • statusstring
    • updated_sincestring
    • fromstring (date-time)
    • tostring (date-time)
Javob 202 · JobAccepted
  • job_idstring (uuid)majburiy
  • status"pending"majburiy
  • linksobjectmajburiy
Javob kodlari
  • 202Accepted
Soʻrov
curl -sS -X POST "https://api.dona.im/seller-api/v1/exports/orders" \
  -H "Authorization: Bearer $DONA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"format":"jsonl","filters":{"status":"string","updated_since":"string","from":"2026-09-24T09:00:00+05:00"}}'
Javob misoli
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
get/jobs/{id}Asosiy

Poll a job

AsosiyRuxsat: anyNarx: key-rate · 1

Readable by any key of the shop that holds the scope the job's kind needs (catalog:read for export_products, orders:read for export_orders, catalog:write for products_batch); otherwise 404 not_found. Poll ≥ 5 s (Retry-After is set while pending/running). After expires_at (7 d) ⇒ 404 not_found.

Parametrlar (4)
Javob 200 · Job
  • idstring (uuid)majburiy
  • kindstringmajburiy

    export_products · export_orders · products_batch

  • statusstringmajburiy

    pending · running · ready · failed

  • progressobjectmajburiy
  • file_urlstring | nullmajburiy

    GET /jobs/{id}/download?token=… — the token is valid 15 min from this response and only for a key of this shop (never a public or pre-signed object URL); re-read the job for a fresh one.

  • file_expires_atstring | nullmajburiy
  • resultsLineResult[] | nullmajburiy

    products_batch only: the per-line shape.

  • errorstring | nullmajburiy

    Our code only.

  • created_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • finished_atstring | nullmajburiy
  • expires_atstring (date-time)majburiy

    Row + file swept after this (7 d); then 404 not_found.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/jobs/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "kind": "export_orders",
  "status": "ready",
  "progress": {
    "done": 1240,
    "total": 1240
  },
  "file_url": "https://api.dona.im/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d/download?token=v1.1790327512.3q2-7wAAAAB3j5E1c0x9fQ",
  "file_expires_at": "2026-09-24T14:17:10+05:00",
  "results": null,
  "error": null,
  "created_at": "2026-09-24T14:01:00+05:00",
  "finished_at": "2026-09-24T14:02:10+05:00",
  "expires_at": "2026-10-01T14:01:00+05:00"
}
get/jobs/{id}/downloadAsosiy

Download an export's file

AsosiyRuxsat: anyNarx: key-rate · 1

What a ready export's file_url points at. Needs BOTH a key of the job's shop that holds the scope the job's kind needs (any key of the shop — the file is the shop's; a key of another shop is 404 not_found whatever token it carries) AND the job's own token from file_url, valid 15 min (401 download_token_invalid when absent, forged or another job's; 401 download_token_expired past its time — re-read GET /jobs/{id} for a fresh one). The file is never on a public origin — it is in Dona's private exports bucket (302 to a presigned GET valid 15 min, issued only after both checks above — D24, 2026-09-26) or, where the bucket is not configured, in the database (200 with the bytes). Follow the redirect WITHOUT the Authorization header (the signed URL carries its own authority; most HTTP clients drop the header on a cross-host redirect). Swept with its job after expires_at (7 d) ⇒ 404 not_found. Not gated by writes_enabled.

Parametrlar (5)
  • idpath · string (uuid)majburiy

    Resource id (UUIDv7). A foreign or missing id is always 404 not_found.

  • tokenquery · stringmajburiy

    The download token file_url carries (v1.<unix expiry>.<mac>), bound to this job and this shop.

  • Accept-Languageheader · string
  • Dona-Sellerheader · string (uuid)
  • X-Dona-Integrationheader · string
Javob 200

Javob turi: application/x-ndjson, text/csv

Javob kodlari
  • 200The file, as an attachment (<code>Content-Disposition</code>, <code>X-Content-Type-Options: nosniff</code>).
  • 302The file is in Dona's private exports bucket — <code>Location</code> is a presigned GET of exactly this job's object, valid 15 minutes, that downloads it as an attachment (<code>dona-&lt;products|orders&gt;-&lt;job id&gt;.&lt;jsonl|csv&gt;</code>). Issued only after the key and token checks; never cacheable.
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/jobs/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/download?token=<token>" \
  -H "Authorization: Bearer $DONA_KEY"

Finance

2 amal

Balance and settlement lines (ADVANCED).

get/finance/balanceKengaytirilgan

Balance

KengaytirilganRuxsat: finance:readNarx: key-rate · 1

The wallet's answer for the key's shop, asked as the shop's CURRENT owner (the portal's own finance bridge), projected field by field. Never error-copied. No requisites, PAN or statement URLs. The wallet unreachable, erroring or not knowing the shop ⇒ 503 wallet_unavailable (Retry-After: 30), never its body (C57). Served by the marketplace process only: a SERVER_ROLE=seller-api server answers 503 role_unavailable before any read (D3).

Parametrlar (3)
Javob 200 · Balance
  • available_uzsinteger (int64)majburiy

    Integer soʻm (no decimals).

  • held_uzsinteger (int64)majburiy

    Integer soʻm — earned, still inside the admin hold (not yet withdrawable).

  • expected_uzsinteger (int64)majburiy

    Integer soʻm — orders in flight, not yet earned.

  • currency"UZS"majburiy
  • as_ofstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/finance/balance" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "available_uzs": 12450000,
  "held_uzs": 3100000,
  "expected_uzs": 5400000,
  "currency": "UZS",
  "as_of": "2026-09-24T14:05:12+05:00"
}
get/finance/settlementsKengaytirilgan

Settlement lines

KengaytirilganRuxsat: finance:readNarx: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

The wallet statement's lines for the shop, newest first (asked as the shop's current owner). memo is the line's machine kind from the wallet's CLOSED vocabulary (sale_income, escrow_hold, escrow_release, refund, return, adjustment, withdrawal, withdrawal_failed, fee, commission, hold_placed, hold_captured, hold_released, cod_collected, cod_remitted, transfer) or other — never the wallet's free-text title (C57). A line whose id or txn_id is not a UUID, or a next_cursor that is not an opaque ≤ 512-character URL-safe token, refuses the whole page. 503 wallet_unavailable / role_unavailable as /finance/balance.

Parametrlar (8)
Javob 200 · SettlementPage
  • itemsSettlement[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/finance/settlements" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "01997d00-1234-7abc-8def-0123456789a0",
      "txn_id": "01997e00-5678-7abc-9def-0123456789b1",
      "direction": "credit",
      "amount_uzs": 233100,
      "signed_amount_uzs": 233100,
      "order_id": "01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b",
      "memo": "sale_income",
      "created_at": "2026-09-24T14:05:12+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Keys

1 amal

Read-only list of the shop's keys.

get/keysAsosiy

The shop's keys (read-only; management is portal-only)

AsosiyRuxsat: anyNarx: key-rate · 1

Metadata only — never a secret, never last_used_ip. Mint/rotate/revoke live in the seller portal.

Parametrlar (3)
Javob 200 · KeyPage
  • itemsKey[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/keys" \
  -H "Authorization: Bearer $DONA_KEY"
Javob misoli
{
  "items": [
    {
      "id": "0199760c-2f4b-7a3e-9d21-5c8e4b1f0a37",
      "name": "billz-prod",
      "kind": "sk",
      "env": "live",
      "prefix": "dona_sk_live_3fK",
      "last4": "q9Zx",
      "scopes": [
        "catalog:read",
        "catalog:stock",
        "orders:read"
      ],
      "state": "active",
      "expiring_soon": false,
      "expires_at": "2027-09-24T00:00:00+05:00",
      "last_used_at": "2026-09-24T14:00:03+05:00",
      "ip_allow": [],
      "rotated_from": null,
      "overlap_until": null,
      "suspended_until": null,
      "created_at": "2026-09-24T11:02:00+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Meta

5 amal

Public: ping, status, changelog, this spec, llms.txt.

get/pingOchiq

Liveness (key optional)

OchiqRuxsat: noneNarx: edge · 0

Public. Without Authorization it answers authenticated:false. With a key the key is fully verified — a bad key is 401, never a silent false.

Parametrlar (2)
Javob 200 · Ping
  • ok"pong"majburiy
  • timestring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

  • authenticatedbooleanmajburiy

    True only when a valid key was presented.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/ping"
Javob misoli
{
  "ok": "pong",
  "time": "2026-09-24T14:05:12+05:00",
  "authenticated": true
}
get/statusOchiq

Service status

OchiqRuxsat: noneNarx: edge · 0

Public; edge-cacheable 60 s; linked from every 503's doc_url.

Parametrlar (2)
Javob 200 · Status
  • statusstringmajburiy

    operational · degraded · outage

  • componentsobjectmajburiy
  • incidentsobject[]majburiy
  • updated_atstring (date-time)majburiy

    ISO 8601 with offset (Tashkent +05:00 on output).

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/status"
Javob misoli
{
  "status": "operational",
  "components": {
    "api": "operational",
    "mcp": "disabled",
    "webhooks": "operational",
    "events": "operational"
  },
  "incidents": [],
  "updated_at": "2026-09-24T14:05:12+05:00"
}
get/changelogOchiq

Changelog (JSON, or RSS with Accept)

OchiqRuxsat: noneNarx: edge · 0

Public. Accept: application/rss+xml returns RSS. Backed by seller_api_changelog (migration 0487, S4): published entries only, newest first; the first row is the v1 seed. Written only from Dona Control (admin-contract §7). The seller portal reads the same body at GET /api/v1/sellers/me/api-docs/changelog (portal-contract §6a) — this tree sends no CORS grant. Cached public, max-age=300 with Vary: Accept-Language, Accept on BOTH formats, and a weak ETag over the exact bytes: If-None-Match with it answers 304 and no body.

Parametrlar (4)
Javob 200 · ChangelogEntryPage
  • itemsChangelogEntry[]majburiy
  • next_cursorstring | nullmajburiy

    Pass back as ?cursor=. null when has_more is false.

  • has_morebooleanmajburiy
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/changelog"
Javob misoli
{
  "items": [
    {
      "id": "01997e00-0000-7000-8000-000000000001",
      "version": "v1",
      "kind": "added",
      "title": {
        "uz": "Dona API v1",
        "ru": "Dona API v1",
        "en": "Dona API v1"
      },
      "body": {
        "uz": "Birinchi versiya: kalitlar, mahsulotlar, qoldiq va narxlar, buyurtmalar, qaytarishlar, hodisalar, eʼtibor talab qiladigan holatlar, webhooklar va MCP.",
        "ru": "Первая версия: ключи, товары, остатки и цены, заказы, возвраты, события, требующие внимания состояния, вебхуки и MCP.",
        "en": "The first version: keys, products, stock and prices, orders, returns, events, attention items, webhooks and MCP."
      },
      "affects_scopes": [],
      "sunset_at": null,
      "published_at": "2026-09-24T00:00:00+05:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/openapi.jsonOchiq

This document

OchiqRuxsat: noneNarx: edge · 0

OpenAPI 3.1, public, Cache-Control: public, max-age=300.

Parametrlar (2)
Javob 200 · object

Javob turi: application/json

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/openapi.json"
get/llms.txtOchiq

llms.txt index for AI agents

OchiqRuxsat: noneNarx: edge · 0

Plain-text index of the docs + spec links (llms-full.txt beside it).

Parametrlar (2)
Javob 200

Javob turi: text/plain

Javob kodlari
  • 200OK
Soʻrov
curl -sS "https://api.dona.im/seller-api/v1/llms.txt"

0308

Chegaralar

Chegaralar IP boʻyicha emas, tasdiqlangan kalit va doʻkon boʻyicha hisoblanadi. Quyida standart qiymatlar; kalitingizga amal qiladiganlari GET /me → limits da.

Chegaralar
ChegaraAsosiy skKengaytirilgan skAgent ak
Soʻrov / daqiqa (kalit)300 · burst 60600 · burst 12060 · burst 20
Soʻrov / kun (kalit)100 000250 00020 000
Yozuv / daqiqa6012010
Yozuv / kun20 00050 0002 000
Bir vaqtdagi soʻrovlar484
Soʻrov / daqiqa (doʻkon, barcha kalitlar)9001 800—
  • Bitta mahsulot zaxirasi yoki narxi — 10 soniyada 1 yozuv (object_cooldown).
  • Ommaviy yozuv ≤ 1 000 qator; tana ≤ 256 KiB (ommaviy — 4 MiB). Tavsiya: 100–300 qator.
  • Sahifa limit ≤ 100 (/events da ≤ 200). If-None-Match → 304 yarim narx.
  • Bizning 429/503 va 5xx javoblar hisobga olinmaydi va kalitni toʻxtatmaydi.

Dona-Rate-Limited-Reason qiymatlari:

  • key-rate
  • write-rate
  • seller-rate
  • concurrency
  • object-cooldown
  • app-rate
  • global
  • suspended

0408

Xato kodlari

59 kod

Har bir xato bir xil konvert: error — barqaror kod, message — Accept-Language boʻyicha tarjima.

Kod boʻyicha tarmoqlang, hech qachon message boʻyicha emas.

Xato konverti
{
  "error": "insufficient_scope",
  "message": "Bu amal uchun ruxsat yetarli emas.",
  "request_id": "req_01997b2e-9a8b-7c6d-8e5f-4a3b2c1d0e9f",
  "details": [],
  "doc_url": "https://dona.uz/uz/developers/errors#insufficient_scope",
  "required_scope": "orders:write"
}

202Accepted

400Bad Request

  • invalid_body

    malformed JSON, a missing Idempotency-Key, validation (details[] carries field codes such as ikpu_required, cursor_expired), a dry_run / Dona-Dry-Run that is not the literal true/false (details[{field, code:"invalid"}], C51), a vendor-app install key without Dona-Seller (details[{field:"Dona-Seller", code:"required"}], S6) or with a repeated / non-canonical one (code:"invalid"), or an op-specific 400 (invalid_decline_reason)

  • invalid_decline_reason

    see POST /orders/{id}/decline

  • request_state_invalid

    the MCP door — see MCP

401Unauthorized

Shuningdek a seller/app/staff JWT on this tree

403Forbidden

  • insufficient_scope

    +required_scope; also a scope in disabled_scopes

  • tier_required

    +scope; derived on every request; also a key minted for a third-party orders:pii recipient — details[pii_recipient: pii_third_party_pending_counsel], D7, C59

  • key_suspended

    +suspended_until, Retry-After, Dona-Rate-Limited-Reason: suspended

  • api_blocked
  • ip_not_allowed

    judged on the trusted client IP only

  • seller_not_approved

    shop closed/blocked/suspended/restricted

  • not_a_seller

    never on this tree; the portal's owner doors

  • app_frozen

    S6: every key of a frozen vendor app, from the next request

  • agreement_required

    +accept_url: the shop owner has not accepted the CURRENT Annex 2 «API and automated access» — the version in force or, while none is, the earliest announced; accepted once in Settings › API, then every door admits the key again. Checked after the sanctions, before the scopes

  • request_state_foreign

    the MCP door — see MCP

404Not Found

  • not_found

    every missing OR foreign id (never 403: no existence oracle)

409Conflict

Shuningdek a replay of a rejected held write

410Gone

413Content Too Large

422Unprocessable Content

429Too Many Requests

Shuningdek Always a JSON body + Retry-After from the origin (an edge 429 from Cloudflare has NO body — treat it as Retry-After: 60). Costs 0 and never counts toward the breaker. rate_limited is also the pre-auth ADDRESS guard, answered before the key is read: an address over 1 200 requests a minute that were not admitted (no key, a public route, a malformed, unknown or refused key — admitted requests never count), or one tarpitted at 60/min for 15 min after ≥ 20 unknown keys in a minute. No key is ever suspended by traffic that did not prove it

Shuningdek Cloudflare edge, per-IP 60/min on public routes. No JSON body (the edge eats it) — treat as Retry-After: 60

500Internal Server Error

  • internal_error

    details are in the redacted error copy, never here. Costs 0

503Service Unavailable

  • auth_unavailable

    key lookup failed — fail closed

  • limits_unavailable

    limiter blind on a write/MCP call, or a kill switch is off: enabled, writes_enabled, webhooks_enabled; Retry-After: 30

  • attention_busy

    an acknowledgement that resolves an item could not take the attention writer lock within 2 s — nothing was written; retry after Retry-After: 2

  • wallet_unavailable

    /finance/*: the wallet could not answer for the shop; Retry-After: 30; its body is never relayed or error-copied — S4, C57

  • role_unavailable

    + served_by: "marketplace": a SERVER_ROLE=seller-api server does not serve decline / cancel or /finance/*; answered before any read or write, nothing changed; no Retry-After — D3

  • intent_unavailable

    the MCP door — see MCP

Shuningdek Costs 0

0508

Hodisalar va webhooklar

41 hodisa turi

Oʻzgarishlar bitta oqimda. 1C kabi faqat oʻzi soʻrov yubora oladigan tizimlar uchun soʻrov-oqim asosiy kanal.

Soʻrov bilan olish

get/events
GET /events
curl -sS "https://api.dona.im/seller-api/v1/events?cursor=$LAST_EVENT_ID&limit=200" \
  -H "Authorization: Bearer $DONA_KEY"

Webhooklar — Standard Webhooks imzosi

Yetkazish qoidalari

One event per POST (≤ 20 KB), at-least-once, unordered. Reply 2xx within 10 s (ack first, process after); 3xx is a failure; 410 Gone disables the endpoint. Retry ladder: immediate · 5 s · 5 m · 30 m · 2 h · 5 h · 10 h · 14 h · 20 h · 24 h (≈ 75 h, ±10 % jitter).

Sarlavhalar

webhook-id
= the event id. Your idempotency key — dedupe for 24 h.
webhook-timestamp
Unix seconds. Reject if |now − ts| > 300 s. A redelivery carries a FRESH timestamp.
webhook-signature
Standard Webhooks: space-delimited v1,<base64 HMAC-SHA256(base64decode(secret after whsec_), id + "." + ts + "." + rawBody)>; two entries during a 24 h rotation.
Dona-Request-Id
Correlates with the delivery log.

Hodisa turlari

  • order.createdorder.paidorder.acceptedorder.declinedorder.readyorder.shippedorder.deliveredorder.cancelledorder.line_cancelledorder.accept_due_soonorder.ship_overdue
  • return.requestedreturn.status_changed
  • product.publishedproduct.heldproduct.rejectedproduct.demotedproduct.violationproduct.deleted
  • stock.lowstock.out
  • write.heldwrite.approvedwrite.rejectedwrite.expired
  • account.status_changedaccount.documents_decidedaccount.kyc_reopenedaccount.suppressedaccount.health_changedaccount.agreement_owed
  • live.access_changedlive.strike
  • attention.openedattention.resolved
  • key.expiringkey.suspendedkey.unsuspended
  • webhook.failingwebhook.disabled
  • ping

Quyidagi imzo haqiqiy: u sayt yigʻilayotganda koʻrsatilgan demo-sir va tana bilan hisoblangan, kod uni aynan shunday tasdiqlaydi.

POST https://example.uz/dona-webhook
POST https://example.uz/dona-webhook

webhook-id: 01997b2e-7f00-7123-8456-789abcdef012
webhook-timestamp: 1790223151
webhook-signature: v1,CFjQ7u8l+tPV5Wzhawj/Hx9iWYx9sM6mcFJu4wsQxpQ=

# demo secret — NOT a real one
# whsec_ZG9uYS1kZW1vLXNlY3JldC1ub3QtYS1yZWFsLW9uZSE=

{"id":"01997b2e-7f00-7123-8456-789abcdef012","type":"order.created","occurred_at":"2026-09-24T09:12:31+05:00","seller_id":"0198f3a2-6c1d-7b40-8e55-2a9c3d4e5f60","api_version":"v1","data":{"order_id":"01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b","status":"paid","payment_status":"paid","payment_method":"card","scheme":"own_fleet","total_uzs":259000,"accept_deadline":"2026-09-25T09:12:00+05:00","ship_by_deadline":null,"updated_at":"2026-09-24T09:12:31+05:00"},"links":{"self":"/seller-api/v1/orders/01997b2e-41c0-7e6f-8a9b-0c1d2e3f4a5b"}}
Imzoni tekshirish · Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'

// secret = "whsec_…" from POST /webhooks; body = the RAW request body (a string, not parsed JSON)
export function verify(secret, headers, body) {
  const id = headers['webhook-id'], ts = headers['webhook-timestamp']
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false
  const key = Buffer.from(secret.slice('whsec_'.length), 'base64')
  const want = createHmac('sha256', key).update(`${id}.${ts}.${body}`).digest()
  return headers['webhook-signature'].split(' ').some((entry) => {
    const [v, sig] = entry.split(',')
    const got = Buffer.from(sig ?? '', 'base64')
    return v === 'v1' && got.length === want.length && timingSafeEqual(got, want)
  })
}
Imzoni tekshirish · Python
import base64, hashlib, hmac, time

def verify(secret: str, headers: dict, body: bytes) -> bool:
    wid, ts = headers["webhook-id"], headers["webhook-timestamp"]
    if abs(time.time() - int(ts)) > 300:
        return False
    key = base64.b64decode(secret.removeprefix("whsec_"))
    want = hmac.new(key, f"{wid}.{ts}.".encode() + body, hashlib.sha256).digest()
    for entry in headers["webhook-signature"].split(" "):
        v, _, sig = entry.partition(",")
        if v == "v1" and hmac.compare_digest(base64.b64decode(sig), want):
            return True
    return False

0608

MCP — AI-agentlar

Claude Code, Cursor, Codex va boshqa AI-agentlar doʻkoningiz bilan MCP orqali ishlay oladi. Har bir chaqiruv jurnalga yoziladi.

Agent kaliti bilan agent doʻkonni oʻqiydi: mahsulotlar, buyurtmalar, hodisalar, e’tibor talab qiladigan holatlar, hisob holati va shu hujjatlar. Yozish vositalari — qoldiq, narx, buyurtmani joʻnatish va bekor qilish — faqat kengaytirilgan darajadagi doʻkonda va yozuvlar yoqilgan paytda chiqadi. Birinchi chaqiruvda hech narsa yozilmaydi: oʻzgarish avval tasdiqlanadi — agentning oʻz tasdiqlash oynasida yoki doʻkon egasi tomonidan Sozlamalar › API › Kutilayotgan yozuvlar boʻlimida.

Endpoint
https://api.dona.im/seller-api/mcp
Himoyalangan resurs metamaʼlumoti (RFC 9728)
/.well-known/oauth-protected-resource/seller-api/mcp

Agent kaliti (dona_ak_live_…, ruxsat mcp) Sozlamalar › API boʻlimida yaratiladi.

Claude Code uchun bitta buyruq
claude mcp add --transport http dona https://api.dona.im/seller-api/mcp --header "Authorization: Bearer ${DONA_AGENT_KEY}"

OAuth 2.1 — claude.ai va ChatGPT ulagichlari

Kalitni qoʻlda kiritib boʻlmaydigan ulagichlar OAuth 2.1 orqali kiradi: ulanishni doʻkon egasi sotuvchi kabinetida tasdiqlaydi (Sozlamalar › API › Ulangan ilovalar) va istalgan vaqtda uzib qoʻyishi mumkin. OAuth orqali agent faqat oʻqiy oladi.

Avtorizatsiya serveri
https://auth.dona.im

0708

SDK

TypeScript, Python, Go, PHP va C# uchun SDKlar shu shartnomadan avtomatik yaratiladi.

  • TypeScript
  • Python
  • Go
  • PHP
  • C#
  • Dastlabki versiya 0.1.0

SDKlar ochiq GitHub repozitoriysida. Paketlar reyestrlarga (npm, PyPI, NuGet, Packagist) hali chiqarilmagan — hozircha toʻgʻridan-toʻgʻri repozitoriydan oʻrnating.

  • TypeScript

    Talab: Node ≥ 20

    Repozitoriyni klonlash kerak

    Oʻrnatish
    git clone https://github.com/ozbuz/dona-api.git && cd dona-api/sdks/typescript && npm install
    Oʻrnatish
    npm install ../dona-api/sdks/typescript
  • Python

    Talab: ≥ 3.11
    Oʻrnatish
    pip install "dona-api @ git+https://github.com/ozbuz/dona-api.git@main#subdirectory=sdks/python"
  • Go

    Talab: ≥ 1.26
    Oʻrnatish
    go get github.com/ozbuz/dona-api/sdks/go@main
  • PHP

    Talab: ≥ 8.1, Guzzle 7

    Repozitoriyni klonlash kerak

    Oʻrnatish
    git clone https://github.com/ozbuz/dona-api.git && cd your-project && composer config repositories.dona-api path ../dona-api/sdks/php && composer require ozbuz/dona-api:*@dev
  • C#

    Talab: .NET 10

    Repozitoriyni klonlash kerak

    Oʻrnatish
    git clone https://github.com/ozbuz/dona-api.git && dotnet add reference path/to/dona-api/sdks/csharp/src/Dona.Api/Dona.Api.csproj

0808

Oʻzgarishlar va holat

Har bir oʻzgarish sanasi, turi va taʼsir qiladigan ruxsatlar bilan eʼlon qilinadi.

Kalit kerakmi?

Kalitni doʻkon egasi sotuvchi kabinetida yaratadi: Sozlamalar › API. Kalit faqat bir marta koʻrsatiladi.

Xaridor yoki sotuvchi sifatida savolingiz bormi? Yordam markaziga oʻting.

Dona ilovasini yuklab olish uchun skanerlangDona ilovasini yuklab oling

QR-kodni koʻrsatish
Dona ilovasini yuklab olish uchun QR-kod

Telefon kamerasi bilan skanerlang