Fouten
Alle fouten komen terug in één uniform formaat - ok: false plus een object error:
{ "ok": false, "error": { "code": "INVALID_API_KEY", "message": "Invalid API key" }}code: een machineleesbare code inUPPER_SNAKE_CASE, stabiel, verandert niet zonder major-bump. Switch hierop, niet opmessage.message: een leesbare uitleg, in het Engels. De tekst kan zonder bump worden verfijnd.details: optioneel. VoorINVALID_INPUTis dit een array{ path, message }per veld dat faalde. VoorINVALID_FIELDkrijgt elk element eenexpectedmet de canonieke veldnaam.docs: optioneel, een link naar een sectie van deze pagina als er voor de code een uitgebreidere uitleg is.request_id: wordt alleen toegevoegd aan5xx- enBAD_JSON-responses; vermeld het als je contact opneemt met support.
HTTP-codes
Section titled “HTTP-codes”| Status | Betekenis |
|---|---|
200 OK | Succes |
400 Bad Request | Kapotte JSON, ontbrekende velden of mislukte Zod-validatie |
401 Unauthorized | X-Api-Key ontbreekt of is ongeldig |
402 Payment Required | Een hoger plan / pack is nodig, of het abonnement is niet actief |
403 Forbidden | De sleutel is geldig, maar heeft geen rechten (scope, origin, suspended) |
404 Not Found | Resource, sleutel of job bestaat niet |
422 Unprocessable Entity | De invoer is geldig, maar de engine kon het niet berekenen |
429 Too Many Requests | Rate limit overschreden, credits of spend-cap op |
500 Internal Server Error | Interne fout - aan onze kant, vermeld de request_id |
503 Service Unavailable | AI-gateway / wachtrij tijdelijk niet beschikbaar |
Error codes
Section titled “Error codes”Authenticatie (401)
Section titled “Authenticatie (401)”| Code | Betekenis |
|---|---|
MISSING_API_KEY | De header X-Api-Key is niet meegestuurd |
INVALID_API_KEY | De sleutel bestaat niet of is revoked |
MISSING_BEARER | Het schema Authorization: Bearer is gekozen, maar het token ontbreekt |
WRONG_AUTH_METHOD | Naar /v1/me/* (alleen Bearer) is X-Api-Key gestuurd. Om een sleutel te controleren - GET /v1/auth/keys/me; voor API-aanroepen - elke /v1/* met X-Api-Key |
Rechten (403)
Section titled “Rechten (403)”| Code | Betekenis |
|---|---|
INSUFFICIENT_SCOPE | De sleutel heeft geen rechten voor deze actie |
DOMAIN_MISMATCH / FORBIDDEN_ORIGIN | De origin van het verzoek staat niet in de allow-list van de sleutel |
ENDPOINT_NOT_IN_SCOPE | De sleutel is beperkt tot een lijst van endpoints (allowed_endpoints), en dit pad staat er niet in. details noemt de lijst |
KEY_SUSPENDED | De sleutel is opgeschort |
Billing (402)
Section titled “Billing (402)”| Code | Betekenis |
|---|---|
PLAN_UPGRADE_REQUIRED | Het endpoint vereist een hoger plan of een add-on pack |
PLAN_PACK_MISMATCH | Het endpoint hoort bij een pack dat de sleutel niet heeft |
SUBSCRIPTION_EXPIRED | De betaalde periode is meer dan 3 dagen geleden afgelopen. In de eerste 3 dagen na afloop worden verzoeken nog volgens het plan bediend en dragen ze de header X-Subscription-Grace-Ends. details bevat expired_at, grace_ended_at en renew_url |
Rate limiting en credits (429)
Section titled “Rate limiting en credits (429)”| Code | Betekenis |
|---|---|
RATE_LIMIT | RPM-limiet overschreden. De response bevat de header Retry-After: <sec> |
CREDITS_EXHAUSTED | Het maandelijkse creditbudget is op |
SPEND_CAP_REACHED | De uitgavenlimiet voor AI-endpoints is bereikt |
KEY_BUDGET_EXHAUSTED | De sleutel heeft zijn eigen budget (credits_cap_cycle) opgebruikt. Op het account kunnen nog credits over zijn: de beperking geldt alleen voor deze sleutel |
Validatie (400)
Section titled “Validatie (400)”| Code | Betekenis |
|---|---|
INVALID_INPUT | Een of meer velden zijn gezakt voor de Zod-validatie. details - een array { path, message } |
INVALID_FIELD | De body bevat een korte veldnaam in plaats van de canonieke. Zie hieronder |
MISSING_FIELDS | Een verplicht veld ontbreekt |
BAD_JSON | Kapotte JSON in de request-body |
Voorbeeld van 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-endpoints accepteren alleen volledige veldnamen. Korte vormen worden met 400 geweigerd in plaats van stilletjes gelezen:
| Verstuurd | Canoniek veld | Wat verwacht wordt |
|---|---|---|
lat | latitude | decimale graden, noord positief |
lng, lon, long | longitude | decimale graden, oost positief |
tz met een getal, tzOffset, utcOffset, timezone_offset | timezoneOffset | aantal uren ten opzichte van UTC, bijv. 5.75 |
tz met een naam, timeZone, time_zone | timezone | IANA-zonenaam, bijv. Europe/Kyiv, of auto |
De response somt alle gevonden velden in één keer op, in de volgorde van de request-body, dus hernoemen doe je in één ronde:
{ "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; a zone name goes in timezone" }, { "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 geeft het volledige pad, dus in synastry zie je om wiens horoscoop het gaat: chart1.lat, niet alleen lat.
Dezelfde code komt terug als timezone niet te parsen is: een lege waarde, een afkorting zoals EST (dat is het hele jaar vast -5, dus New York komt in juli een uur verkeerd uit), een naam die niet in de tijdzonedatabase staat, een verschuiving die als tekst is geschreven, zoals +03:00, of auto zonder latitude en longitude. De melding zegt wat je in plaats daarvan moet sturen, en path wijst naar het object, bijvoorbeeld chart2.timezone.
Twee dingen om rekening mee te houden.
Dit is geen deprecation. Korte namen hebben nooit in het contract gestaan en kwamen in /openapi.json niet voor als body-velden. Tot 2026-08-01 werkten ze niet, maar werden ze stilletjes genegeerd: coördinaten hebben standaard nul, dus de horoscoop werd berekend voor 0°N 0°E in UTC. De ascendant, de huizen en alles wat daarvan afgeleid is, waren fout, en de response meldde dat niet. Daarom worden korte vormen niet opnieuw geaccepteerd: twee namen voor één veld is voor altijd, en tz is bovendien dubbelzinnig (getal of zonenaam).
Een geneste point is iets anders. In /v1/acg-zones, /v1/acg/by-category, /v1/ccg-analysis en /v1/eclipse-analysis is het object point: { lat, lng } een set gedeclareerde veldnamen, en die gaan door.
Ontbrekende coördinaten: 400 vanaf 2026-11-09
Section titled “Ontbrekende coördinaten: 400 vanaf 2026-11-09”De juiste veldnaam is maar de helft. Een body zonder latitude en longitude gaf ook 200, omdat coördinaten standaard nul waren, en de response beschreef 0°N 0°E.
Tot 2026-11-09 werkt zo’n verzoek, maar de response draagt Deprecation: true, Sunset, Warning en een veld _warning in de body. Vanaf 2026-11-09 is het 400 INVALID_INPUT met latitude is required, in decimal degrees.
Expliciete latitude: 0, longitude: 0 blijven geldig: het gaat om het ontbrekende veld, niet om de waarde. timezoneOffset houdt de standaardwaarde nul, omdat nul daar UTC betekent. city vervangt geen coördinaten: niemand geocodeert het. De controle geldt alleen voor objecten die tegelijk date en time bevatten.
Rekenfouten (422)
Section titled “Rekenfouten (422)”| Code | Betekenis |
|---|---|
CALCULATION_ERROR | De invoer is geldig, maar de engine kon het niet berekenen (bijvoorbeeld een polaire breedte voor Placidus). Probeer Whole Sign / Equal of een andere datum. |
Serverfouten
Section titled “Serverfouten”| Code | HTTP | Betekenis |
|---|---|---|
INTERNAL_ERROR | 500 | Onverwachte fout. We loggen hem met stack trace, vermeld de request_id |
GATEWAY_UNAVAILABLE / AI_UNAVAILABLE / LLM_UNAVAILABLE | 503 | AI-gateway niet beschikbaar. Retry met exponentiële backoff |
QUEUE_UNAVAILABLE | 503 | De wachtrij voor achtergrondtaken is niet beschikbaar |
Afhandeling in clientcode
Section titled “Afhandeling in clientcode”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})` : ''}`); }}Switch op code, niet op message. De officiële SDK’s (@astroway/sdk, astroway) gooien getypeerde subklassen van fouten op basis van de HTTP-status (AuthenticationError, RateLimitError, BadRequestError …), dus afhandelingscode hoef je niet zelf te schrijven.
Supportverzoek
Section titled “Supportverzoek”Stuur voor een supportverzoek naar support@astroway.info:
- De
request_iduit de response (als het een5xxis) - Het endpoint en een ingekorte JSON-body (zonder geheimen)
- Verwacht gedrag vs werkelijk gedrag
- Tijdzone en het ongeveer tijdstip van het verzoek (UTC)
Antwoord - binnen de SLA van je plan (48 uur Starter, 24 uur Pro, eigen SLA voor Enterprise).