Errors
All errors are returned in a unified format:
{ "error": { "code": "invalid_api_key", "message": "The API key provided is invalid or has been revoked.", "request_id": "01HXY2A7ZM0ABCDEF", "details": null }}code— machine-readable snake_case code, stable, never changes without a major version bumpmessage— human-readable explanation in Englishrequest_id— ULID for the request, quote it when contacting supportdetails— optional object with context (for 422 — list of failed fields)
HTTP codes
Section titled “HTTP codes”| Status | Meaning |
|---|---|
200 OK | Success |
400 Bad Request | Malformed request (invalid JSON, missing required fields) |
401 Unauthorized | Missing or invalid X-Api-Key |
402 Payment Required | Credits exhausted for current period |
403 Forbidden | Key is valid but lacks permission for this action |
404 Not Found | Endpoint does not exist |
422 Unprocessable Entity | Valid JSON, but values fail Zod validation |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Server-side error — quote request_id in support request |
503 Service Unavailable | API temporarily unavailable (deploy, maintenance) |
Error codes
Section titled “Error codes”Authentication
Section titled “Authentication”| Code | HTTP | Meaning |
|---|---|---|
missing_api_key | 401 | Header X-Api-Key not sent |
invalid_api_key | 401 | Key doesn’t exist or was revoked |
insufficient_scope | 403 | Key lacks permission for this action (e.g. not a master key) |
Billing
Section titled “Billing”| Code | HTTP | Meaning |
|---|---|---|
credits_exhausted | 402 | Monthly credit budget exhausted |
subscription_inactive | 402 | Subscription canceled or expired |
overage_disabled | 402 | Overage disabled in settings and budget exhausted |
Rate limiting
Section titled “Rate limiting”| Code | HTTP | Meaning |
|---|---|---|
rate_limit_exceeded | 429 | RPM limit exceeded. Includes retry_after_seconds |
Validation
Section titled “Validation”| Code | HTTP | Meaning |
|---|---|---|
invalid_request | 400 | Invalid JSON or missing required header |
validation_failed | 422 | One or more fields failed Zod validation. details contains array of { field, message } |
Example 422:
{ "error": { "code": "validation_failed", "message": "Request body validation failed.", "request_id": "01HXY2A7ZM...", "details": [ { "field": "datetime", "message": "Invalid ISO 8601 datetime" }, { "field": "latitude", "message": "Must be between -90 and 90" } ] }}Calculation errors
Section titled “Calculation errors”| Code | HTTP | Meaning |
|---|---|---|
location_out_of_range | 422 | Coordinates outside allowed range for this endpoint (e.g. Arctic for Placidus) |
date_out_of_range | 422 | Date outside Swiss Ephemeris bounds (before -13000 or after 17000) |
house_system_unsupported | 422 | Polar region with Placidus/Koch — suggest Whole Sign or Equal |
ephemeris_error | 500 | Internal calculation error — rare, quote request_id |
Server errors
Section titled “Server errors”| Code | HTTP | Meaning |
|---|---|---|
internal_error | 500 | Unexpected error. Logged with stack trace, quote request_id |
service_unavailable | 503 | Deploy or scheduled maintenance. Retry in 30s |
dependency_failure | 503 | DB or other dependency failure. Retry with exponential backoff |
Client-side handling
Section titled “Client-side handling”type ApiError = { error: { code: string; message: string; request_id: string; details?: unknown; };};
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), });
if (!res.ok) { const body = (await res.json()) as ApiError; throw new AstrowayError(body.error.code, body.error.message, body.error.request_id); }
return res.json();}
class AstrowayError extends Error { constructor( public code: string, message: string, public requestId: string, ) { super(`[${code}] ${message} (request_id=${requestId})`); }}Codes are the stable part of the API. Switch on code, not on message (message text may change without a version bump).
Support requests
Section titled “Support requests”To contact support, send to support@astroway.info:
request_idfrom the response- Endpoint and abbreviated JSON body (redact secrets)
- Expected vs actual behavior
- Timezone and approximate request time (UTC)
Response within your plan’s SLA (48h Starter, 24h Pro, custom for Enterprise).
Was this helpful?
Thanks for the feedback.