Помилки
Deze inhoud is nog niet vertaald.
Усі помилки повертаються у єдиному форматі - ok: false плюс об’єкт error:
{ "ok": false, "error": { "code": "INVALID_API_KEY", "message": "Invalid API key" }}code: машиночитнийUPPER_SNAKE_CASEкод, стабільний, не змінюється без мажорного бампа. Свіч по ньому, не поmessage.message: людиночитне пояснення, англійською. Текст може уточнюватись без бампа.details: опціональний. ДляINVALID_INPUTце масив{ path, message }по кожному проваленому полю. ДляINVALID_FIELDдо кожного елемента додаєтьсяexpectedз канонічним ім’ям поля.docs: опціональний, посилання на розділ цієї сторінки, коли для коду є докладніше пояснення.request_id: додається лише до5xxтаBAD_JSONвідповідей; цитуй його при зверненні в підтримку.
HTTP-коди
Section titled “HTTP-коди”| Статус | Значення |
|---|---|
200 OK | Успіх |
400 Bad Request | Битий JSON, відсутні поля або провалена Zod-валідація |
401 Unauthorized | Відсутній або невалідний X-Api-Key |
402 Payment Required | Потрібен вищий тариф / пак, або підписка неактивна |
403 Forbidden | Ключ валідний, але немає прав (scope, origin, suspended) |
404 Not Found | Ресурс, ключ або job не існує |
422 Unprocessable Entity | Вхід валідний, але рушій не зміг порахувати |
429 Too Many Requests | Перевищено rate limit, вичерпано кредити або spend-cap |
500 Internal Server Error | Внутрішня помилка - з нашого боку, цитуй request_id |
503 Service Unavailable | AI-шлюз / черга тимчасово недоступні |
Error codes
Section titled “Error codes”Автентифікація (401)
Section titled “Автентифікація (401)”| Код | Значення |
|---|---|
MISSING_API_KEY | Header X-Api-Key не надіслано |
INVALID_API_KEY | Ключ не існує або revoked |
MISSING_BEARER | Схема Authorization: Bearer обрана, але токен відсутній |
WRONG_AUTH_METHOD | На /v1/me/* (Bearer-only) надіслано X-Api-Key. Для перевірки ключа - GET /v1/auth/keys/me; для викликів API - будь-який /v1/* з X-Api-Key |
Права (403)
Section titled “Права (403)”| Код | Значення |
|---|---|
INSUFFICIENT_SCOPE | Ключ не має прав на цю дію |
DOMAIN_MISMATCH / FORBIDDEN_ORIGIN | Origin запиту не в allow-list ключа |
KEY_SUSPENDED | Ключ призупинено |
Білінг (402)
Section titled “Білінг (402)”| Код | Значення |
|---|---|
PLAN_UPGRADE_REQUIRED | Ендпоінт потребує вищого тарифу або add-on пака |
PLAN_PACK_MISMATCH | Ендпоінт входить у пак, якого немає на ключі |
SUBSCRIPTION_EXPIRED | Підписка касована або expired |
Rate limiting та кредити (429)
Section titled “Rate limiting та кредити (429)”| Код | Значення |
|---|---|
RATE_LIMIT | Перевищено ліміт RPM. Відповідь містить header Retry-After: <sec> |
CREDITS_EXHAUSTED | Місячний бюджет кредитів вичерпано |
SPEND_CAP_REACHED | Досягнуто ліміт витрат на AI-ендпоінти |
Валідація (400)
Section titled “Валідація (400)”| Код | Значення |
|---|---|
INVALID_INPUT | Одне або кілька полів провалили Zod-валідацію. details - масив { path, message } |
INVALID_FIELD | Тіло містить коротке ім’я поля замість канонічного. Див. нижче |
MISSING_FIELDS | Відсутнє обов’язкове поле |
BAD_JSON | Битий JSON у тілі запиту |
Приклад 400:
{ "ok": false, "error": { "code": "INVALID_INPUT", "message": "Validation failed: date: Invalid input: expected string, received undefined", "details": [ { "path": "date", "message": "Invalid input: expected string, received undefined" }, { "path": "time", "message": "Invalid input: expected string, received undefined" } ] }}INVALID_FIELD
Section titled “INVALID_FIELD”Chart-ендпоінти приймають лише повні імена полів. Короткі форми відхиляються з 400, а не читаються мовчки:
| Надіслано | Канонічне поле | Що очікується |
|---|---|---|
lat | latitude | десяткові градуси, північ додатна |
lng, lon, long | longitude | десяткові градуси, схід додатний |
tz, timezone, timeZone, time_zone | timezoneOffset | число годин від UTC, напр. 5.75, не назва зони |
Відповідь перелічує всі знайдені поля за один раз, у порядку тіла запиту, тож перейменування робиться одним проходом:
{ "ok": false, "error": { "code": "INVALID_FIELD", "message": "Unsupported fields: \"tz\", \"lat\", \"lng\". Rename them to \"timezoneOffset\", \"latitude\", \"longitude\". See details for what each one expects.", "details": [ { "path": "tz", "expected": "timezoneOffset", "message": "numeric hours from UTC, e.g. 5.75, not a timezone name" }, { "path": "lat", "expected": "latitude", "message": "decimal degrees, north positive" }, { "path": "lng", "expected": "longitude", "message": "decimal degrees, east positive" } ], "docs": "https://api.astroway.info/en/errors/#invalid_field" }}path вказує повний шлях, тому в synastry видно, чия саме карта: chart1.lat, а не просто lat.
Дві речі, на які варто зважати.
Це не депрекація. Короткі імена ніколи не були в контракті й не фігурували в /openapi.json як поля тіла. До 2026-08-01 вони не працювали, а мовчки ігнорувалися: координати мають типовий нуль, тому карта рахувалася для 0°N 0°E за UTC. Асцендент, доми і все похідне від них були неправильні, а відповідь про це не повідомляла. Тому короткі форми не приймаються назад: два імені на одне поле назавжди, а tz до того ж неоднозначний (число чи назва зони).
Вкладений point це інша річ. У /v1/acg-zones, /v1/acg/by-category, /v1/ccg-analysis і /v1/eclipse-analysis об’єкт point: { lat, lng } це задекларовані імена полів, і вони проходять.
Відсутні координати: 400 з 2026-11-09
Section titled “Відсутні координати: 400 з 2026-11-09”Правильне ім’я поля це половина справи. Тіло без latitude і longitude теж давало 200, бо координати мали типовий нуль, і відповідь описувала 0°N 0°E.
До 2026-11-09 такий запит працює, але відповідь несе Deprecation: true, Sunset, Warning і поле _warning у тілі. З 2026-11-09 це 400 INVALID_INPUT з latitude is required, in decimal degrees.
Явні latitude: 0, longitude: 0 валідні й далі: питання у відсутньому полі, а не в значенні. timezoneOffset типовий нуль зберігає, бо нуль там означає UTC. city координат не замінює: його ніхто не геокодує. Перевірка застосовується лише до об’єктів, які несуть одночасно date і time.
Розрахункові помилки (422)
Section titled “Розрахункові помилки (422)”| Код | Значення |
|---|---|
CALCULATION_ERROR | Вхід валідний, але рушій не зміг порахувати (наприклад, полярна широта для Placidus). Спробуй Whole Sign / Equal або іншу дату. |
Серверні
Section titled “Серверні”| Код | HTTP | Значення |
|---|---|---|
INTERNAL_ERROR | 500 | Неочікувана помилка. Логуємо зі stack trace, цитуй request_id |
GATEWAY_UNAVAILABLE / AI_UNAVAILABLE / LLM_UNAVAILABLE | 503 | AI-шлюз недоступний. Retry з експоненційним backoff |
QUEUE_UNAVAILABLE | 503 | Черга фонових задач недоступна |
Обробка в клієнтському коді
Section titled “Обробка в клієнтському коді”type ApiError = { ok: false; error: { code: string; message: string; details?: unknown; request_id?: string; };};
async function chart(input: ChartInput) { const res = await fetch('https://api.astroway.info/v1/chart', { method: 'POST', headers: { 'X-Api-Key': process.env.ASTROWAY_API_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify(input), });
const body = await res.json(); if (!body.ok) { throw new AstrowayError(body.error.code, body.error.message, body.error.request_id); }
return body.data;}
class AstrowayError extends Error { constructor( public code: string, message: string, public requestId?: string, ) { super(`[${code}] ${message}${requestId ? ` (request_id=${requestId})` : ''}`); }}Свіч по code, не по message. Офіційні SDK (@astroway/sdk, astroway) кидають типізовані підкласи помилок за HTTP-статусом (AuthenticationError, RateLimitError, BadRequestError …), тож код обробки писати не доведеться.
Запит підтримки
Section titled “Запит підтримки”Для звернення надішли на support@astroway.info:
request_idз відповіді (якщо це5xx)- Ендпоінт і скорочений JSON body (без секретів)
- Очікувана поведінка vs фактична
- Часовий пояс і приблизний час запиту (UTC)
Відповідь - у межах SLA твого плану (48 год Starter, 24 год Pro, власна для Enterprise).