Aller au contenu
AstroWay/api v2.254.12 · fr
tous les systèmes sont opérationnels

Erreurs

Toutes les erreurs sont renvoyées dans un format unique: ok: false plus un objet error:

{
"ok": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API key"
}
}
  • code: code UPPER_SNAKE_CASE lisible par machine, stable, il ne change pas sans version majeure. Faites votre switch dessus, pas sur message.
  • message: explication lisible par un humain, en anglais. Le texte peut être précisé sans changement de version.
  • details: facultatif. Pour INVALID_INPUT, c’est un tableau { path, message } pour chaque champ en échec. Pour INVALID_FIELD, chaque élément reçoit en plus expected avec le nom canonique du champ.
  • docs: facultatif, lien vers la section de cette page lorsque le code a une explication plus détaillée.
  • request_id: ajouté uniquement aux réponses 5xx et BAD_JSON; citez-le lorsque vous contactez le support.
StatutSignification
200 OKSuccès
400 Bad RequestJSON invalide, champs manquants ou échec de la validation Zod
401 UnauthorizedX-Api-Key absente ou invalide
402 Payment RequiredUn plan / pack supérieur est nécessaire, ou l’abonnement est inactif
403 ForbiddenClé valide, mais sans les droits (scope, origin, suspended)
404 Not FoundLa ressource, la clé ou le job n’existe pas
422 Unprocessable EntityEntrée valide, mais le moteur n’a pas pu calculer
429 Too Many RequestsRate limit dépassée, crédits ou spend-cap épuisés
500 Internal Server ErrorErreur interne, de notre côté, citez le request_id
503 Service UnavailablePasserelle IA / file d’attente temporairement indisponibles
CodeSignification
MISSING_API_KEYL’en-tête X-Api-Key n’a pas été envoyé
INVALID_API_KEYLa clé n’existe pas ou a été révoquée
MISSING_BEARERLe schéma Authorization: Bearer a été choisi, mais le jeton est absent
WRONG_AUTH_METHODX-Api-Key envoyée sur /v1/me/* (Bearer uniquement). Pour vérifier une clé: GET /v1/auth/keys/me; pour les appels API: n’importe quel /v1/* avec X-Api-Key
CodeSignification
INSUFFICIENT_SCOPELa clé n’a pas les droits pour cette action
DOMAIN_MISMATCH / FORBIDDEN_ORIGINL’origine de la requête ne figure pas dans l’allow-list de la clé
ENDPOINT_NOT_IN_SCOPELa clé est limitée à une liste d’endpoints (allowed_endpoints), et ce chemin n’y figure pas. details cite la liste
KEY_SUSPENDEDLa clé est suspendue
CodeSignification
PLAN_UPGRADE_REQUIREDL’endpoint nécessite un plan supérieur ou un pack add-on
PLAN_PACK_MISMATCHL’endpoint fait partie d’un pack absent de la clé
SUBSCRIPTION_EXPIREDLa période payée s’est terminée il y a plus de 3 jours. Pendant les 3 premiers jours après l’expiration, les requêtes sont encore servies selon le plan et portent l’en-tête X-Subscription-Grace-Ends. details contient expired_at, grace_ended_at et renew_url
CodeSignification
RATE_LIMITLimite RPM dépassée. La réponse contient l’en-tête Retry-After: <sec>
CREDITS_EXHAUSTEDLe budget mensuel de crédits est épuisé
SPEND_CAP_REACHEDLa limite de dépenses sur les endpoints IA est atteinte
KEY_BUDGET_EXHAUSTEDLa clé a épuisé son propre budget (credits_cap_cycle). Il peut encore rester des crédits sur le compte: la restriction concerne uniquement cette clé
CodeSignification
INVALID_INPUTUn ou plusieurs champs ont échoué à la validation Zod. details est un tableau { path, message }
INVALID_FIELDLe corps contient un nom de champ abrégé au lieu du nom canonique. Voir ci-dessous
MISSING_FIELDSUn champ obligatoire est absent
BAD_JSONJSON invalide dans le corps de la requête

Exemple de 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" }
]
}
}

Les endpoints de carte n’acceptent que les noms de champs complets. Les formes abrégées sont rejetées avec un 400 au lieu d’être lues en silence:

EnvoyéChamp canoniqueCe qui est attendu
latlatitudedegrés décimaux, nord positif
lng, lon, longlongitudedegrés décimaux, est positif
tz avec un nombre, tzOffset, utcOffset, timezone_offsettimezoneOffsetnombre d’heures par rapport à UTC, par ex. 5.75
tz avec un nom, timeZone, time_zonetimezonenom de zone IANA, par ex. Europe/Kyiv, ou auto

La réponse liste tous les champs trouvés en une seule fois, dans l’ordre du corps de la requête, le renommage se fait donc en une seule passe:

{
"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 indique le chemin complet, donc en synastrie on voit de quelle carte il s’agit: chart1.lat, et pas simplement lat.

Le même code est renvoyé lorsque timezone ne peut pas être analysé: valeur vide, abréviation comme EST (c’est un décalage fixe de -5 toute l’année, donc New York en juillet aura une heure d’erreur), nom absent de la base des fuseaux horaires, décalage écrit en texte comme +03:00, ou auto sans latitude ni longitude. Le message indique quoi envoyer à la place, et path pointe vers l’objet, par exemple chart2.timezone.

Deux points à prendre en compte.

Ce n’est pas une dépréciation. Les noms abrégés n’ont jamais fait partie du contrat et n’apparaissaient pas dans /openapi.json comme champs du corps. Avant le 2026-08-01, ils ne fonctionnaient pas, mais étaient ignorés en silence: les coordonnées valent zéro par défaut, donc la carte était calculée pour 0°N 0°E en UTC. L’ascendant, les maisons et tout ce qui en découle étaient faux, et la réponse ne le signalait pas. C’est pourquoi les formes abrégées ne seront pas réacceptées: deux noms pour un même champ pour toujours, et tz est en plus ambigu (nombre ou nom de zone).

Un point imbriqué, c’est autre chose. Dans /v1/acg-zones, /v1/acg/by-category, /v1/ccg-analysis et /v1/eclipse-analysis, l’objet point: { lat, lng } utilise des noms de champs déclarés, et ils sont acceptés.

Coordonnées absentes: 400 à partir du 2026-11-09

Section intitulée « Coordonnées absentes: 400 à partir du 2026-11-09 »

Le bon nom de champ n’est que la moitié du travail. Un corps sans latitude ni longitude renvoyait lui aussi 200, car les coordonnées valaient zéro par défaut, et la réponse décrivait 0°N 0°E.

Jusqu’au 2026-11-09, une telle requête fonctionne, mais la réponse porte Deprecation: true, Sunset, Warning et le champ _warning dans le corps. À partir du 2026-11-09, ce sera 400 INVALID_INPUT avec latitude is required, in decimal degrees.

Des valeurs explicites latitude: 0, longitude: 0 restent valides: le problème est le champ absent, pas la valeur. timezoneOffset garde zéro par défaut, car zéro y signifie UTC. city ne remplace pas les coordonnées: personne ne le géocode. La vérification ne s’applique qu’aux objets qui portent à la fois date et time.

CodeSignification
CALCULATION_ERROREntrée valide, mais le moteur n’a pas pu calculer (par exemple, une latitude polaire pour Placidus). Essayez Whole Sign / Equal ou une autre date.
CodeHTTPSignification
INTERNAL_ERROR500Erreur inattendue. Nous la journalisons avec la stack trace, citez le request_id
GATEWAY_UNAVAILABLE / AI_UNAVAILABLE / LLM_UNAVAILABLE503Passerelle IA indisponible. Retry avec backoff exponentiel
QUEUE_UNAVAILABLE503La file des tâches d’arrière-plan est indisponible
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})` : ''}`);
}
}

Faites votre switch sur code, pas sur message. Les SDK officiels (@astroway/sdk, astroway) lèvent des sous-classes d’erreurs typées selon le statut HTTP (AuthenticationError, RateLimitError, BadRequestError …), vous n’aurez donc pas à écrire le code de traitement.

Pour nous contacter, envoyez à support@astroway.info:

  1. Le request_id de la réponse (s’il s’agit d’un 5xx)
  2. L’endpoint et le corps JSON abrégé (sans secrets)
  3. Le comportement attendu vs le comportement réel
  4. Le fuseau horaire et l’heure approximative de la requête (UTC)

Réponse dans le cadre du SLA de votre plan (48 h pour Starter, 24 h pour Pro, sur mesure pour Enterprise).

Utile?
Proposer une modification

Dernière mise à jour :