Skip to content
AstroWay/api v2.77.14 · docs
all systems operational

Errors

Every error comes back in a single shape — ok: false plus an error object:

{
"ok": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API key"
}
}
  • code — machine-readable UPPER_SNAKE_CASE code, stable, never changes without a major bump. Switch on this, not on message.
  • message — human-readable explanation in English. Wording may be refined without a bump.
  • details — optional. For INVALID_INPUT it’s an array of { path, message } for each failed field.
  • request_id — added only to 5xx and BAD_JSON responses; quote it when contacting support.
StatusMeaning
200 OKSuccess
400 Bad RequestMalformed JSON, missing fields, or failed Zod validation
401 UnauthorizedMissing or invalid X-Api-Key
402 Payment RequiredA higher plan / add-on pack is required, or the subscription is inactive
403 ForbiddenKey is valid but lacks permission (scope, origin, suspended)
404 Not FoundResource, key, or job does not exist
422 Unprocessable EntityInput is valid but the engine could not compute it
429 Too Many RequestsRate limit exceeded, credits exhausted, or spend cap hit
500 Internal Server ErrorOur fault — quote request_id
503 Service UnavailableAI gateway / queue temporarily down
CodeMeaning
MISSING_API_KEYThe X-Api-Key header was not sent
INVALID_API_KEYKey does not exist or was revoked
MISSING_BEARERAuthorization: Bearer scheme selected but token missing
CodeMeaning
INSUFFICIENT_SCOPEKey lacks permission for this action
DOMAIN_MISMATCH / FORBIDDEN_ORIGINRequest origin is not in the key’s allow-list
KEY_SUSPENDEDKey has been suspended
CodeMeaning
PLAN_UPGRADE_REQUIREDEndpoint requires a higher plan or an add-on pack
PLAN_PACK_MISMATCHEndpoint is in a pack the key doesn’t have
SUBSCRIPTION_EXPIREDSubscription cancelled or expired
CodeMeaning
RATE_LIMITRPM limit exceeded. Response carries a Retry-After: <sec> header
CREDITS_EXHAUSTEDMonthly credit budget used up
SPEND_CAP_REACHEDAI-endpoint spend cap reached
CodeMeaning
INVALID_INPUTOne or more fields failed Zod validation. details is an array of { path, message }
MISSING_FIELDSA required field is missing
BAD_JSONMalformed JSON in the request body

Example 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" }
]
}
}
CodeMeaning
CALCULATION_ERRORInput is valid but the engine could not compute (e.g. a polar latitude for Placidus). Try Whole Sign / Equal or a different date.
CodeHTTPMeaning
INTERNAL_ERROR500Unexpected error. Logged with a stack trace — quote request_id
GATEWAY_UNAVAILABLE / AI_UNAVAILABLE / LLM_UNAVAILABLE503AI gateway down. Retry with exponential backoff
QUEUE_UNAVAILABLE503Background-job queue down
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 on code, not on message. The official SDKs (@astroway/sdk, astroway) throw typed error subclasses by HTTP status (AuthenticationError, RateLimitError, BadRequestError, …), so you won’t need to write this yourself.

To open a ticket, email support@astroway.info:

  1. The request_id from the response (for 5xx)
  2. The endpoint and a trimmed JSON body (no secrets)
  3. Expected vs actual behavior
  4. Timezone and approximate request time (UTC)

Replies land within your plan’s SLA (48 h Starter, 24 h Pro, custom for Enterprise).

Was this helpful?
Suggest an edit

Last updated: