# API 401 қайтарады — кілт қабылданбай жатыр

> 401 unauthorized дегені — сұрауыңызда жарамды API кілт жоқ. Себептері, тексеру реті және жұмыс істейтін curl мысалы. Көбіне тақырып атауы немесе Bearer префиксі кінәлі.

## Қысқаша

`401` және `{"error":"unauthorized"}` дегені бір ғана нәрсені білдіреді: **сұрауда жарамды API кілт келмеді**. Бұл счётқа, сомаға, кассирге, тарифке қатысы жоқ қате — сұрау денесі дұрыс болса да 401 келе береді. Ең жиі үш себеп: `X-API-Key` тақырыбы мүлде жіберілмеген, оның орнына `Authorization: Bearer` жазылған, немесе кілт кабинетте жойылған. Төмендегі бес қадамнан өтсеңіз, себебі табылады.

## Симптом бойынша себеп

| Не көріп тұрсыз | Себебі | Шешімі |
|---|---|---|
| `401 unauthorized`, барлық эндпоинтте | `X-API-Key` тақырыбы жоқ | Тақырыпты қосыңыз |
| `401 unauthorized`, кеше істеп тұрған кілтпен | Кілт кабинеттен жойылған немесе өшірілген | Кабинеттен жаңа кілт жасап, интеграцияны жаңартыңыз |
| `401`, ал Postman-да сол кілт істейді | Кодыңыз кілтті басқа айнымалыдан алып тұр, бос жол келеді | `.env` жүктелген бе, қызмет қайта іске қосылған ба, тексеріңіз |
| `422 invalid_api_key` | Кілттің пішімі бұзылған | Кілт `qp_live_…` немесе `qp_test_…` болуы керек |
| `401`, кілт дұрыс сияқты | Кілт `Bearer` префиксімен жіберілген | Префикссіз, таза кілтті жіберіңіз |

`401` бен `403` екеуі екі басқа нәрсе. 401 — «кім екеніңізді білмеймін». 403 — «кім екеніңізді білемін, бірақ бұған құқығыңыз жоқ». Егер 403 келсе, [API 403 қайтарады](/kb/api-403) бетін қараңыз.

## Тексеру реті

**1. Тақырыптың атауын дәл салыстырыңыз.** Ол — `X-API-Key`. `X-Api-Key` де жарайды (HTTP тақырыптарында регистр маңызды емес), бірақ `X_API_KEY`, `ApiKey`, `api-key` жарамайды. Кейбір фреймворктер астыңғы сызықты сызықшаға айналдырмайды — тақырыпты дәл солай жазыңыз.

**2. Bearer жазбаңыз.** Бұл ең жиі кездесетін қате. Біздің API `Authorization: Bearer …` схемасын пайдаланбайды. Кілт `X-API-Key` тақырыбында, префикссіз, таза күйінде келуі керек.

```
Дұрыс:  X-API-Key: qp_live_xxxxxxxxxxxxxxxx
Қате:   Authorization: Bearer qp_live_xxxxxxxxxxxxxxxx
Қате:   X-API-Key: Bearer qp_live_xxxxxxxxxxxxxxxx
```

**3. Кілттің өзін көзбен тексеріңіз.** Ол `qp_live_` немесе `qp_test_` деп басталуы керек. Көшіргенде басына немесе аяғына бос орын, жол ауыстыру таңбасы, тырнақша түсіп кетуі жиі болады. Кодта кесіп алыңыз:

```js
const key = (process.env.QUTPAY_API_KEY || '').trim();
if (!key.startsWith('qp_')) throw new Error('API кілт жүктелмеген');
```

Мұндай тексеру қызмет іске қосылған кезде істесе, 401-ді өндірісте емес, бірден көресіз.

