# Прайсыңызды ADAM-ға жіберіңіз

Бір HTTP сұрауы кестені ауыстырады. Жүйеңіз файлды жібереді, біз жол-жолымен нені оқығанымызды және нені оқи алмағанымызды айтамыз.

Payload-ты ештеңе жасамай тексеруді Параметрлер → Интеграциялар → Сынақ алаңы бөлімінде жасауға болады.

- OpenAPI 3.1: https://adam.ua/kk/docs/api/openapi.json
- HTML: https://adam.ua/kk/docs/api

## Кілт алу

Параметрлер → Интеграциялар → Қосу. Құпия сөз жасалғанда бір рет көрсетіледі және тек хеш ретінде сақталады — оны ERP оқитын жерде ұстаңыз. `Authorization: Bearer …` ретінде жіберіңіз.

```bash
curl -X POST https://ingest.adam.ua/v1/products \
  -H "Authorization: Bearer adam_live_…" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"sku":"KRB-46","name":"Карбамід 46% гранульований","brand":"Sumykhimprom","category":"Добрива","unit":"кг","price":12.5,"stock":1000,"warehouse":"Київський склад","moq":100,"updated_at":"2026-08-24T14:02:31Z"}]}'
```

## Позиция, өріс-өріспен — `POST /v1/products`

| Өріс | Түрі | | Ереже |
| --- | --- | --- | --- |
| `name` | string · ≤300 | **міндетті** | Тауардың сіздің жүйеңіздегі атауы. Қиылады, бос болмайды. |
| `brand` | string · ≤120 | **міндетті** | Санат ішінде матчер арқылы анықталады. |
| `category` | string · ≤120 | **міндетті** | Адами түрде. Төмендегі тізім бойынша анықталады. |
| `unit` | string · ≤40 | **міндетті** | Адами түрде: «шт», «шт.», «кг», «т», «канистр» — барлығы анықталады. |
| `price` | number | **міндетті** | 0-ден жоғары. Сан, жол емес; ондық бөлгіш — «.». |
| `stock` | number | **міндетті** | 0 немесе одан көп. Нөл «қоймада жоқ» дегенді білдіреді, «белгісіз» емес. |
| `sku` | string · ≤100 | міндетті емес | Сіздің артикулыңыз. Схема бойынша міндетті емес, бірақ онсыз кейінгі PATCH-қа сүйенер нәрсе жоқ. |
| `warehouse` | string · ≤200 | міндетті емес | Сіздің қоймаларыңызбен салыстырылады — алдымен нақты атауы немесе қаласы, содан кейін осы мәнді қамтитын жалғыз қойма. Сәйкестік болмаса немесе мән мүлде берілмесе, жол әдепкі қоймаңызға түседі: жалғыз қоймаңыз немесе негізгі деп белгілегеніңіз. Екі үміткер — біз болжамайтын жалғыз жағдай: қойма қойылмайды, `warehouse_ambiguous` қайтарылады. |
| `moq` | number | міндетті емес | 0-ден жоғары. Әдепкі мәні 1. |
| `description` | string · ≤500 | міндетті емес | Еркін мәтін. Жол каталогқа жаңа тауар сұрауына айналғанда қолданылады. |
| `updated_at` | rfc3339 | міндетті емес | Позиция сіздің жүйеңізде соңғы рет қашан өзгерді. PATCH үшін тәртіп ережесін береді. |

Біз оқымайтын өріс үнсіз тасталмай, бүкіл сұранысты құлатады. Үнсіз тастау — сіз қоймаған валютаны қойдым деп сенуіңіздің жолы.

## Жауап

202, себебі жолдар өңдеуге қабылданды, сәйкестендіру мен тексеру әлі алда. Қабылданбағандар сіздің өз позиция индексіңізді атайды, сондықтан кезең-кезеңімен түзетілетін файл жинақталады.

