---
title: "Помилки · API Reference: документація AOA API"
description: "Формат помилок публічного API AOA: коди, HTTP-статуси і що робити з кожним."
canonical: "https://aoa.com.ua/docs/api-reference/errors"
---

# Помилки

Формат помилок публічного API AOA: коди, HTTP-статуси і що робити з кожним.

Помилки приходять у тому самому конверті, що й успішні відповіді. Поле `code` — стабільне машинне значення, за ним і варто розгалужувати логіку. Поле `message` призначене для людини й може змінюватись.

```json
{
  "error": {
    "code": "conflict",
    "message": "Залишилось лише 3 квитки"
  }
}
```

## Коди помилок

| Код | HTTP | Коли трапляється |
| --- | --- | --- |
| `bad_request` | 400 | Некоректні дані запиту: невідома категорія, кількість поза межами 1–20, відсутній Idempotency-Key. |
| `unauthorized` | 401 | Ключ відсутній там, де потрібен, невірний або відкликаний. |
| `forbidden` | 403 | Ключ дійсний, але не має потрібного дозволу. Також — спроба глянути чуже замовлення. |
| `not_found` | 404 | Події чи замовлення немає, або подія не опублікована. |
| `conflict` | 409 | Стан завадив дії: квитків не вистачило, оплата в події не налаштована. |
| `gone` | 410 | Подія існувала, але її видалено. На відміну від 404, повторювати запит немає сенсу ніколи. |
| `rate_limited` | 429 | Вичерпано ліміт запитів. |
| `internal_error` | 500 | Збій на нашому боці. Можна повторити з паузою. |

## Що варто повторювати

| Код | Повторювати? |
| --- | --- |
| `rate_limited` | Так, через Retry-After. |
| `internal_error` | Так, з наростаючою паузою, до 3 спроб. |
| `conflict` | Тільки після перевірки актуальних залишків — сам собою повтор не допоможе. |
| `bad_request` | Ні. Запит треба виправити. |
| `unauthorized` | Ні. Проблема в ключі. |
| `forbidden` | Ні. Потрібно розширити дозволи ключа. |
| `not_found` | Ні. |
| `gone` | Ні. Приберіть подію зі свого каталогу. |

```javascript
const response = await fetch(url, options);
const body = await response.json();

if (body.error) {
  switch (body.error.code) {
    case 'rate_limited':
      // Почекати Retry-After і повторити
      break;
    case 'conflict':
      // Місць не вистачило — показати актуальні залишки
      break;
    case 'unauthorized':
    case 'forbidden':
      // Проблема з ключем: повторювати не варто
      break;
    default:
      // Логувати і показати загальне повідомлення
  }
}
```

## Мова повідомлень

Не розбирайте `message`

Частина повідомлень приходить українською — зокрема ті, що стосуються залишку квитків («Залишилось лише 3 квитки»). Показувати їх покупцеві можна, а от будувати логіку на тексті не варто: він може змінитись будь-коли. Розгалужуйтесь лише за

`code`

.

## Окремі випадки

### 409 «Payments are not configured for this event»

Це не збій. Організатор події ще не підключив приймання оплат, тож продати квиток неможливо. Безкоштовні події при цьому працюють нормально. Позначайте таку подію як недоступну для продажу, повторні спроби нічого не змінять.

### 404 замість 403 на чужі замовлення

Запит чужого `paymentId` дає `404`, а не `403`. Так зроблено навмисно: інакше перебором ідентифікаторів можна було б дізнатися, які замовлення існують.

### 404 на неопубліковану подію

Чернетка чи прихована подія теж віддає `404`, хоча технічно існує. Через API видно лише опубліковані публічні події.
