Начать продаватьУстановить

OpenAPI 3.1REST · v1

Dona API

Подключите магазин к своей системе: товары, остатки и цены, заказы, здоровье аккаунта и события — через один REST API. Для 1С, МойСклад, BILLZ, SmartUp, Linko и AI-агентов.

Ключ создаёт владелец магазина в кабинете продавца: Настройки › API. Ключ показывается один раз.

Базовый адрес
https://api.dona.im/seller-api/v1
Типы ключей
  • dona_sk_live_…ключ интеграции — для ERP, 1С, POS и вашей системы
  • dona_ak_live_…ключ AI-агента — только через MCP
  • dona_it_live_…токен установки приложения — скоро

API открывается поэтапно. Что работает сейчас — на странице «Статус», что добавлено — в «Изменениях».

Первый запросget/me
curl
curl -sS https://api.dona.im/seller-api/v1/me \
  -H "Authorization: Bearer $DONA_KEY"
200Пример ответа
{
  "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"
}
Содержание

0108

Быстрый старт

4 шага

Четыре шага: ключ, первый запрос, безопасная пробная запись и лента событий.

  1. Создайте ключ

    Кабинет продавца › Настройки › API › Создать ключ. Отметьте только нужные права (scope). Перед созданием первого ключа владелец магазина должен принять условия Приложения 2 (API и автоматизированный доступ) в кабинете продавца.

    Пока владелец магазина не примет действующее Приложение 2, каждый вход — REST, MCP и OAuth — отвечает 403 agreement_required с accept_url: страницей кабинета, где его принимают.

  2. Проверьте, кто вы

    GET /me возвращает ключ, магазин, уровень (Базовый/Расширенный), права и текущие лимиты.

    GET /me
    curl -sS https://api.dona.im/seller-api/v1/me \
      -H "Authorization: Bearer $DONA_KEY"
    Ответ GET /me (пример из спецификации)
    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. Пробная запись остатков

    С Dona-Dry-Run: true запись проверяется, результат считается — и ничего не сохраняется.

    Пока запись закрыта (writes_enabled), сервер отвечает 503 limits_unavailable — это не ошибка ключа.

    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. Получайте изменения

    GET /events?cursor=… — основной канал. Вебхуки присылают те же события.

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

0208

Справочник

14 групп · 61 операция

Каждая операция отрисована из контракта OpenAPI при сборке сайта. Значки показывают уровень ключа и право, нужные для операции.

Справочник — на английском, как и сам контракт.

Базовый
Любой действующий ключ
Расширенный
Подтверждены личность, документы и магазин, нет санкций
Открытый
Без ключа
Общие параметры (в операциях указаны по имени)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 операция

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

get/meБазовый

Who am I — key, shop, tier, limits

БазовыйПраво: anyСтоимость: 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.

Параметры (3)
Ответ 200 · Me
  • keyobjectобязательно
  • shopobjectобязательно
  • tierstringобязательно

    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_accessobjectобязательно
  • writes_enabledbooleanобязательно

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

  • limitsLimitsобязательно
  • attentionobjectобязательно
  • docs_urlstring (uri)обязательно

    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).

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/me" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операций

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

get/productsБазовый

List products

БазовыйПраво: catalog:readСтоимость: 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.

Параметры (12)
Ответ 200 · ProductPage
  • itemsProduct[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/products" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/productsБазовый

Create a product (lands as draft / ai_review)

БазовыйПраво: catalog:writeСтоимость: 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.

Параметры (6)
Тело запроса · ProductCreate
  • 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
  • seller_skustringобязательно
  • barcodestring
  • external_idstring

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

  • price_uzsinteger (int64)обязательно
  • compare_at_uzsinteger | null
  • stockintegerобязательно
  • ikpustring
  • package_codestring
  • image_urlsstring (uri)[]
  • video_urlstring (uri)
  • attributesobject
  • variantsVariantInput[]
    VariantInput[]
    • optionsobjectобязательно
    • skustring
    • barcodestring
    • price_uzsinteger (int64)обязательно
    • compare_at_uzsinteger | null
    • stockintegerобязательно
  • publishboolean

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

Ответ 201 · ProductCreated
  • idstring (uuid)обязательно
  • statusstringобязательно
  • holdobject | nullобязательно
  • issuesIssue[]обязательно
  • created_via"api"обязательно
Коды ответа
  • 201Created
  • 202Held for review — nothing written.
Запрос
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}'
Пример ответа
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "draft",
  "hold": {
    "reason": "shop_not_activated"
  },
  "issues": [],
  "created_via": "api"
}
get/products/{id}Базовый

Get a product

БазовыйПраво: catalog:readСтоимость: key-rate · 1

One product with its variants.