```json
{
  "request_id": "8f14e45f-ceea-467a-9c4c-1b0f0e5c9e2a",
  "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "accepted": 1198,
  "rejected": [
    {
      "index": 42,
      "sku": "XYZ-1",
      "reason": "category_unresolved",
      "detail": "«Хімія» matches no category"
    },
    {
      "index": 87,
      "sku": "KRB-99",
      "reason": "required_field_missing",
      "field": "brand"
    }
  ],
  "rejected_total": 2
}
```

## Себеп кодтары — `POST /v1/products`

| Код | Аймақ | Мағынасы |
| --- | --- | --- |
| `invalid_envelope` | бүкіл сұраныс | Сұраныс денесі — items массиві бар объект емес. |
| `unknown_field` | бүкіл сұраныс | Біз оқымайтын өріс. Үнсіз тастамай, қатені қайтарамыз — қоймағаныңызды қойдым деп ойламауыңыз үшін. |
| `idempotency_key_reused` | бүкіл сұраныс | Бұл Idempotency-Key басқа денелі сұраныс үшін қолданылған. Жаңа кілт алыңыз — сақталған нәтиже осы сұранысқа емес, алдыңғысына тиесілі. |
| `no_items` | бүкіл сұраныс | items бос. |
| `too_many_items` | бүкіл сұраныс | Позициялар сұраныс шегінен көп. Кішірек бөліктермен жіберіңіз. |
| `required_field_missing` | бір жол | `field` көрсетіледі — жоқ немесе бос міндетті өріс. PATCH /v1/offers-та бұл әрқашан sku. |
| `field_too_long` | бір жол | `field` көрсетіледі. Әр өрістің шегі жоғарыдағы кестеде. |
| `price_invalid` | бір жол | Сан емес немесе 0-ден жоғары емес. |
| `stock_invalid` | бір жол | Сан емес немесе теріс. Нөл жарамды. |
| `moq_invalid` | бір жол | Сан емес немесе 0-ден жоғары емес. |
| `sku_duplicate_in_payload` | бір жол | Дәл осы артикул осы сұраныста бұрын кездеседі. Бірінші кездесуі жеңеді. |
| `updated_at_invalid` | бір жол | RFC 3339 емес, мысалы 2026-08-24T14:02:31Z. |
| `review_backlog` | бүкіл сұраныс | Тексерілмеген жолдарыңыз шекке жетті. Жаңасын жібермей тұрып тексеруді бітіріңіз. |
| `category_unresolved` | бір жол | Мән slug-пен де, бүркеншік атпен де сәйкес келмейді. |
| `unit_unresolved` | бір жол | Мән ешбір өлшем бірлігімен сәйкес келмейді. |
| `wrong_endpoint` | бір жол | Сіз мұнда `discontinued` жібердіңіз. Сатудан алу және қайтару — PATCH /v1/offers. |

Жабық жиын — интеграцияңыз оларға қарай тармақталады. Қабылданбаған жолға бір код: бірнеше тексеруден өтпеген жол жоғарыдағы тәртіп бойынша бірінші кодты береді.

## Бағаны мен қалдықты жаңарту — `PATCH /v1/offers`

Позиция байланысқаннан кейін `PATCH /v1/offers` оның бағасы мен қалдығын тексерусіз және адамның қатысуынсыз өзгертеді. Сіз тауар файлына жіберген артикулды жібересіз, біз оның артындағы ұсынысты өзгертеміз. Бұл — ERP жүйеңіз кесте бойынша орындайтын шақыру.

```bash
curl -X PATCH https://ingest.adam.ua/v1/offers \
  -H "Authorization: Bearer adam_live_…" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"sku":"KRB-46","price":12.9,"stock":840,"updated_at":"2026-08-25T09:00:00Z"},{"sku":"KAS-32","stock":0},{"sku":"OLD-01","discontinued":true}]}'
```

| Өріс | Түрі | | Ереже |
| --- | --- | --- | --- |
| `sku` | string · ≤100 | **міндетті** | Сіздің артикулыңыз, POST /v1/products-қа жіберілгенмен бірдей. Позицияны атаудың жалғыз жолы. |
| `price` | number | міндетті емес | 0-ден жоғары. Жібермесеңіз — баға өзгермейді. |
| `stock` | number | міндетті емес | 0 немесе одан көп. Нөл «қоймада жоқ» деп қояды және ұсынысты каталогта қалдырады. |
| `moq` | number | міндетті емес | 0-ден жоғары. Ең аз тапсырыс көлемі; өлшем бірлігі мұнда өзгермейді. |
| `discontinued` | boolean | міндетті емес | true ұсынысты сатудан алады, false қайтарады. Алу әрқашан өтеді; қайтару қабылданбауы мүмкін. |
| `updated_at` | rfc3339 | міндетті емес | Позиция сіздің жүйеңізде соңғы рет қашан өзгерді. Жіберсеңіз — кешіккен қайталау жаңа бағаны басып жаза алмайды; жібермесеңіз — соңғы келген сұраныс жеңеді. Сол уақыт және сол мәндер — no-op; сол уақыт басқа мәндермен — equal_timestamp_conflict. |

Позицияға `sku` және `price`, `stock`, `moq`, `discontinued` ішінен кемінде біреуі керек. Жібермегеніңіз сол күйінде қалады — сондықтан тек қалдық бойынша өту бағаға тимейді. Жалғыз `sku` қолданылған деп саналмай, қабылданбайды.

`updated_at` жіберсеңіз, қайталаулар қауіпті болуын қояды: уақыты соңғы қолданылғаннан ескі позиция ештеңе өзгертпейді және `stale_update` болып қайтады. Жібермесеңіз — соңғы келген сұраныс жеңеді: бір жоспарлы тапсырма үшін бұл қалыпты, екеуі үшін — жоқ.

`unchanged` — ұсынысы жіберілген мәндерді әлдеқашан ұстап отырған позициялар. Ештеңе жазылмады және ештеңе бұзылмады: барлығын жіберетін түнгі файл өзгергені үшін `applied`, қалғаны үшін `unchanged` алады, мыңдаған қате емес. Сол `updated_at` сол мәндермен де осында түседі; басқа мәндермен бұл `equal_timestamp_conflict`, себебі бірдей уақыт қай нұсқа ағымдағы екенін айта алмайды.

Сатудан алу мен қайтару симметриялы емес, және неге екенін білу практикада байқағаннан жақсы. `discontinued: true` әрқашан өтеді — өз ұсынысыңызды алуға ешкімнің рұқсаты керек емес. `discontinued: false` оны тек ұсыныс толық болса және аккаунтыңыз жариялауға құқылы болса қайтарады; әйтпесе жол `relist_blocked` болып, себебі `detail`-да қайтады.

`not_published` — фермер көрмейтін ұсыныстардағы қолданылған жолдар саны: жоба, тоқтатылған ұсыныс. Баға шынымен өзгерді, бірақ оны ешкім көрмейді. Патч сіздің орнына жарияламайды, сондықтан бұл сан — «неге ештеңе өзгермеді» деп ойламай, білу жолы.

```json
{
  "request_id": "1c9d4b7e-3f60-4a21-8de5-7a2b6c0f9e11",
  "applied": 1198,
  "unchanged": 613,
  "not_published": 42,
  "rejected": [
    {
      "index": 17,
      "sku": "ZIR-20",
      "reason": "sku_ambiguous",
      "detail": "7 of your offers carry this code: Зірочка Z-20, Зірочка Z-22, …"
    },
    {
      "index": 63,
      "sku": "KRB-46",
      "reason": "stale_update",
      "detail": "last applied 2026-08-25T09:00:00+00"
    }
  ],
  "rejected_total": 2
}
```

### Себеп кодтары — `PATCH /v1/offers`

| Код | Аймақ | Мағынасы |
| --- | --- | --- |
| `no_change_requested` | бір жол | Тек sku, өзгертілетін өріссіз. Жалғыз timestamp — өзгеріс емес: price, stock, moq немесе discontinued жіберіңіз. |
| `discontinued_invalid` | бір жол | Бар, бірақ логикалық емес. `"yes"` — true емес. |
| `sku_unknown` | бір жол | Бұл код үшін белсенді байланыс жоқ. Позицияны POST /v1/products арқылы бір рет жіберіңіз — расталғаннан кейін PATCH әрқашан жұмыс істейді. |
| `sku_pending_catalog` | бір жол | Бұл кодты сіз бұрын жібергенсіз, позиция біздің каталог тобын күтіп тұр. Қайта жібермеңіз — тауар жасалған бойда PATCH осы кодпен жұмыс істей бастайды. |
| `sku_ambiguous` | бір жол | Бұл кодты сіздің бірнеше ұсынысыңыз алып жүр, сондықтан қай бағаны өзгертетіні белгісіз. `detail` тауарларды атайды. Оларға өз жүйеңізде әртүрлі код беріңіз. |
| `offer_missing` | бір жол | Байланыс бар, бірақ оның ұсынысы жоғалған. Позицияны POST /v1/products арқылы қайта жіберіңіз. |
| `stale_update` | бір жол | Сіздің updated_at соңғы қолданылғаннан ескі, сондықтан ештеңе өзгермеді. `detail` бізде сақталған уақытты береді. |
| `equal_timestamp_conflict` | бір жол | Сіздің updated_at қолданылғанмен бірдей, бірақ мәндер өзге — қайсысы ағымдағы екенін анықтай алмаймыз және болжамай, қабылдамаймыз. updated_at-ты жылжытыңыз. Мәндер бірдей болса, позиция `unchanged`-ке кетеді және қате болмайды. |
| `relist_blocked` | бір жол | `discontinued: false` жариялау тексерісімен қабылданбады. Сатудан алу әрқашан өтеді; қайтару толық ұсынысты және жариялау құқығын талап етеді. `detail` себебін береді. |
| `price_tiered` | бір жол | Бұл ұсыныста көлемге қарай баға сатылары бар, оларды бір тұрақты баға алмастырмайды. Сатыларды кабинетте алып тастаңыз — әрі қарай позицияны API басқарады. |

Тек осы эндпоинт қайтаратын кодтар. Жоғарыдағы кестедегі сұраныс деңгейіндегі барлық кодтар мен мән тексерулері мұнда да қолданылады, ал `field` тауар файлы ондаған өрісті атайтын жерде `sku` атайды.

## Автожаңарту — баға файлын өзіміз аламыз

`PATCH /v1/offers`-пен дәл сол келісім — сол сұраныс құрылымы, сол позиция өрістері, сол себеп кодтары, сол нәтиже. Айырмашылық тек бағытта: сіздің жүйеңіз бізге емес, біз тәулігіне бір рет сіздің жағыңыздағы URL-ге қосыламыз. Конвейерде басқа ештеңе өзгермейді. Параметрлер → Интеграциялар бөлімінде бапталады.

Ол тауар жасай алмайды. Біз білмейтін артикул `sku_unknown` болып қабылданбайды. Жаңа позициялар бұрынғыдай `POST /v1/products` арқылы және оның тексеру кезегінен өтеді; автожаңарту тек байланысқан позициялардың бағасы мен қалдығын өзгертеді — басқа ештеңе емес.

Дене — сіз `PATCH /v1/offers`-қа жіберіп жүрген дене: объектілері `sku` мен қоса `price`, `stock`, `moq`, `discontinued` және `updated_at` алып жүретін `items` массиві. Позицияға `price`, `stock`, `moq`, `discontinued` ішінен кемінде біреуі керек, әйтпесе позиция `no_change_requested` болып қабылданбайды. Танылмаған өріс бүкіл сұранысты `unknown_field` деп қабылдамайды — үнсіз тастау емес, әдейі. Ең көбі 5000 позиция (`too_many_items`), ал 16 MiB-тан асатын бір партия JSON — `payload_too_large`.

