Autenticación
Casi todas las solicitudes a AstroWay API se autentican mediante el header X-Api-Key. Excepciones: 14 endpoints /v1/reference/* (signs, planets, houses, aspects, …) funcionan públicamente sin clave con un límite de 30 solicitudes / hora por IP. Si las solicitudes las hace tu servidor, envía el header X-AstroWay-Site-URL y el límite será de 300 solicitudes / hora por sitio: detalles.
Para todos los endpoints computacionales /v1/* (chart, synastry, transits, /reports, /tarot, etc.) - solo X-Api-Key. Para las operaciones de usuario /v1/me/* (GET /me, DELETE /me/account) - Bearer JWT, emitido a través de /v1/auth/login. OAuth/session-cookies no se usan en la API pública. Diccionarios de referencia /v1/reference/* - sin clave, gratis (tablas de búsqueda canónicas).
Formato de clave
Sección titulada «Formato de clave»aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_test_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_live_: production, descuenta créditos del saldoaw_test_: sandbox, las solicitudes devuelven una respuesta estable (o el cálculo real mínimo), no descuentan créditos, marcados en el dashboard por separado- Después del prefijo: 32 caracteres base62, criptográficamente aleatorios
- La clave se muestra en texto plano solo una vez al crearla. Después en el dashboard - solo los primeros y últimos 4 caracteres.
Encabezado de la solicitud
Sección titulada «Encabezado de la solicitud»POST /v1/chart HTTP/1.1Host: api.astroway.infoX-Api-Key: aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRContent-Type: application/jsonColección Postman
Sección titulada «Colección Postman»Si te resulta más cómodo Postman que curl/SDK, hay una colección lista con todos los 771 endpoints, dividida en 55 carpetas por etiquetas OpenAPI, con ejemplos de solicitudes incluidos. Auth está configurado a nivel de colección: insertas la clave en la variable apiKey una vez, y todas las solicitudes la usan.
- Documentación publicada: documenter.getpostman.com/view/54689779/2sBXqNmy3n
- Espacio de trabajo público: postman.com/astroway-info/astroway-api
- Descargar JSON: astroway-api.json (≈ 5 MB) - importa directamente en Postman o Insomnia
Colección auto-generada desde OpenAPI spec - se actualiza con cada despliegue.
Creación y gestión de claves
Sección titulada «Creación y gestión de claves»A través del dashboard:
- https://api.astroway.info/dashboard/keys
- Puedes tener hasta 10 claves activas por cuenta simultáneamente
- Cada clave tiene un nombre, campo
name(por ejemploproduction-backend,ci-tests,local-dev)
A través de la API (para integraciones self-service):
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"name": "ci-tests", "mode": "test"}'// Equivalent via @astroway/sdk: aw.client.POST('/keys', { body: { name, mode } })const r = await fetch('https://api.astroway.info/v1/keys', { method: 'POST', headers: { 'X-Api-Key': process.env.ASTROWAY_MASTER_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'ci-tests', mode: 'test' }),});
const { data: created } = await r.json();console.log(created.api_key); // shown once - store it now# Equivalent via `astroway` (PyPI): aw.post('/keys', body={'name': ..., 'mode': ...})import os, requests
r = requests.post( 'https://api.astroway.info/v1/keys', headers={'X-Api-Key': os.environ['ASTROWAY_MASTER_KEY']}, json={'name': 'ci-tests', 'mode': 'test'},)created = r.json()['data']print(created['api_key']) # shown once - store it now<?phpuse GuzzleHttp\Client;
$aw = new Client(['base_uri' => 'https://api.astroway.info/v1/']);$r = $aw->post('keys', [ 'headers' => ['X-Api-Key' => getenv('ASTROWAY_MASTER_KEY')], 'json' => ['name' => 'ci-tests', 'mode' => 'test'],]);
$created = json_decode($r->getBody(), true)['data'];echo $created['api_key']; // shown once - store it nowClaves para el navegador
Sección titulada «Claves para el navegador»Una clave típica server-only: si la solicitud con ella lleva el header Origin o Referer, devuelve 403 ORIGIN_FORBIDDEN. Esto es intencional, y es lo que captura una clave dejada accidentalmente en el frontend.
Cuando un widget o página necesita llamar a la API desde el navegador, la clave se crea inmediatamente con una política de origen. Campo origin_restriction en POST /v1/keys:
type | Qué se permite | Cuándo usar |
|---|---|---|
server-only (por defecto) | solo solicitudes sin Origin y Referer | backend, cron, CI |
public | solo los hosts listados, y la solicitud debe llevar origen | widget o página en tu dominio, clave en el código fuente |
allowlist | lo mismo que public | sintaxis obsoleta: todavía aceptada, pero ya no aparece en openapi.json |
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "name": "site-widget", "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] }, "credits_cap_cycle": 20000, "allowed_endpoints": ["chart", "public/*"] }'Reglas de coincidencia, probadas en producción:
- Hasta 20 hosts por clave. El esquema (
https://) y el puerto se ignoran, el caso no importa. www.se elimina del host entrante, por lo queexample.comcubre tambiénwww.example.com. No es necesario añadir una forma conwww.por separado, no cambia nada.*.example.comcubre subdominios (app.example.com), pero noexample.commismo. El asterisco se lista en una línea separada, como en el ejemplo anterior.- Un host que no esté en la lista recibe
403 ORIGIN_NOT_ALLOWEDcon el host en el campoincoming_origin, para que se vea qué línea falta. Refererse cuenta al mismo nivel queOrigin: el navegador lo envía donde no hayOrigin.
Cambiar la lista en una clave ya creada
Sección titulada «Cambiar la lista en una clave ya creada»PATCH /v1/keys/{id} sobrescribe la lista sin tocar la propia clave. El permiso de acceso es el mismo que en POST /v1/keys arriba; en el dashboard es la opción “Cambiar origen” en el menú de la clave.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] } }'La nueva lista entra en vigor desde la siguiente solicitud: la caché de la clave se invalida al escribir, no hace falta esperar un minuto. La propia cadena de la clave no cambia, así que no necesitas volver a publicar la página ni el backend. Después de POST /v1/keys/{id}/rotate la lista se guarda, y el valor antiguo de la clave deja de funcionar inmediatamente.
La clase de la clave no se edita, porque está codificada en la propia clave:
| Intento | Respuesta |
|---|---|
pk_ a server-only | 400: la clase es parte de la clave, debes revocarla y crear una nueva |
aw_ con lista de dominios | 400: la clave de navegador es otra clase, se crea como public |
pk_ con lista vacía | 400: una clave sin lista rechazaría cualquier solicitud |
pk_ sin presupuesto o ámbito (null) | 400: la clave para navegador siempre está limitada por ambos, pueden cambiarse pero no eliminarse |
Presupuesto de créditos por clave individual
Sección titulada «Presupuesto de créditos por clave individual»Los créditos son compartidos en toda la cuenta, así que una clave puede gastar todos. Para una clave backend eso es normal, pero para una clave en el código fuente de la página no: la lista de dominios indica de dónde se puede llamar, pero no cuánto puede costar.
credits_cap_cycle en el mismo PATCH /v1/keys/{id} limita esa clave:
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"credits_cap_cycle": 5000}'null elimina la restricción (excepto la clave pk_, cuyo presupuesto puede cambiarse pero no eliminarse). 0 significa una clave que no puede gastar nada: una forma de bloquear la clave sin revocarla. El contador es el mismo que el de los créditos y se reinicia con el ciclo de tarifa.
Cuando la clave alcanza su presupuesto, se devuelve 429 KEY_BUDGET_EXHAUSTED, incluso si la cuenta aún tiene créditos, y aun en un plan con overage: el presupuesto que se puede exceder pagando no es presupuesto. Mientras el presupuesto está definido, cada respuesta incluye X-Key-Budget-Limit y X-Key-Budget-Remaining.
Ámbito de endpoints
Sección titulada «Ámbito de endpoints»Una clave sin ámbito llama a todo lo incluido en el plan. allowed_endpoints lo restringe a una lista de rutas: exactas (chart) o espacios de nombres (embed/*). Es la tercera restricción independiente: la lista de dominios indica de dónde, el presupuesto cuánto, el ámbito qué.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"allowed_endpoints": ["embed/*", "public/moon-phase"]}'null elimina la restricción (excepto la clave pk_, cuyo ámbito es obligatorio). Una lista vacía no se acepta: se interpretaría tanto como “todo” como “nada”. Las rutas se escriben relativas a /v1, sin barra inicial, el caso no importa.
Una llamada fuera de la lista recibe 403 ENDPOINT_NOT_IN_SCOPE, y details nombra la propia lista para no tener que adivinar. El ámbito se aplica a ambas clases de claves y a /v1/public/* y /v1/embed/* igual que al resto. Las lecturas de servicio bajo él no están exentas, a diferencia de los créditos: una clave restringida a embed/* tampoco leerá su propia estadística. Esto es intencional, ya que una clave en el código fuente de la página no debe revelar al visitante los gastos de la cuenta, y gestionar la clave no lo impide: el dashboard usa sesión, no la clave.
Buenas prácticas
Sección titulada «Buenas prácticas»1. No pongas una clave server‑only en el frontend
Sección titulada «1. No pongas una clave server‑only en el frontend»Una clave típica es un secreto de nivel backend. Si termina en JS que se ejecuta en el navegador del usuario, es visible en DevTools y se filtra. Por eso esa clave responde 403 ORIGIN_FORBIDDEN a cualquier solicitud con Origin o Referer.
Si necesitas llamar desde el navegador, se hace con una clave distinta, creada con origin_restriction.type: "public": claves para el navegador. Esa clave tiene el prefijo pk_, también visible en DevTools, y esa es la idea: su valor está limitado a la lista de tus dominios, y rechaza solicitudes sin origen.
Correcto: tu backend mantiene la clave, el frontend llama a tu backend, tu backend llama a AstroWay API.
Incorrecto:
// DO NOT DO THISfetch('https://api.astroway.info/v1/chart', { headers: { 'X-Api-Key': 'aw_live_...' }, // visible in browser});2. Variables de entorno, no hardcode
Sección titulada «2. Variables de entorno, no hardcode»# .env (in .gitignore)ASTROWAY_API_KEY=aw_live_...// in codeconst key = process.env.ASTROWAY_API_KEY;if (!key) throw new Error('ASTROWAY_API_KEY is not set');3. Claves separadas para diferentes entornos
Sección titulada «3. Claves separadas para diferentes entornos»production-backend: producciónstaging-backend: stagingci-tests: pipeline CI/CDlocal-dev-maksym: desarrollo local de cada desarrollador
Si una clave se compromete, revoca solo esa, las demás siguen funcionando.
4. Rotación
Sección titulada «4. Rotación»Frecuencia recomendada - una vez cada 90 días. O inmediatamente si sospechas una fuga.
- Crea una nueva clave con el mismo
name+-v2 - Despliega en producción (paralelo a la antigua)
- Asegúrate de que el usage fluya a la nueva clave (dashboard)
- Revoca la antigua
5. Monitoreo de usage
Sección titulada «5. Monitoreo de usage»El dashboard muestra las solicitudes por clave por separado. Si de repente una clave empieza a hacer 10× más solicitudes de lo habitual, es una señal para investigar.
Puedes configurar una alerta: Settings → Notifications → Alert when daily credits > X.
Errores de autenticación
Sección titulada «Errores de autenticación»| Código | Valor |
|---|---|
401 Unauthorized | Header X-Api-Key ausente o clave no válida |
403 Forbidden | La clave es válida, pero no tiene scope para esta acción (por ejemplo, una clave normal intenta gestionar otras claves) |
403 PUBLISHABLE_KEY_UNBOUNDED | Clave pk_ sin presupuesto credits_cap_cycle o sin ámbito allowed_endpoints: establece ambos en la configuración de la clave |
402 Payment Required | Los créditos se agotaron (en Free) o la suscripción no está activa |
429 Too Many Requests | Límite de velocidad excedido (10/60/300 req/min según el plan) |
Ejemplo 401:
{ "error": { "code": "invalid_api_key", "message": "The API key provided is invalid or has been revoked.", "request_id": "8aec43e9bc749b37e998a489bbad1757" }}Modo sandbox
Sección titulada «Modo sandbox»Claves con prefijo aw_test_ funcionan en sandbox:
- No descuentan créditos
- Devuelven una respuesta estable o el cálculo real mínimo
- No afectan la estadística de producción
- Endpoints disponibles: los mismos
Útil para CI/CD, pruebas e2e y desarrollo local. Se crea a través del dashboard con un solo clic.
Siguiente
Sección titulada «Siguiente»- Créditos y límites: cómo funciona la facturación y el rate limiting
- Errores: lista completa de códigos de error