Параметры (4)
Ответ 200 · Product
  • idstring (uuid)обязательно
  • titleLocalizedTextобязательно

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

  • descriptionLocalizedText | nullобязательно
  • statusstringобязательно

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

  • category_idstring | nullобязательно
  • brandstring | nullобязательно
  • seller_skustring | nullобязательно
  • barcodestring | nullобязательно
  • external_idstring | nullобязательно
  • price_uzsinteger (int64)обязательно

    Integer soʻm (no decimals).

  • compare_at_uzsinteger | nullобязательно

    Must exceed price_uzs (0020 CHECK).

  • stockintegerобязательно

    Sum over variants when has_variants.

  • has_variantsbooleanобязательно
  • variantsVariant[]обязательно
  • ikpustring | nullобязательно
  • package_codestring | nullобязательно
  • image_urlsstring (uri)[]обязательно
  • video_urlstring | nullобязательно
  • attributesobjectобязательно
  • created_viastringобязательно

    manual, mass_upload, api, … (products_created_via_check).

  • holdobject | nullобязательно
  • open_issuesintegerобязательно

    Open listing_issues + product_violations.

  • versionstringобязательно

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

  • created_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

Update a product

БазовыйПраво: catalog:writeСтоимость: write-rate · 1

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

Параметры (7)
Тело запроса · 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.

Ответ 200 · Product
  • idstring (uuid)обязательно
  • titleLocalizedTextобязательно

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

  • descriptionLocalizedText | nullобязательно
  • statusstringобязательно

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

  • category_idstring | nullобязательно
  • brandstring | nullобязательно
  • seller_skustring | nullобязательно
  • barcodestring | nullобязательно
  • external_idstring | nullобязательно
  • price_uzsinteger (int64)обязательно

    Integer soʻm (no decimals).

  • compare_at_uzsinteger | nullобязательно

    Must exceed price_uzs (0020 CHECK).

  • stockintegerобязательно

    Sum over variants when has_variants.

  • has_variantsbooleanобязательно
  • variantsVariant[]обязательно
  • ikpustring | nullобязательно
  • package_codestring | nullобязательно
  • image_urlsstring (uri)[]обязательно
  • video_urlstring | nullобязательно
  • attributesobjectобязательно
  • created_viastringобязательно

    manual, mass_upload, api, … (products_created_via_check).

  • holdobject | nullобязательно
  • open_issuesintegerобязательно

    Open listing_issues + product_violations.

  • versionstringобязательно

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

  • created_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
  • 202Held for review — nothing written.