Тәулігіне бір рет. Сағатты 00-ден 23-ке дейін және ол саналатын уақыт белдеуін өзіңіз таңдайсыз — сондықтан 03:00 дегеніміз жүйеңіз жұмыс істейтін жердегі 03:00, ал жазғы уақытқа өту мен қайту біздің жағымызда есептеледі. Келесі іске қосылу карточкада көрсетіледі. Баға файлыңыз жазылып бітетін сағатты таңдаңыз, ол жазыла бастайтын сағатты емес.

Аутентификация міндетті емес: не ештеңе, не Параметрлер → Интеграциялар бөлімінде өзіңіз қоятын бір `Authorization: Bearer <token>` тақырыбы. Токен шифрланған күйде сақталады, әрбір сұрауда сіздің серверіңізге жіберіледі және ешқашан логқа да, процесс аргументтеріне де түспейді. Сізден келген 401 не 403 — біздің аутентификация кодымыз емес, сол статусы бар `feed_http_error`.

### URL-ге қойылатын талаптар

Тек `https://` — қарапайым HTTP қосылым орнатылмай тұрып қабылданбайды. 443 порты немесе мүлдем портсыз: біз домен атауыңыз шешілген мекенжайды `curl --resolve host:443:<address>` арқылы бекітеміз, ал бұл бекіту (хост, порт) жұбына қолданылады — сондықтан басқа порттағы URL сұрау кезінде қарапайым DNS-ке кетіп, бекітуді мүлдем жоққа шығарар еді. Мекенжай емес, домен атауын беріңіз — IP-литералдар да, олардың он алтылық, сегіздік немесе бүтін сандық түрі де болмайды (`https://0x7f000001/` қабылданбайды), себебі клиент оларды мекенжай деп санап, мүлдем шешпейді.

Осы домен атауына сәйкес келетін жарамды TLS сертификаты. Біз сертификаттың тізбегі мен жарамдылық мерзімін ғана емес, оның субъектісін де тексереміз — басқа атауға жарамды сертификат қабылданбайды. Және қайта бағыттау болмайды: біз `--max-redirs 0` жібереміз, сондықтан 3xx сізге өз статусымен `feed_http_error` болып қайтады. Файлды бізге берген URL бойынша беріңіз.

Қарапайым `GET` — біз не дене, не өз сұрау параметрлерімізді жібермейміз. Жауап жарамды UTF-8 болуы керек; қалғаны — `bad_encoding`, ал Windows-1251 — украин және орыс есеп жүйелерінен шыққан файлдардың әдеттегі қатесі. Шек — 16 MiB: одан асса, жүктеу тоқтайды және сіз `too_large` аласыз. Жауап беруге 20 секунд бар; оған дейін домен атауыңызды шешуге бөлек алты секунд бөлінген. Баға файлын CDN артында ұзақ кештемеңіз — біз оны тәулігіне бір рет аламыз, сондықтан сағаттарға не күндерге қойылған max-age бар `Cache-Control` біз кешегі файлды оқитынымызды және бағаларыңыз қозғалмай тұрғандай көрінетінін білдіреді. Қысқа max-age қойыңыз немесе мүлдем қоймаңыз.

Баға файлын сақтаған кезде біз домен атауыңызды шешіп, мекенжайды жазып аламыз. Кейінгі әрбір сұрауда оны қайта шешеміз және тек өзіңіздің DNS-іңіз осы атау үшін дәл қазір жариялайтын мекенжайға қосыламыз, жазылған мекенжай солардың арасында болса, оған басымдық береміз. Атап айтуға тұрарлық екі салдар: DNS жаңартылған болса, хостингті көшіру сізден ешқандай әрекет талап етпейді, және біз DNS-іңіз қазір атамайтын мекенжайға ешқашан қосылмаймыз. Ол жариялайтын барлық мекенжай жеке, loopback, carrier-NAT, link-local немесе резервтелген кеңістіктен болса, іске қосылу `host_not_routable` деп тоқтайды; ол бір де біреуін жарияламаса — `pin_unresolvable`.

### Іске қосылу сәтсіз болғанда