**4. Кілт кабинетте бар ма, қараңыз.** [Кабинет](https://qut.kz/app) → Интеграциялар бөлімінде кілттер тізімі тұрады. Жойылған кілт қалпына келмейді — жаңасын жасап, интеграцияны жаңарту керек.

**5. Кілт қай режимнің кілті екенін тексеріңіз.** `qp_test_` — sandbox, `qp_live_` — нақты режим. Интеграцияңыз бір режимде, кілт екінші режимде болса, шатасу осыдан басталады. Sandbox пен live айырмашылығы туралы: [Qut Pay деген не](/kb/what-is-qutpay).

## Жұмыс істейтін мысал

Кілттің өзі жарамды ма, жоқ па — соны бір сұраумен білесіз:

```bash
curl -i https://api.qut.kz/api/v1/invoices \
  -H "X-API-Key: qp_test_СІЗДІҢ_КІЛТІҢІЗ"
```

`200` келсе — кілт жарамды, мәселе сіздің кодыңыздың тақырып жіберу тәсілінде. `401` келсе — мәселе кілттің өзінде.

Счёт жасау:

```bash
curl -i -X POST https://api.qut.kz/api/v1/invoices \
  -H "X-API-Key: qp_test_СІЗДІҢ_КІЛТІҢІЗ" \
  -H "Content-Type: application/json" \
  -d '{"amount":1000,"description":"Сынақ счёт"}'
```

Node.js:

```js
const res = await fetch('https://api.qut.kz/api/v1/invoices', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.QUTPAY_API_KEY.trim(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ amount: 1000, description: 'Сынақ счёт' }),
});
```

PHP-де cURL қолдансаңыз, тақырып жолын толық жазу керек:

```php
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . trim(getenv('QUTPAY_API_KEY')),
  'Content-Type: application/json',
]);
```

## Жиі кездесетін бес қателік

- **Кілт кодта жазулы, ал серверде `.env` жаңартылмаған.** Жаңа кілт жасағанда қызметті қайта іске қосуды ұмытпаңыз.
- **Прокси немесе CDN тақырыпты кесіп тастаған.** Кейбір баптауларда белгісіз `X-` тақырыптары өткізілмейді. Сұрауды тікелей жіберіп көріңіз.
- **Кілт браузердегі кодқа салынған.** Ол жерде тұруға болмайды, әрі көбіне CORS салдарынан тақырып жетпей қалады. Кілт тек серверде болуы керек.
- **Екі кілт шатасқан.** Бір жерде ескі, бір жерде жаңа кілт қалып қояды. Барлық орында біреуін қолданыңыз.
- **Кілт жойылғанын біреу айтпаған.** Командада бірнеше адам болса, кілттерді кім жасап, кім жойғанын біліп отырыңыз.

## Егер бәрі дұрыс болса

Кілт жаңа, тақырып дұрыс, бос орын жоқ, ал 401 келе берсе — мәселенің біздің жақта екенін тексеріңіз:

```bash
curl -s https://api.qut.kz/api/v1/status
```

Бұл эндпоинт кілтсіз де жауап береді. Ол жауап бермей тұрса, қате сіздің кілтіңізде емес. Қалай ажырату керек: [Мәселе менде ме, Kaspi-де ме](/kb/is-it-us-or-kaspi).

Қолдауға жазғанда мыналарды қоса жіберіңіз: кілттің **алғашқы он таңбасы** (толық кілтті ешқашан жібермеңіз), сұрау уақыты, эндпоинт атауы және жауаптың толық мәтіні.

## Жиі қойылатын сұрақтар

**401 келгенде қайталауға бола ма?** Мәні жоқ. Сұрауды өзгертпей қайталасаңыз, нәтиже сол болады. Қайталау циклі тек тәуліктік қорғаныс шегіне жеткізеді.

**Кілтті ауыстырсам, ескі счёттарым жоғала ма?** Жоқ. Счёттар ұйымға тиесілі, кілтке емес. Жаңа кілтпен бәрін бұрынғыдай көресіз.

**Кілт сыртқа шығып кетсе не істеу керек?** Бірден кабинеттен жойып, жаңасын жасаңыз. Жойылған кілтпен ешкім счёт жасай алмайды.

**Бір кілтпен бірнеше сервер жұмыс істей ала ма?** Иә. Бірақ әр нүктеге бөлек кілт берген ыңғайлы — сонда қайсысы қандай трафик жасап тұрғанын көресіз.

**Sandbox кілтімен нақты счёт жасауға бола ма?** Жоқ. `qp_test_` кілт тек sandbox-та жұмыс істейді, нақты ақша жүрмейді.