Запрос
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"}'
Пример ответа
{
  "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}/issuesБазовый

Why a product is held, rejected or flagged

БазовыйПраво: catalog:readСтоимость: key-rate · 1

Open listing_issues, product_shop_holds and product_violations for one product.

Параметры (4)
Ответ 200 · ProductIssues
  • product_idstring (uuid)обязательно
  • itemsIssue[]обязательно
Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/products/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/issues" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/deletedБазовый

Tombstones since a time

БазовыйПраво: catalog:readСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

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

Параметры (6)
Ответ 200 · TombstonePage
  • itemsTombstone[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/products/deleted?since=<since>" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/publishБазовый

Publish

БазовыйПраво: catalog:writeСтоимость: 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.

Параметры (7)
Ответ 200 · ProductState
  • idstring (uuid)обязательно
  • statusstringобязательно
  • holdobject | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
  • 202Held for review — nothing written.
Запрос
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"
Пример ответа
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "active",
  "hold": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/products/{id}/delistБазовый

Delist (hide) — never a hard delete

БазовыйПраво: catalog:writeСтоимость: 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.

Параметры (7)
Ответ 200 · ProductState
  • idstring (uuid)обязательно
  • statusstringобязательно
  • holdobject | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
  • 202Held for review — nothing written.
Запрос
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"
Пример ответа
{
  "id": "0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e",
  "status": "delisted",
  "hold": null,
  "updated_at": "2026-09-24T14:05:12+05:00"
}
post/products/batchБазовый

Batch create/update (async job)

БазовыйПраво: catalog:writeСтоимость: 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.

Параметры (6)
Тело запроса · BatchRequest
  • itemsBatchCommand[]обязательно
    BatchCommand[]
    • opstringобязательно

      create · update

    • product_idstring (uuid)

      Required when op=update.

    • createProductCreate
      ProductCreate
      • 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
      • seller_skustringобязательно
      • barcodestring
      • external_idstring

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

      • price_uzsinteger (int64)обязательно
      • compare_at_uzsinteger | null
      • stockintegerобязательно
      • 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.

Ответ 202 · JobAccepted
  • job_idstring (uuid)обязательно
  • status"pending"обязательно
  • linksobjectобязательно
Коды ответа
  • 202Accepted
Запрос
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"}]}'
Пример ответа
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
post/media/upload-urlБазовый

Presigned media upload

БазовыйПраво: catalog:writeСтоимость: write-rate · 1

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

Параметры (3)
Тело запроса · MediaUploadRequest
  • content_typestringобязательно

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

  • size_bytesintegerобязательно

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

Ответ 200 · MediaUploadUrl
  • keystringобязательно
  • upload_urlstring (uri)обязательно

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

  • public_urlstring (uri)обязательно

    Use this in image_urls.

  • expires_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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}'
Пример ответа
{
  "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 операции

Absolute, bulk, guarded (catalog.ApplyGuardedStockPrice).

get/stockБазовый

Stock, SKU-level

БазовыйПраво: catalog:readСтоимость: 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).

Параметры (9)
Ответ 200 · StockLineViewPage
  • itemsStockLineView[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/stock" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/stockБазовый

Set absolute stock (≤ 1 000 lines)

БазовыйПраво: catalog:stockСтоимость: 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.

Параметры (7)
Тело запроса · StockRequest
  • itemsStockLine[]обязательно
    StockLine[]
    • product_idstring (uuid)
    • seller_skustring
    • barcodestring
    • external_idstring
    • variant_idstring (uuid)
    • quantityintegerобязательно

      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.

Ответ 200 · BulkResult
  • resultsLineResult[]обязательно
  • summaryobjectобязательно
  • dry_runbooleanобязательно
Коды ответа
  • 200OK
  • 202<code>atomic=true</code> and a line was held — nothing written.
Запрос
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}]}'
Пример ответа
{
  "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/pricesБазовый

Set absolute prices (≤ 1 000 lines)

БазовыйПраво: catalog:stockСтоимость: 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.

Параметры (7)
Тело запроса · PriceRequest
  • itemsPriceLine[]обязательно
    PriceLine[]
    • product_idstring (uuid)
    • seller_skustring
    • barcodestring
    • external_idstring
    • variant_idstring (uuid)
    • price_uzsinteger (int64)обязательно

      ABSOLUTE price.

    • compare_at_uzsinteger | null

      Must exceed price_uzs; null clears.

    • versionstring
Ответ 200 · BulkResult
  • resultsLineResult[]обязательно
  • summaryobjectобязательно
  • dry_runbooleanобязательно
Коды ответа
  • 200OK
  • 202<code>atomic=true</code> and a line was held — nothing written.
Запрос
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}]}'
Пример ответа
{
  "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 операций

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

get/ordersБазовый

List orders (no buyer PII)

БазовыйПраво: orders:readСтоимость: 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.

Параметры (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
Ответ 200 · OrderPage
  • itemsOrder[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/orders" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

Get an order (PII only with orders:pii)

БазовыйПраво: orders:readСтоимость: 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).

Параметры (4)
Ответ 200 · Order | OrderWithPii

Один из вариантов: Order · OrderWithPii

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/timelineБазовый

Order timeline

БазовыйПраво: orders:readСтоимость: key-rate · 1

order_events in order.

Параметры (4)
Ответ 200 · OrderTimeline
  • order_idstring (uuid)обязательно
  • itemsOrderTimelineEntry[]обязательно
Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/timeline" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/acceptБазовый

Accept

БазовыйПраво: orders:writeСтоимость: write-rate · 1

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

Параметры (7)
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"
Пример ответа
{
  "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}/readyБазовый

Mark ready to ship

БазовыйПраво: orders:writeСтоимость: write-rate · 1

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

Параметры (7)
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"
Пример ответа
{
  "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}/shipБазовый

Ship

БазовыйПраво: orders:writeСтоимость: write-rate · 1

409: order_not_shippable, order_awaiting_courier. Kill switch: writes_enabled.

Параметры (7)
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"
Пример ответа
{
  "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}/handoverБазовый

Hand over to the courier

БазовыйПраво: orders:writeСтоимость: write-rate · 1

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

Параметры (7)
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"
Пример ответа
{
  "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}/notesБазовый

Add a seller note

БазовыйПраво: orders:writeСтоимость: write-rate · 1

Appends to order_notes. Kill switch: writes_enabled.

Параметры (7)
Тело запроса · NoteRequest
  • textstringобязательно
Ответ 201 · NoteCreated
  • idstring (uuid)обязательно
  • order_idstring (uuid)обязательно
  • created_atstring (date-time)обязательно

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

Коды ответа
  • 201Created
Запрос
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"}'
Пример ответа
{
  "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}/declineРасширенный

Decline (before acceptance) — money-reversing

РасширенныйПраво: orders:cancelСтоимость: 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).

Параметры (7)
Тело запроса · DeclineRequest
  • reasonstringобязательно

    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
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"}'
Пример ответа
{
  "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}/cancelРасширенный

Cancel (after acceptance) — money-reversing

РасширенныйПраво: orders:cancelСтоимость: 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.

Параметры (7)
Тело запроса · DeclineRequest
  • reasonstringобязательно

    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
Ответ 200 · OrderTransition
  • idstring (uuid)обязательно
  • statusstringобязательно
  • payment_statusstringобязательно
  • accepted_atstring | nullобязательно
  • shipped_atstring | nullобязательно
  • cancelled_bystring | nullобязательно

    seller · buyer · system

  • decline_reason_codestring | nullобязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"}'
Пример ответа
{
  "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.pdfРасширенный

Shipping label (PDF, contains PII)

РасширенныйПраво: orders:piiСтоимость: 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.

Параметры (4)
Ответ 200

Тип ответа: application/pdf

Коды ответа
  • 200OK
Запрос
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.pdfРасширенный

Invoice (PDF, contains PII)

РасширенныйПраво: orders:piiСтоимость: 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).

Параметры (4)
Ответ 200

Тип ответа: application/pdf

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/orders/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/invoice.pdf" \
  -H "Authorization: Bearer $DONA_KEY"
post/orders/labelsРасширенный

Labels for ≤ 100 orders (one PDF)

РасширенныйПраво: orders:piiСтоимость: 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).

Параметры (3)
Тело запроса · LabelsRequest
  • order_idsstring (uuid)[]обязательно
Ответ 200

Тип ответа: application/pdf

Коды ответа
  • 200OK
Запрос
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 операции

Read-only in v1.

get/returnsБазовый

List returns

БазовыйПраво: returns:readСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

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

Параметры (7)
Ответ 200 · ReturnPage
  • itemsReturn[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/returns" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

Get a return

БазовыйПраво: returns:readСтоимость: key-rate · 1

Includes the buyer's reason_text (detail only).

Параметры (4)
Ответ 200 · Return
  • idstring (uuid)обязательно
  • order_idstring (uuid)обязательно
  • statusstringобязательно

    requested · approved · refunded · rejected · disputed · closed

  • typestringобязательно
  • reason_codestringобязательно
  • refund_uzsinteger (int64)обязательно

    Integer soʻm (no decimals).

  • due_atstring | nullобязательно
  • itemsobject[]обязательно
  • reason_textstring | nullобязательно

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

  • created_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/returns/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операции

Account health, metrics, verification verdicts.

get/account/healthБазовый

Account health summary

БазовыйПраво: health:readСтоимость: key-rate · 1

accounthealth.BuildSummary projection.

Параметры (3)
Ответ 200 · HealthSummary
  • health_labelstringобязательно

    good · fair · poor

  • reputation_scorenumber | nullобязательно
  • penalty_pointsintegerобязательно
  • penalty_maxintegerобязательно
  • punishment_activebooleanобязательно
  • suppressionobject | nullобязательно
  • metricsMetric[]обязательно
  • open_attentionintegerобязательно
  • computed_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/account/health" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

One metric with weekly history

БазовыйПраво: health:readСтоимость: key-rate · 1

Unknown metric id ⇒ 404 not_found.

Параметры (4)
Ответ 200 · MetricDetail

Тип ответа: application/json

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/account/metrics/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/verificationБазовый

The three verdicts and what ADVANCED still needs

БазовыйПраво: health:readСтоимость: key-rate · 1

From seller_api_shop_v.

Параметры (3)
Ответ 200 · Verification
  • statusstringобязательно

    pending · approved · suspended · blocked · restricted · closed

  • documents_statusstringобязательно
  • kyc_statusstringобязательно
  • documents_waivedbooleanобязательно
  • bank_confirmedbooleanобязательно
  • can_sellbooleanобязательно
  • tierstringобязательно

    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[]обязательно

    Empty when ADVANCED. A waiver never satisfies documents_approved.

    kyc_approved · documents_approved · shop_approved · no_active_punishment

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/account/verification" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операции

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

get/attentionБазовый

Errors, warnings, attention required

БазовыйПраво: attention:readСтоимость: 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).

Параметры (12)
Ответ 200 · AttentionPage
  • itemsAttentionItem[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

  • countsAttentionCountsобязательно
Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/attention" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

One attention item

БазовыйПраво: attention:readСтоимость: key-rate · 1

—

Параметры (4)
Ответ 200 · AttentionItem
  • idstring (uuid)обязательно
  • kindstringобязательно

    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

  • severitystringобязательно

    low · medium · high · critical

  • action_requiredbooleanобязательно

    True only when the SELLER can clear it.

  • resolves_bystringобязательно

    condition · decision · deadline · expiry · ack

  • subjectobject | nullобязательно
  • titleLocalizedTextобязательно

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

  • bodyLocalizedTextобязательно

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

  • deadline_atstring | nullобязательно
  • action_urlstring | nullобязательно

    Portal deep link.

  • opened_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

  • acked_atstring | nullобязательно
  • acked_viastring | nullобязательно

    portal · api · mcp

  • resolved_atstring | nullобязательно
  • resolved_reasonstring | nullобязательно

    condition_cleared · decided · deadline_passed · expired · acked

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/attention/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/ackБазовый

Acknowledge

БазовыйПраво: attention:readСтоимость: 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.

Параметры (4)
Ответ 200 · AttentionItem
  • idstring (uuid)обязательно
  • kindstringобязательно

    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

  • severitystringобязательно

    low · medium · high · critical

  • action_requiredbooleanобязательно

    True only when the SELLER can clear it.

  • resolves_bystringобязательно

    condition · decision · deadline · expiry · ack

  • subjectobject | nullобязательно
  • titleLocalizedTextобязательно

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

  • bodyLocalizedTextобязательно

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

  • deadline_atstring | nullобязательно
  • action_urlstring | nullобязательно

    Portal deep link.

  • opened_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

  • acked_atstring | nullобязательно
  • acked_viastring | nullобязательно

    portal · api · mcp

  • resolved_atstring | nullобязательно
  • resolved_reasonstring | nullобязательно

    condition_cleared · decided · deadline_passed · expired · acked

Коды ответа
  • 200OK
Запрос
curl -sS -X POST "https://api.dona.im/seller-api/v1/attention/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ack" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операция

/events — the primary, pollable change feed.

get/eventsБазовый

The change feed (primary channel)

БазовыйПраво: events:readСтоимость: 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.

Параметры (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
Ответ 200 · EventPage
  • itemsEvent[]обязательно
  • next_cursorstring | nullобязательно

    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_morebooleanобязательно

    True ⇒ call again immediately.

  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/events" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операций

Signed push of the same events (Standard Webhooks).

get/webhooksБазовый

List endpoints (≤ 5)

БазовыйПраво: webhooks:manageСтоимость: key-rate · 1

Never a secret.

Параметры (3)
Ответ 200 · WebhookPage
  • itemsWebhook[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/webhooks" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/webhooksБазовый

Register an endpoint (secret shown once)

БазовыйПраво: webhooks:manageСтоимость: 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.

Параметры (4)
Тело запроса · WebhookCreate
  • urlstring (uri)обязательно

    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.

Ответ 201 · WebhookWithSecret

Тип ответа: application/json

Коды ответа
  • 201Created
Запрос
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"}'
Пример ответа
{
  "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}Базовый

Get an endpoint

БазовыйПраво: webhooks:manageСтоимость: key-rate · 1

—

Параметры (4)
Ответ 200 · Webhook
  • idstring (uuid)обязательно
  • urlstring (uri)обязательно
  • event_typesstring[]обязательно

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

  • statusstringобязательно

    active · paused · disabled

  • failing_sincestring | nullобязательно
  • disabled_reasonstring | nullобязательно

    ladder_exhausted · success_rate · owner · staff · ssrf_recheck

  • consecutive_failuresintegerобязательно
  • last_delivered_atstring | nullобязательно
  • success_rate_24hnumber | nullобязательно
  • secret_rotating_untilstring | nullобязательно

    While set, deliveries carry two signatures.

  • created_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}Базовый

Change url / event types / pause

БазовыйПраво: webhooks:manageСтоимость: write-rate · 1

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

Параметры (5)
Тело запроса · 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

Ответ 200 · Webhook
  • idstring (uuid)обязательно
  • urlstring (uri)обязательно
  • event_typesstring[]обязательно

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

  • statusstringобязательно

    active · paused · disabled

  • failing_sincestring | nullобязательно
  • disabled_reasonstring | nullобязательно

    ladder_exhausted · success_rate · owner · staff · ssrf_recheck

  • consecutive_failuresintegerобязательно
  • last_delivered_atstring | nullобязательно
  • success_rate_24hnumber | nullобязательно
  • secret_rotating_untilstring | nullобязательно

    While set, deliveries carry two signatures.

  • created_atstring (date-time)обязательно

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

  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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"}'
Пример ответа
{
  "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}Базовый

Remove an endpoint

БазовыйПраво: webhooks:manageСтоимость: write-rate · 1

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

Параметры (4)
Ответ 204
Коды ответа
  • 204Deleted
Запрос
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}/pingБазовый

Re-run the verification ping

БазовыйПраво: webhooks:manageСтоимость: 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.

Параметры (4)
Ответ 200 · WebhookPing
  • okbooleanобязательно
  • response_statusinteger | nullобязательно
  • response_msinteger | nullобязательно
  • failurestring | nullобязательно

    timeout · tls · dns · status

  • webhookWebhookобязательно
Коды ответа
  • 200OK
Запрос
curl -sS -X POST "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/ping" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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-secretБазовый

Rotate the signing secret (24 h dual signing)

БазовыйПраво: webhooks:manageСтоимость: write-rate · 1

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

Параметры (5)
Ответ 200 · WebhookWithSecret

Тип ответа: application/json

Коды ответа
  • 200OK
Запрос
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)"
Пример ответа
{
  "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}/deliveriesБазовый

Delivery log (30 d)

БазовыйПраво: webhooks:manageСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

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

Параметры (8)
  • idpath · string (uuid)обязательно

    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
Ответ 200 · DeliveryPage
  • itemsDelivery[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/webhooks/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/deliveries" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/redeliverБазовый

Redeliver one delivery

БазовыйПраво: webhooks:manageСтоимость: 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.

Параметры (6)
  • idpath · string (uuid)обязательно

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

  • delivery_idpath · string (uuid)обязательно

    Delivery id.

  • Idempotency-Keyheader · stringобязательно
  • Accept-Languageheader · string
  • Dona-Sellerheader · string (uuid)
  • X-Dona-Integrationheader · string
Ответ 200 · Delivery
  • idstring (uuid)обязательно
  • webhook_idstring (uuid)обязательно
  • event_idstring (uuid)обязательно
  • event_typestringобязательно

    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

  • attemptintegerобязательно
  • statusstringобязательно

    queued · delivered · failed · dead

  • next_attempt_atstring | nullобязательно
  • delivered_atstring | nullобязательно
  • response_statusinteger | nullобязательно
  • response_msinteger | nullобязательно
  • errorstring | nullобязательно
  • occurred_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
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)"
Пример ответа
{
  "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 операции

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

get/categoriesБазовый

Category tree (platform-owned)

БазовыйПраво: anyСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

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

Параметры (6)
Ответ 200 · CategoryPage
  • itemsCategory[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/categories" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/requirementsБазовый

What a product in this leaf needs

БазовыйПраво: anyСтоимость: key-rate · 1

Per-category requirements + listing policy.

Параметры (4)
Ответ 200 · CategoryRequirements
  • category_idstring (uuid)обязательно
  • statusstringобязательно
  • listing_policystringобязательно

    open default; approval_required, licensed, restricted, prohibited.

  • is_leafbooleanобязательно
  • can_listbooleanобязательно

    status=active AND is_leaf AND listing_policy <> prohibited.

  • min_imagesintegerобязательно
  • requires_dimensionsbooleanобязательно
  • requires_brandbooleanобязательно
  • requires_size_chartbooleanобязательно
  • commission_pctnumber | nullобязательно
  • attributesCategoryAttribute[]обязательно
Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/categories/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e/requirements" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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/brandsБазовый

Brand search

БазовыйПраво: anyСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

Prefix search.

Параметры (6)
Ответ 200 · BrandPage
  • itemsBrand[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/brands" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "items": [
    {
      "id": "01972b20-2222-7ccc-9ddd-0123456789cd",
      "name": "Bahor",
      "protection": "open"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
get/ikpuБазовый

IKPU (tax classifier) search

БазовыйПраво: anyСтоимость: key-rate · 1 + ceil(limit/50) when limit > 50, else 1

From the local tasnif copy.

Параметры (6)
Ответ 200 · IkpuPage
  • itemsIkpu[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/ikpu?q=<q>" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "items": [
    {
      "code": "06109100001000000",
      "name": "Paxtali trikotaj futbolkalar",
      "active": true,
      "packages": [
        {
          "code": "1520227",
          "name": "dona"
        }
      ]
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Jobs

4 операции

Async exports and product batches.

post/exports/productsБазовый

Export products (async)

БазовыйПраво: catalog:readСтоимость: key-rate · 10

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

Параметры (4)
Тело запроса · 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)
Ответ 202 · JobAccepted
  • job_idstring (uuid)обязательно
  • status"pending"обязательно
  • linksobjectобязательно
Коды ответа
  • 202Accepted
Запрос
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"}}'
Пример ответа
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
post/exports/ordersБазовый

Export orders (async, no PII)

БазовыйПраво: orders:readСтоимость: key-rate · 10

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

Параметры (4)
Тело запроса · 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)
Ответ 202 · JobAccepted
  • job_idstring (uuid)обязательно
  • status"pending"обязательно
  • linksobjectобязательно
Коды ответа
  • 202Accepted
Запрос
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"}}'
Пример ответа
{
  "job_id": "01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d",
  "status": "pending",
  "links": {
    "self": "/seller-api/v1/jobs/01997b34-4e5f-7a6b-9c7d-8e9f0a1b2c3d"
  }
}
get/jobs/{id}Базовый

Poll a job

БазовыйПраво: anyСтоимость: 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.

Параметры (4)
Ответ 200 · Job
  • idstring (uuid)обязательно
  • kindstringобязательно

    export_products · export_orders · products_batch

  • statusstringобязательно

    pending · running · ready · failed

  • progressobjectобязательно
  • file_urlstring | nullобязательно

    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 | nullобязательно
  • resultsLineResult[] | nullобязательно

    products_batch only: the per-line shape.

  • errorstring | nullобязательно

    Our code only.

  • created_atstring (date-time)обязательно

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

  • finished_atstring | nullобязательно
  • expires_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/jobs/0199612e-8a0b-7c4d-b1e2-3f4a5b6c7d8e" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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}/downloadБазовый

Download an export's file

БазовыйПраво: anyСтоимость: 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.

Параметры (5)
  • idpath · string (uuid)обязательно

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

  • tokenquery · stringобязательно

    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
Ответ 200

Тип ответа: application/x-ndjson, text/csv

Коды ответа
  • 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.
Запрос
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 операции

Balance and settlement lines (ADVANCED).

get/finance/balanceРасширенный

Balance

РасширенныйПраво: finance:readСтоимость: 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).

Параметры (3)
Ответ 200 · Balance
  • available_uzsinteger (int64)обязательно

    Integer soʻm (no decimals).

  • held_uzsinteger (int64)обязательно

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

  • expected_uzsinteger (int64)обязательно

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

  • currency"UZS"обязательно
  • as_ofstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/finance/balance" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "available_uzs": 12450000,
  "held_uzs": 3100000,
  "expected_uzs": 5400000,
  "currency": "UZS",
  "as_of": "2026-09-24T14:05:12+05:00"
}
get/finance/settlementsРасширенный

Settlement lines

РасширенныйПраво: finance:readСтоимость: 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.

Параметры (8)
Ответ 200 · SettlementPage
  • itemsSettlement[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/finance/settlements" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операция

Read-only list of the shop's keys.

get/keysБазовый

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

БазовыйПраво: anyСтоимость: key-rate · 1

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

Параметры (3)
Ответ 200 · KeyPage
  • itemsKey[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/keys" \
  -H "Authorization: Bearer $DONA_KEY"
Пример ответа
{
  "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 операций

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

get/pingОткрытый

Liveness (key optional)

ОткрытыйПраво: noneСтоимость: 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.

Параметры (2)
Ответ 200 · Ping
  • ok"pong"обязательно
  • timestring (date-time)обязательно

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

  • authenticatedbooleanобязательно

    True only when a valid key was presented.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/ping"
Пример ответа
{
  "ok": "pong",
  "time": "2026-09-24T14:05:12+05:00",
  "authenticated": true
}
get/statusОткрытый

Service status

ОткрытыйПраво: noneСтоимость: edge · 0

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

Параметры (2)
Ответ 200 · Status
  • statusstringобязательно

    operational · degraded · outage

  • componentsobjectобязательно
  • incidentsobject[]обязательно
  • updated_atstring (date-time)обязательно

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

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/status"
Пример ответа
{
  "status": "operational",
  "components": {
    "api": "operational",
    "mcp": "disabled",
    "webhooks": "operational",
    "events": "operational"
  },
  "incidents": [],
  "updated_at": "2026-09-24T14:05:12+05:00"
}
get/changelogОткрытый

Changelog (JSON, or RSS with Accept)

ОткрытыйПраво: noneСтоимость: 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.

Параметры (4)
Ответ 200 · ChangelogEntryPage
  • itemsChangelogEntry[]обязательно
  • next_cursorstring | nullобязательно

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

  • has_morebooleanобязательно
  • metaPageMeta

    Endpoint-specific facts; clients must tolerate unknown keys.

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/changelog"
Пример ответа
{
  "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.jsonОткрытый

This document

ОткрытыйПраво: noneСтоимость: edge · 0

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

Параметры (2)
Ответ 200 · object

Тип ответа: application/json

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/openapi.json"
get/llms.txtОткрытый

llms.txt index for AI agents

ОткрытыйПраво: noneСтоимость: edge · 0

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

Параметры (2)
Ответ 200

Тип ответа: text/plain

Коды ответа
  • 200OK
Запрос
curl -sS "https://api.dona.im/seller-api/v1/llms.txt"

0308

Лимиты

Лимиты считаются по подтверждённому ключу и магазину, а не по IP. Ниже — значения по умолчанию; действующие для вашего ключа — в GET /me → limits.

Лимиты
ЛимитБазовый skРасширенный skАгент ak
Запросов / мин (ключ)300 · burst 60600 · burst 12060 · burst 20
Запросов / сутки (ключ)100 000250 00020 000
Записей / мин6012010
Записей / сутки20 00050 0002 000
Одновременных запросов484
Запросов / мин (магазин, все ключи)9001 800—
  • Остаток или цена одного товара — не чаще 1 записи в 10 секунд (object_cooldown).
  • Пакетная запись ≤ 1 000 строк; тело ≤ 256 КиБ (пакетная — 4 МиБ). Рекомендуем 100–300 строк.
  • Страница limit ≤ 100 (на /events ≤ 200). If-None-Match → 304 за полцены.
  • Наши 429/503 и 5xx не списываются и не приостанавливают ключ.

Значения Dona-Rate-Limited-Reason:

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

0408

Коды ошибок

59 кодов

Любая ошибка — один конверт: error — стабильный код, message — перевод по Accept-Language.

Ветвитесь по коду, никогда — по message.

Конверт ошибки
{
  "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

Также 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

Также a replay of a rejected held write

410Gone

413Content Too Large

422Unprocessable Content

429Too Many Requests

Также 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

Также 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

Также Costs 0

0508

События и вебхуки

41 тип события

Все изменения — в одной ленте. Для систем, которые умеют только инициировать запрос (как 1С), опрос ленты — основной канал.

Опрос ленты

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"

Вебхуки — подпись Standard Webhooks

Правила доставки

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).

Заголовки

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.

Типы событий

  • 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

Подпись ниже настоящая: она вычислена при сборке сайта из показанного демо-секрета и тела, и код подтверждает её байт в байт.

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"}}
Проверка подписи · 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)
  })
}
Проверка подписи · 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-агенты

Claude Code, Cursor, Codex и другие AI-агенты могут работать с вашим магазином через MCP. Каждый вызов журналируется.

С ключом агента агент читает магазин: товары, заказы, события, требующие внимания состояния, здоровье аккаунта и эту документацию. Инструменты записи — остатки, цены, отправка и отмена заказа — доступны только магазину расширенного уровня и только пока запись включена. С первого вызова ничего не записывается: изменение сначала подтверждается — в форме подтверждения самого агента или владельцем магазина в Настройки › API › Отложенные изменения.

Endpoint
https://api.dona.im/seller-api/mcp
Метаданные защищённого ресурса (RFC 9728)
/.well-known/oauth-protected-resource/seller-api/mcp

Ключ агента (dona_ak_live_…, право mcp) создаётся в разделе Настройки › API.

Одна команда для Claude Code
claude mcp add --transport http dona https://api.dona.im/seller-api/mcp --header "Authorization: Bearer ${DONA_AGENT_KEY}"

OAuth 2.1 — коннекторы claude.ai и ChatGPT

Коннекторы, в которые нельзя вставить ключ, входят через OAuth 2.1: подключение одобряет владелец магазина в кабинете продавца (Настройки › API › Подключённые приложения) и может отключить его в любой момент. Через OAuth агент может только читать.

Сервер авторизации
https://auth.dona.im

0708

SDK

SDK для TypeScript, Python, Go, PHP и C# генерируются из этого же контракта.

  • TypeScript
  • Python
  • Go
  • PHP
  • C#
  • Предварительная версия 0.1.0

SDK лежат в открытом репозитории на GitHub. В реестрах (npm, PyPI, NuGet, Packagist) пакеты ещё не опубликованы — пока устанавливайте прямо из репозитория.

  • TypeScript

    Требуется: Node ≥ 20

    Нужен клон репозитория

    Установка
    git clone https://github.com/ozbuz/dona-api.git && cd dona-api/sdks/typescript && npm install
    Установка
    npm install ../dona-api/sdks/typescript
  • Python

    Требуется: ≥ 3.11
    Установка
    pip install "dona-api @ git+https://github.com/ozbuz/dona-api.git@main#subdirectory=sdks/python"
  • Go

    Требуется: ≥ 1.26
    Установка
    go get github.com/ozbuz/dona-api/sdks/go@main
  • PHP

    Требуется: ≥ 8.1, Guzzle 7

    Нужен клон репозитория

    Установка
    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#

    Требуется: .NET 10

    Нужен клон репозитория

    Установка
    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

Изменения и статус

Каждое изменение публикуется с датой, типом и затронутыми правами.

Нужен ключ?

Ключ создаёт владелец магазина в кабинете продавца: Настройки › API. Ключ показывается один раз.

Вопрос как у покупателя или продавца? Загляните в центр помощи.

Отсканируйте, чтобы скачать DonaСкачайте Dona

Показать QR-код
QR-код для загрузки приложения Dona

Наведите камеру телефона на QR-код