Әрбір іске қосылу интеграциялар экранындағы сұраулар журналында автожаңартудан келгені белгіленген жол қалдырады — санақтарымен және қабылданбағандарымен. Сіз түзете алатын қате қосымша ішінде хабарландыру да жібереді.

Біздің жағымыздағы ақаулар — іске қосылу арендасының жоғалуы, өз дерекқорымыз — әдейі хабарландыру жібермейді және біздің деп белгіленеді, себебі бұл сіз түзете алатын нәрсе емес, ал келесі жоспарланған іске қосылу өзі қайта әрекеттенеді.

| Код | Аймақ | Мағынасы |
| --- | --- | --- |
| `bad_url` | бүкіл сұраныс | Сақталған URL енді жарамсыз. Оны қайта енгізіңіз. |
| `bad_pin` | бүкіл сұраныс | Сақталған мекенжайды оқу мүмкін болмады. Оны қайта тексеріп, ауыстыру үшін сақтаңыз. |
| `pin_unresolvable` | бүкіл сұраныс | Домен атауыңыз қазір мүлдем шешілмейді. DNS баптауларыңызды тексеріп, содан кейін мекенжайды қайта тексеріңіз. |
| `host_not_routable` | бүкіл сұраныс | Домен атауыңыз шешіледі, бірақ ол қазір жариялайтын барлық мекенжайлар — біз қосылмайтындар: жеке, loopback, carrier-NAT, link-local немесе резервтелген. Домен атауын жария мекенжайға бағыттаңыз. |
| `bad_auth` | бүкіл сұраныс | Сақталған токенді пайдалану мүмкін болмады. Оны қайта енгізіп, сақтаңыз. |
| `too_large` | бүкіл сұраныс | Жауап біз қабылдайтыннан үлкен. Оны бөліңіз немесе қажет емес өрістерді алып тастаңыз. |
| `timeout` | бүкіл сұраныс | Серверіңіз белгіленген уақытта жауап бермеді. |
| `fetch_failed` | бүкіл сұраныс | Серверіңізге қосылу мүмкін болмады. |
| `feed_http_error` | бүкіл сұраныс | Серверіңіз HTTP қатесімен жауап берді. 401 немесе 403 коды оның біздің токенді қабылдамағанын білдіреді. |
| `bad_encoding` | бүкіл сұраныс | Жауап жарамды UTF-8 емес. Файлды UTF-8 кодтауында беріңіз. |
| `malformed_json` | бүкіл сұраныс | Жауап жарамды JSON емес. |
| `payload_too_large` | бүкіл сұраныс | Баға файлыңыздың бір партиясы біз қолдана алатыннан тым үлкен болды. Қажет емес өрістерді алып тастаңыз немесе файлды бөліңіз. |
| `feed_not_found` | бүкіл сұраныс | Іске қосылу жүріп тұрған кезде параметрлер жоғалып кетті. Оларды қайта сақтаңыз; егер бұл қайталанса, қолдау көрсету қызметіне хабарласыңыз. |
| `lease_expired` | бүкіл сұраныс | Біз іске қосылуды бастап, аяқталмай тұрып үзуге мәжбүр болдық. Баға файлыңызда бәрі дұрыс — келесі жоспарланған іске қосылу қайта әрекеттенеді. |
| `lease_lost` | бүкіл сұраныс | Дәл осы тапсырманы қатарлас басқа іске қосылу алып кетті, сондықтан біз өзгерістерді кері қайтардық және ештеңе қолданылмады. Баға файлыңызда бәрі дұрыс — келесі жоспарланған іске қосылу қайта әрекеттенеді. |
| `internal_error` | бүкіл сұраныс | Деректерді қолдану кезінде біздің жағымызда бірдеңе бұзылды. Баға файлыңызда бәрі дұрыс — келесі жоспарланған іске қосылу қайта әрекеттенеді. |
| `lock_timeout` | бүкіл сұраныс | Деректерді қолдану кезінде біздің жағымызда бірдеңе бұзылды. Баға файлыңызда бәрі дұрыс — келесі жоспарланған іске қосылу қайта әрекеттенеді. |
| `statement_timeout` | бүкіл сұраныс | Деректерді қолдану кезінде біздің жағымызда бірдеңе бұзылды. Баға файлыңызда бәрі дұрыс — келесі жоспарланған іске қосылу қайта әрекеттенеді. |

Тек автожаңарту беретін кодтар — олар бір позиция оқылмай тұрып, сұраудың өзін сипаттайды. `PATCH /v1/offers` кестелеріндегі барлық кодтар мазмұнға өзгеріссіз қолданылады, себебі бұл сол мазмұн. Соңғы үшеуі — біздің, сіздің емес: келесі жоспарланған іске қосылу өзі қайталайды, олар туралы хабарлама алмайсыз.

## Біз танитын санаттар

Каталогтан тікелей оқылады, сондықтан бұл тізім резолвер қабылдайтыннан ажырай алмайды. Регистр мен соңғы тыныс белгісі маңызды емес.

- `seeds` — Семена: Hybrids · Seed · seeds · Sowing material · Гибриды · Гібриди · Кукурудза · Кукуруза · Насіннєвий матеріал · Насіння · Насіння кукурудзи · Насіння рапсу · Насіння сої · Насіння соняшника · Посевной материал · Посівний матеріал · Пшеница · Пшениця · Рапс · Семена · Семена кукурузы · Семена подсолнечника · Семена подсолнуха · Семена рапса · Семена сои · Семенной материал · Соняшник · Соя · Ячмень · Ячмінь
- `fertilizers` — Удобрения: Fertiliser · Fertilizer · fertilizers · Growth stimulants · Micro fertilizers · Агрохимия · Агрохімія · Добрива · Микроудобрения · Микроудобрения и стимуляторы роста · Минеральные удобрения · Мікродобрива · Мікродобрива та стимулятори росту · Мінеральні добрива · Органические удобрения · Органічні добрива · Стимулятори росту · Стимуляторы роста · Удобрения
- `pesticides` — Средства защиты растений: Agrochemicals · CPP · Crop Protection · Fungicide · Fungicides · Herbicide · Herbicides · Insecticide · Insecticides · Pesticide · pesticides · Plant protection · Агрохимикаты · Агрохімікати · Адъюванты · Адьюванти · Акарициди · Акарициды · Гербицид · Гербициды · Гербіцид · Гербіциди · Десиканти · Десиканты · Засоби захисту · Засоби захисту рослин · ЗЗР · Инсектицид · Инсектициды · Інсектицид · Інсектициди · Пестициди · Пестициди та агрохімікати · Пестициды · Пестициды и агрохимикаты · Прилипатели · Прилипачі · Прилипачі (пав) · Протравители · Протруйник · Протруйники · Родентициди · Родентициды · СЗР · Средства защиты · Средства защиты растений · Фунгицид · Фунгициды · Фунгіцид · Фунгіциди
- `fuel-lubricants` — Горюче-смазочные материалы: Diesel · Fuel · fuel-lubricants · Grease · Lubricants · Oils · Антифриз · Бензин · Горюче-смазочные материалы · ГСМ · Дизельне пальне · Дизельное топливо · ДТ · Масла · Мастила · Пальне · Пально-мастильні матеріали · ПММ · Смазки · Топливо
- `machinery` — Техника: Combines · Equipment · Implements · machinery · Tractors · Комбайни · Комбайны · Обладнання · Оборудование · Прицепы · Причепи · Сельхозтехника · Сільгосптехніка · Техника · Техніка · Трактори · Тракторы
- `spare-parts` — Запчасти: Bearings · Belts · Filters · Parts · spare-parts · Детали · Деталі · Запчасти · Запчастини · Ножи · Ножі · Підшипники · Подшипники · Ремені · Ремни · Фильтры · Фільтри
- `tires-wheels` — Шины и диски: Rims · Tires · tires-wheels · Tyres · Wheels · Диски · Колеса · Колёса · Покришки · Покрышки · Шини · Шини та диски · Шины · Шины и диски
- `supplies` — Расходные материалы: supplies · Витратні матеріали · Расходные материалы · Спецодежда · Спецодяг · Тара · Упаковка
- `services` — Услуги: services · Послуги · Сервис · Сервіс · Услуги
- `livestock` — Животноводство: livestock · Ветпрепарати · Ветпрепараты · Животноводство · Корма · Корми · Тваринництво
- `energy-systems` — Энергосистемы: energy-systems · Генератори · Генераторы · Енергосистеми · Солнечные панели · Сонячні панелі · Энергосистемы

## Біз танитын өлшем бірліктері

- `piece`: шт · штука · штук · штуки · од · одиниця · pcs · pc · piece · unit
- `kg`: кг · кілограм · килограмм · кілограмів · kg
- `ton`: т · t · тонна · тонн · тонни · ton · tonne
- `liter`: л · l · літр · литр · літрів · liter · litre
- `bag`: мішок · мешок · мішків · bag
- `pack`: уп · пак · пачка · упаковка · паковання · pack
- `canister`: каністра · канистра · кан · canister
- `bottle`: пляшка · бутылка · флакон · bottle
- `set`: набір · набор · set
- `hectare`: га · гектар · гектарів · ha · hectare

## Шектеулер мен идемпотенттілік

- `POST /v1/products` — 5000 × 10 min · 30 req / 10 min
- `PATCH /v1/offers` — 5000 × 60 s · 30 req / 60 s
- 20000 unresolved rows · 10 open jobs
- `sku` + ≥1 of `price`, `stock`, `moq`, `discontinued` per `PATCH /v1/offers` item

Әр нақты шақыруда `Idempotency-Key` жіберіңіз. Дәл сол кілтпен қайталау сақталған нәтижені қайтарады — сол тапсырма, сол қабылданбағандар — және ештеңе жасамайды, сондықтан сіздегі таймаут екінші прайсқа айналмайды. Қайталау алғашқы 20 қабылданбағанды және rejected_total-ды әкеледі; қалғанын қабылданбағандар эндпоинтінен алыңыз.

## Өз құралыңызда ашу

Жоғарыдағы келісім OpenAPI 3.1 құжаты ретінде де жарияланған және сол дереккөзден жасалады — сондықтан ол осы беттен ажырай алмайды. Кез келген клиентті оған бағыттасаңыз, сұрау құрастырғышын, валидацияны және біз жазбайтын `Try it` консолін аласыз.

```
https://adam.ua/kk/docs/api/openapi.json
```

- Postman · Insomnia · Bruno — Import → Link, URL-ді қойыңыз
- Swagger Editor — File → Import URL
- Клиент генераторлары — openapi-generator, oazapfts, openapi-typescript

Нақты сұрау жіберу үшін жұмыс кілті керек. Мұны Параметрлер → Интеграциялар → Сынақ алаңы бөлімінде жасаңыз — онда кілт сіздің сессияңызда қалады, кез келген адам аша алатын бетте емес.

## Әрі қарай не болады

Қабылданған жолдар каталогымызбен салыстырылып, тексеру экранына түседі. Танылған позицияны сіз сол жерде растайсыз; танылмағаны каталогқа жаңа тауар сұрауына айналады. Тексеру — адамның қадамы және ол лезде болмайды: алғашқы файлды осыны ескеріп жоспарлаңыз. Бұл сонымен қатар бір жолғы: позиция байланысқаннан кейін оның бағасы мен қалдығы `PATCH /v1/offers` арқылы жүреді және енді тексеру кезегіне тұрмайды.

## Әзірге қолдау көрсетілмейді

`currency`, `vat_rate` және `lead_time_days` екі эндпоинтте де оқылмайды, сондықтан оларды жіберу — үнсіз тастау емес, қате. Көлемге қарай баға сатылары да API арқылы өңделмейді: сатылары бар ұсыныс тұрақты `price`-ты `price_tiered` деп қабылдамайды.
