La API de SkySolver
Resuelve la astrometría de una foto del cielo nocturno, o de una lista de sus estrellas, y dibuja su anotación, como SVG para superponer a la foto o como JSON para dibujarla tú mismo; o resuelve una foto de la Luna: los mismos solucionadores y las mismas anotaciones que el taller. Es gratuita y no necesita clave, y los programas hechos para el solucionador en línea de Astrometry.net, como N.I.N.A. y KStars, pueden usarla cambiando una sola dirección: mira cómo.
Resumen
- URL base
https://skysolver.app/api/v1. Las peticiones y las respuestas son JSON (UTF-8); la anotación también puede venir como SVG. - Cuatro endpoints: resolver una imagen enviada en base64, resolver posiciones de estrellas que hayas medido tú mismo, resolver una foto de la Luna y anotar una imagen resuelta.
- CORS está abierto: puedes llamar a la API desde una página web.
- Versiones: los cambios incompatibles reciben una ruta nueva (
/api/v2);v1solo gana campos opcionales. El documento OpenAPI describe todos los modelos. - Uso razonable: el servicio es gratuito y corre en un servidor pequeño. Para lotes grandes, resuelve listas de estrellas que detectes tú mismo, o pregunta en [email protected].
Inicio rápido
Resuelve una foto y luego obtén su anotación como un SVG del tamaño de la foto, para superponerlo:
# 1. solve: the body is {"image": "<the file in base64>"}
base64 < photo.jpg | jq -Rs '{image: .}' \
| curl -s https://skysolver.app/api/v1/solve/image \
-H 'Content-Type: application/json' --data-binary @- > solution.json
# 2. annotate: the whole solution goes in as the sky model
jq '{solution: ., format: "svg"}' solution.json \
| curl -s https://skysolver.app/api/v1/annotate \
-H 'Content-Type: application/json' --data-binary @- > annotation.svgLo mismo en JavaScript (Node 18 o posterior; en un navegador solo cambia la lectura del archivo):
import { readFile } from "node:fs/promises";
const post = (path, body) => fetch("https://skysolver.app/api/v1" + path, {
method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body),
});
// in a browser: FileReader's readAsDataURL(file) gives a data: URL, which works as it is
const image = (await readFile("photo.jpg")).toString("base64");
const solution = await (await post("/solve/image", { image })).json();
if (solution.solved) {
const answer = await post("/annotate", { solution, time: "2024-10-12T21:34:05+02:00" });
const svg = await answer.text();
}Y en Python:
import base64, json, urllib.request
API = "https://skysolver.app/api/v1"
def post(path, body):
req = urllib.request.Request(API + path, data=json.dumps(body).encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req) as r:
return r.read()
with open("photo.jpg", "rb") as f:
image = base64.b64encode(f.read()).decode()
solution = json.loads(post("/solve/image", {"image": image}))
if solution["solved"]:
print(solution["center"], solution["scale_arcsec"])
svg = post("/annotate", {"solution": solution, "format": "svg"})Límites
Cada dirección de cliente tiene un cubo de peticiones por endpoint: hasta burst de golpe, recargado a un ritmo constante. Una petición más allá se responde al instante con 429 y Retry-After. Cada respuesta lleva RateLimit-Limit (la ráfaga), RateLimit-Remaining, RateLimit-Reset (segundos hasta que el cubo esté lleno) y RateLimit-Policy.
| Endpoint | Ráfaga | Recarga | Cuerpo de la petición |
|---|---|---|---|
POST /solve/image | 10 | 1 por minuto | 28 MB (un archivo de 20 MB en base64) |
POST /solve/stars | 30 | 30 por minuto | 4 MB |
POST /solve/moon | 20 | 10 por minuto | 28 MB (un archivo de 20 MB en base64) |
POST /annotate | 30 | 30 por minuto | 2 MB |
GET /health | 60 | 60 por minuto | – |
- Imágenes: como máximo 20 MB y 120 megapíxeles. El solucionador busca durante como máximo
time_limit_ms(1–30 s, 12 s por defecto). Una foto de la Luna se resuelve a un máximo de 2048 píxeles en su lado largo (las mayores se reducen antes; la respuesta está en los píxeles del archivo) y tarda unos pocos segundos como mucho. - Listas de estrellas: de 5 a 10 000 estrellas; se usan las 3000 más brillantes.
- Ocupado: el servidor ejecuta unas pocas soluciones a la vez (
max_concurrenten health). Más allá, una petición se responde al instante con429,error: "busy"yRetry-After: espera ese tiempo, más un segundo aleatorio más o menos, y vuelve a enviarla. GET /healthdevuelve los límites en vigor.
Convenciones
- Las coordenadas celestes son grados en el ICRS (J2000): RA 0–360, Dec −90–90.
- Los píxeles se cuentan desde 0 en el centro del píxel superior izquierdo; x crece hacia la derecha e y hacia abajo. La esquina superior izquierda de la imagen es por tanto (−0,5, −0,5) y su centro (ancho/2 − 0,5, alto/2 − 0,5). FITS cuenta desde 1: las listas de estrellas pueden indicarlo (
pixel_origin), yfits_headerusa la convención propia de FITS. - Las horas son ISO 8601 con desfase UTC o
Z:2024-10-12T21:34:05+02:00. Una hora sin él se rechaza, nunca se adivina. - Los errores son
{"error": código, "message": texto}, condetailspara los campos no válidos: consulta Errores.
Resolver una imagen
Detecta las estrellas de una imagen y averigua hacia dónde apunta en el cielo: a ciegas, sin ninguna pista de posición, escala ni rotación, para campos desde unos pocos minutos de arco hasta panoramas de todo el cielo. La imagen se decodifica y se resuelve en memoria y no se conserva.
data:image/…;base64, no molesta). Como máximo 20 MB decodificados y 120 megapíxeles. Formatos: JPEG, PNG (8/16 bits), TIFF (8/16/32 bits y coma flotante; sin comprimir, LZW, ZIP, PackBits), FITS (entero o coma flotante; gris, RGB o el mosaico en bruto de una cámara de color), XISF (sin comprimir o zlib), BMP, GIF, TGA y PSD. Los datos lineales (apilados, FITS, XISF) se estiran antes de la detección.12000Permitido 1000–30000{
"image": "/9j/4AAQSkZJRgABAQEASABIAAD…",
"time_limit_ms": 12000
}La respuesta es la solución, más image (format, width, height) y capture: cuándo y dónde se tomó la foto, según sus metadatos (EXIF, XMP, IPTC, cabeceras FITS, propiedades XISF).
+02:00; null cuando se desconoce.EXIF DateTimeOriginal, FITS DATE-OBS, XISF Observation:Time:Start…{lat, lon, height, source}, grados este y norte, metros.{
"api_version": "1.0",
"solved": true,
"width": 2048,
"height": 1366,
"wcs": {
"ctype": "RA---TAN-SIP",
"crval": [57.56884791, 30.441625],
"crpix": [1023.5, 682.5],
"cd": [[0.0004834903827, 0.008644326623], [-0.008637593318, 0.0004834749004]],
"sip": { "order": 3, "a": [[0, 2, -1.585329748e-7], …], "b": […], "inv_order": 4, "ap": […], "bp": […] }
},
"projection": null,
"center": { "ra": 57.56884791, "dec": 30.441625 },
"corners": [{ "name": "top-left", "x": -0.5, "y": -0.5, "ra": 49.44900035, "dec": 38.65911116 }, …],
"fov": { "width_deg": 17.6401047, "height_deg": 11.79908067 },
"scale_arcsec": 31.15610913,
"rotation_deg": 266.7987974,
"parity": "normal",
"stats": { "stars": 3294, "matches": 972, "rms_px": 0.3723350842, "log_odds": 3198.350966, … },
"fits_header": "SIMPLE = T …",
"matched": [[1988.17, 1290.68, 63.70586, 22.302973, 8.59], …],
"timing_ms": { "solve": 153.9, "detect": 40.3, "decode": 507.7, "server": 844.4 },
"image": { "format": "FITS", "width": 2048, "height": 1366 },
"capture": {
"time": { "utc": "2025-08-16T21:00:00.000Z", "local": "2025-08-16T23:00:00.000", "utc_offset": "+02:00",
"source": "FITS DATE-OBS", "exposure_s": 60 },
"location": { "lat": 52.2297, "lon": 21.0122, "height": 110, "source": "FITS SITELAT/SITELONG" },
"other_dates": []
}
}Resolver posiciones de estrellas
Resuelve a partir de posiciones de estrellas que hayas medido tú mismo (SExtractor, SEP, photutils, el StarDetector de PixInsight, tus propios centroides): la imagen nunca sale de tu equipo, y la petición ocupa unos pocos kilobytes. Así es como resuelve el taller.
8–1000008–100000[x, y], [x, y, flux] o {"x": …, "y": …, "flux": …}. flux es cualquier medida positiva de brillo (suma, pico, …): dalo para todas las estrellas o para ninguna, y sin él lista las estrellas de más a menos brillante. Con 30 a 300 estrellas sobra; se usan las 3000 más brillantes. Las posiciones deben caer dentro de la imagen.5–10000 items0: el centro del primer píxel es (0, 0), como en numpy y OpenCV. 1: es (1, 1), como en FITS, SExtractor, astrometry.net y DS9. Las respuestas siempre empiezan en 0.0Permitido 0 · 112000Permitido 1000–30000{
"width": 6000,
"height": 4000,
"stars": [
[3735.37, 69.14, 51230],
[2120.04, 1987.51, 48810],
{ "x": 812.6, "y": 3020.9, "flux": 47002 },
…
]
}La respuesta es la solución.
La solución
Los dos endpoints de campos de estrellas responden con este objeto.
200, con solved: false y un error.{ra, dec} en grados. null cuando el centro de una imagen de todo el cielo no está sobre el cielo.top-left, top-right, bottom-right, bottom-left: cada una {name, x, y, ra, dec}, con ra y dec null donde una esquina queda fuera del cielo.{width_deg, height_deg}: la longitud angular de las líneas medias horizontal y vertical de la imagen.normal · mirroredcrval (RA, Dec del píxel de referencia), crpix (el píxel de referencia, desde 0), cd (grados por píxel) y sip (polinomios de distorsión, términos [p, q, coeficiente]). null para soluciones de proyección.stars (detectadas o dadas), matches, rms_px (a qué distancia del modelo quedan las estrellas emparejadas), log_odds (la evidencia de la coincidencia, un logaritmo natural: una solución necesita 25 y 10 estrellas emparejadas) y detalles de la búsqueda.[x, y, ra, dec, magnitude] cada una, la magnitud es la G de Gaia.decode (lectura del archivo), detect, solve y el total del server para la petición, en milisegundos.Resolver una foto de la Luna
Encuentra la Luna en una foto y ajusta su disco: a ciegas, a cualquier escala, rotación e inversión, en cualquier fase, tanto si el encuadre contiene el disco entero como una parte o un primer plano de unos pocos cráteres. La foto filtrada en banda se compara, en cada posición, rotación y paridad, como una mezcla de tres mapas fijos de la cara visible (el albedo y sus dos pendientes), que es lo que cualquier dirección del Sol hace con el terreno; la fracción de la foto que la mezcla explica es la confianza, y el limbo, cuando lo hay, fija la libración. La respuesta sitúa cada punto de la foto sobre la Luna: el centro, el radio y la orientación del disco, la libración, y el Sol y la fase leídos del terminador. Los primeros planos se resuelven con fiabilidad hasta regiones de unos 250 km de ancho; un campo de menos de unos 150 km, un cráter que llena el encuadre, a menudo vuelve como unsure. La imagen se decodifica y se resuelve en memoria y no se conserva.
data:image/…;base64, no molesta). Como máximo 20 MB decodificados y 120 megapíxeles. Formatos: JPEG, PNG (8/16 bits), TIFF, WebP, BMP y GIF; el color se convierte a luminancia, los datos de 16 bits se estiran por su píxel más brillante. Los píxeles se leen tal como están almacenados (no se aplica la orientación EXIF), así que la respuesta coincide con lo que muestra un visor de imágenes que la ignore.{
"image": "/9j/4AAQSkZJRgABAQEASABIAAD…"
}unsure. Una foto sin Luna sigue siendo una respuesta 200, con solved: false y un error.verified: una respuesta segura que superó las comprobaciones cruzadas (un primer plano destaca claramente sobre la segunda opción de la propia foto, y concuerda con el limbo cuando hay uno en el encuadre). plausible: probable pero no confirmada. unsure: sin resolver; la mejor conjetura se informa de todos modos en view, por lo que pueda valer.verified · plausible · unsuredisk · closeup · none0–1null cuando no se encontró nada: cx, cy, R son el centro y el radio del disco en píxeles (centros de píxel desde 0; en un primer plano quedan muy fuera del encuadre); rho es el ángulo en pantalla del norte lunar, grados en sentido antihorario desde el «arriba» de la imagen; par es 1 para una vista directa y -1 para una especular; lon0, lat0 son el punto subobservador en grados selenográficos (longitud positiva hacia el este), es decir, la libración.{lon, lat, score, terminator}, leído de la foto: donde se encuentran el terreno iluminado y el oscuro en el encuadre, la longitud del Sol que mejor predice cuál es cuál (lat es 0; el valor real siempre está a menos de 1,6°); score es la fracción de las muestras del encuadre que predice bien. Un disco entero sin terminador es una Luna llena (terminator: false, el Sol en el punto subobservador). null para un primer plano sin terminador: la fase no se puede deducir de él.view y sun: angle_deg (el ángulo de fase: 0 llena, 180 nueva), fraction (iluminada), waxing, colongitude (la colongitud selenográfica del Sol: 0 en cuarto creciente, 90 llena, 180 en cuarto menguante) y name (new moon, waxing crescent, first quarter, waxing gibbous, full moon, waning gibbous, last quarter, waning crescent). null sin sun.{cx, cy, R, arc, refined, locked} (píxeles como en view; arc es la parte del círculo que se midió), null cuando no se encontró limbo. locked: true significa que el círculo de la vista es este borde; en otro caso, la textura de la superficie situó la esfera por sí misma, que queda dentro del borde rebosado de una Luna sobreexpuesta.center y corners (top-left, top-right, bottom-right, bottom-left), cada una {lon, lat} o null donde el punto queda fuera del disco (las esquinas de una foto del disco entero).hyps (posiciones probadas por la búsqueda de primer plano) y octaves (octavas de escala buscadas); ambos 0 cuando el limbo lo zanjó.decode, limb, disk, closeup, solve y el total del server, en milisegundos.format (tal como lo nombra el decodificador: JPEG, PNG, …), width, height.{
"api_version": "1.0",
"solved": true,
"verdict": "verified",
"path": "closeup",
"confidence": 0.7642,
"runner_up": 0.0223,
"width": 1560,
"height": 1075,
"view": { "cx": -602.996, "cy": 3686.543, "R": 4399.212, "rho": 305.2046, "par": 1, "lon0": 5.727, "lat0": 4.9752 },
"scale_km_px": 0.39493,
"sun": { "lon": 56.5, "lat": 0.0, "score": 0.9505, "terminator": true },
"phase": { "angle_deg": 50.95, "fraction": 0.815, "waxing": true, "colongitude": 33.5, "name": "waxing gibbous" },
"limb": null,
"frame": {
"center": { "lon": -29.9219, "lat": 46.1421 },
"corners": [{ "lon": -46.2102, "lat": 39.6896 }, { "lon": -62.682, "lat": 64.4227 }, { "lon": -13.7619, "lat": 52.7875 }, { "lon": -22.696, "lat": 31.4166 }]
},
"stats": { "hyps": 864, "octaves": 3 },
"timing_ms": { "limb": 10.6, "disk": 181.8, "closeup": 145.4, "solve": 337.7, "decode": 5.4, "server": 347.9 },
"image": { "format": "JPEG", "width": 1560, "height": 1075 }
}Para dibujar sobre la foto, proyecta un punto selenográfico (lon, lat) con la vista: con p = (cos lat cos lon, cos lat sin lon, sin lat), e_z el mismo vector para (lon0, lat0), e_y el eje de la Luna hecho perpendicular a e_z y e_x = e_y × e_z: X = par · p·e_x, Y = p·e_y, x = cx + R (X cos ρ − Y sin ρ), y = cy − R (X sin ρ + Y cos ρ); el punto está en la cara visible cuando p·e_z > 0.
Anotar una imagen resuelta
Dibuja la cuadrícula de coordenadas, las constelaciones, los objetos de cielo profundo (20 000: Messier, NGC, IC, Sharpless, Barnard, Lynds, van den Bergh, Caldwell, los catálogos de cúmulos estelares, nebulosas planetarias, restos de supernova, grupos de galaxias de Arp, Hickson y Abell, RCW y Cederblad), las estrellas con nombre y designación y, dada una hora, el Sol, la Luna, los planetas, asteroides y cometas, tal como los dibuja Guardar imagen en el taller: los mismos objetos, etiquetas y estilos. Envías el modelo de cielo, no la imagen. La anotación no se recorta al cielo: el taller encuentra el horizonte en la propia foto.
corners, wcs y projection; en otro caso se toma de solution o de NAXIS1/NAXIS2 de la cabecera FITS.8–100000svg: un documento SVG del tamaño de la imagen, transparente, para superponer a la foto. json: los objetos, cuerpos, líneas y etiquetas colocadas como datos (Salida JSON)."svg"Permitido svg · jsonZ). Con ella, el Sol, la Luna, los planetas y Plutón se dibujan donde estaban (con 1″ de precisión para 1850–2150), y los asteroides más brillantes y los cometas (con alrededor de 1″ para 1990–2041).-90–90-180–180-500–100001400Permitido 200–80000Permitido 0–1{
"solution": { "width": 2048, "height": 1366, "wcs": { … }, … },
"format": "svg",
"time": "2025-08-16T23:00:00+02:00",
"location": { "lat": 52.23, "lon": 21.01 },
"view": { "group_by": "catalog", "grid": { "on": false }, "catalogs": { "solar": { "color": "#ff8800", "size": 16 } } },
"filter": { "catalogs": { "ldn": false, "lbn": false }, "magnitude": [-2, 10] },
"edits": { "hidden": ["Mars"], "names": { "NGC 1499": "California" } }
}Con format: "svg" la respuesta es image/svg+xml: <svg width="2048" height="1366" viewBox="0 0 2048 1366">…, en los píxeles de la foto. Un aviso sobre el modelo de cielo, si lo hay, viene en la cabecera SkySolver-Warning.
Modelos de cielo
Envía el que tengas; todos describen cómo los píxeles de la imagen se corresponden con el cielo.
{ra, dec}: center, top_left, top_right, bottom_right, bottom_left. Se les ajusta una proyección gnomónica (TAN); para objetivos gran angular que distorsionan, la respuesta avisa de a qué distancia quedan las esquinas de ella. Cada esquina debe estar a menos de 87° del centro: las vistas más amplias necesitan la projection del solucionador.crval [RA, Dec], crpix [x, y] (desde 0), cd [[CD1_1, CD1_2], [CD2_1, CD2_2]] en grados por píxel y, opcionalmente, sip {order, a, b, inv_order, ap, bp} con términos [p, q, coeficiente].CTYPE1 = 'RA---TAN' o 'RA---TAN-SIP', CRVAL, CRPIX (desde 1, como en FITS), y CD, o PC con CDELT, o CDELT con CROTA2; los A_*, B_*, AP_*, BP_* de SIP. Lo que escriben astrometry.net, ASTAP, PixInsight y este solucionador./solve./solve: se usan su tamaño y su wcs o projection.Salida JSON
Con format: "json": lo que dibuja la anotación, en píxeles de la imagen (desde 0, y hacia abajo), y las etiquetas tal como quedan colocadas.
center {ra, dec}, scale_arcsec (en el centro), diagonal_deg (null para vistas de todo el cielo).width (el layout_width usado) y scale: píxeles de imagen por píxel de composición, por el que se multiplicaron los tamaños y grosores.M 42, NGC 1977), tal como la acepta edits, y la etiqueta dibujada (M42).Orion Nebula, o el dado en edits) y el propio del catálogo.emission…) y todos los grupos de catálogo a los que pertenece.["Mel 22", "LBN 770"].[x0, y0, x1, y1, …] en píxeles (un contorno trazado, o la elipse del catálogo); closed es false cuando la forma sale del dominio de una vista de todo el cielo y solo se dibujan trozos de ella.edits.hidden lo oculta.time: el Sol, la Luna, los planetas, asteroides y cometas del encuadre: id, name, kind (star, moon, planet, dwarf planet, asteroid, comet), ra, dec, mag (en un cometa, una previsión aproximada), diameter_arcsec (null para asteroides y cometas), distance_au, phase (fracción iluminada), elongation_deg, topocentric (situado como se ve desde location), uncertainty_arcsec (asteroides y cometas: cuánto puede desviarse la posición), x, y, radius_px, outline, shown.id, name, lines (polilíneas en píxeles), stars, label_at.kind (ra o dec), value (grados), label, lines.kind (ecliptic, galactic, borders), lines, label_at.text, of (el objeto), kind, x, y (el anclaje de la línea base del texto), size, anchor (start, middle, end), color, opacity.Opciones
Todas opcionales, y parciales: lo que omitas conserva los valores predeterminados del taller. Los valores fuera de rango, y las claves que no existen, se rechazan con 422 en lugar de ignorarse.
types o catalogs de abajo."type"Permitido type · catalogon y un estilo de línea (predeterminado #96beff, discontinua).on y un estilo de línea.on (desactivado por defecto) y un estilo de línea.on (desactivado por defecto) y un estilo de línea.on (desactivado por defecto), color, opacity, blur (0–16 px), distance (0–12 px).truetrue{"emission": {"color": "#ff99cc"}}.#rrggbb0–10.3–6solid · dashed · dotted · dashdot6–32group_by: "type"): {"dark": false}. Todos están activados por defecto.group_by: "catalog").auto: los objetos Messier siempre, los demás según lo que destaquen en el encuadre (tamaño, o un límite de magnitud que sigue la escala de la imagen). Un rango: los objetos con una magnitud dentro de él; los que no la tienen (la mayoría de las nebulosas), por tamaño."auto"Permitido "auto" · [brightest, faintest] within -2–18objects[].id: ["NGC 1999", "Mars"].{"NGC 1499": "California"}; una cadena vacía etiqueta un objeto solo por su designación.Grupos y estilos
Las claves de view.types, filter.types, view.catalogs y filter.catalogs, con su estilo predeterminado (color, opacidad, grosor, línea, tamaño de letra):
| clave de types | Grupo | Predeterminado |
|---|---|---|
galaxy | Galaxias | #f4b8700.75 · 1 px · solid · 10.5 px |
open | Cúmulos abiertos | #86d3f30.75 · 1 px · solid · 10.5 px |
globular | Cúmulos globulares | #f3dc8e0.78 · 1 px · solid · 10.5 px |
emission | Nebulosas de emisión | #d4a5ff0.78 · 1 px · solid · 10.5 px |
reflection | Nebulosas de reflexión | #9cc3ff0.75 · 1 px · solid · 10.5 px |
planetary | Nebulosas planetarias | #7ee8c60.78 · 1 px · solid · 10.5 px |
snr | Restos de supernova | #ff9eb40.75 · 1 px · solid · 10.5 px |
dark | Nebulosas oscuras | #b5c0d40.45 · 1 px · solid · 10.5 px |
star | Estrellas | #fde9b00.7 · 0.9 px · solid · 10 px |
solar | Sistema solar | #e4f68e0.85 · 1.2 px · solid · 12 px |
other | Otros | #dce3f00.65 · 1 px · solid · 10.5 px |
| clave de catalogs | Grupo | Predeterminado |
|---|---|---|
messier | Messier | #f7cf4a0.85 · 1 px · solid · 12 px |
ngc | NGC | #86d3f30.75 · 1 px · solid · 10.5 px |
ic | IC | #aab8ff0.75 · 1 px · solid · 10.5 px |
sharpless | Sharpless (Sh2) | #d4a5ff0.78 · 1 px · solid · 10.5 px |
barnard | Barnard (B) | #b5c0d40.5 · 1 px · solid · 10.5 px |
ldn | Lynds oscuras (LDN) | #93a1b80.45 · 1 px · solid · 10.5 px |
lbn | Lynds brillantes (LBN) | #f7a8d30.72 · 1 px · solid · 10.5 px |
vdb | van den Bergh (vdB, vdBH) | #9cc3ff0.75 · 1 px · solid · 10.5 px |
caldwell | Caldwell | #7ee8c60.75 · 1 px · solid · 10.5 px |
clusters | Cúmulos estelares (Collinder, Melotte, Trumpler, …) | #a5e4f70.72 · 1 px · solid · 10.5 px |
pn | Nebulosas planetarias (PN G, PK, Abell) | #7ee8c60.78 · 1 px · solid · 10.5 px |
snr | Restos de supernova (SNR G) | #ff9eb40.75 · 1 px · solid · 10.5 px |
groups | Grupos de galaxias (Arp, Hickson, Abell/ACO) | #f4c48a0.7 · 1 px · solid · 10.5 px |
rcw | Más nebulosas (RCW, Gum, Cederblad, DWB) | #e0b3ff0.72 · 1 px · solid · 10.5 px |
stars | Estrellas (nombres, Bayer, Flamsteed, HR, HD) | #fde9b00.7 · 0.9 px · solid · 10 px |
custom | Tus catálogos (archivos) | #ffb86b0.85 · 1 px · solid · 11 px |
vizier | En línea (VizieR) | #9fe8700.7 · 0.9 px · solid · 9.5 px |
solar | Sistema solar | #e4f68e0.85 · 1.2 px · solid · 12 px |
other | Otros | #dce3f00.65 · 1 px · solid · 10.5 px |
Errores
Toda respuesta de error tiene la misma forma: un código al que reaccionar y un mensaje que mostrar. Las peticiones no válidas enumeran cada problema:
{
"error": "invalid_request",
"message": "view.grid.color: String should match pattern '^#[0-9a-fA-F]{6}$'",
"details": [
{ "field": "view.grid.color", "problem": "String should match pattern '^#[0-9a-fA-F]{6}$'" },
{ "field": "filter.magnitude", "problem": "magnitude must be \"auto\" or [brightest, faintest] within -2..18" }
]
}| Estado | error | Cuándo |
|---|---|---|
| 400 | invalid_image | La imagen no es base64 válido, o no se puede leer. |
| 400 | unsupported_format | El archivo no es de uno de los formatos de arriba. |
| 413 | payload_too_large | El cuerpo de la petición, el archivo o su número de píxeles supera el límite. |
| 422 | invalid_request | Falta un campo, o es de tipo incorrecto, está fuera de rango o es desconocido; details enumera cada uno. |
| 429 | rate_limited | Tu dirección de cliente agotó sus peticiones; retry_after dice cuándo volver a intentarlo. |
| 429 | busy | El servidor está resolviendo todo lo que puede; reintenta tras Retry-After. |
| 500 | internal_error | Algo falló de nuestro lado. |
| 503 | unavailable | El solucionador, el solucionador lunar o el anotador no está listo. |
Una imagen que no se puede resolver no es un error: la respuesta es 200 con solved: false.
Estado
El estado del servicio, los índices de estrellas, el solucionador lunar y los procesos de anotación cargados, y los límites en vigor.
{
"status": "ok",
"version": "1.0",
"uptime_s": 86400.2,
"solver": { "indexes": 4, "max_concurrent": 4, "in_flight": 0 },
"moon": { "ready": true },
"annotator": { "ok": true, "workers": 2, "objects": 15333 },
"limits": {
"rates": {
"image": { "burst": 10, "per_minute": 1 },
"moon": { "burst": 20, "per_minute": 10 },
"stars": { "burst": 30, "per_minute": 30 },
"annotate": { "burst": 30, "per_minute": 30 },
"light": { "burst": 60, "per_minute": 60 }
},
"image_mb": 20, "megapixels": 120, "stars": 10000, "time_limit_ms": 30000
}
}API compatible con Astrometry.net
Los programas que resuelven astrometría en línea con astrometry.net (nova.astrometry.net) pueden usar SkySolver en su lugar: pon su servidor en https://skysolver.app. Cualquier clave de API sirve, también una vacía; no hay cuentas. Las rutas, las respuestas y los archivos son los de nova, hasta los detalles de los que dependen sus clientes, en la raíz del sitio (/api/…, /wcs_file/…).
| Programa | Ajuste |
|---|---|
| N.I.N.A. | Options → Plate solving → Astrometry.net: URL https://skysolver.app, cualquier clave de API |
| KStars / Ekos | Align → solver options → Online (astrometry.net): API URL https://skysolver.app (https: StellarSolver lo añade de todos modos), cualquier clave |
| astroquery | AstrometryNet() con URL = "https://skysolver.app", API_URL = "https://skysolver.app/api", cualquier api_key |
| client.py (astrometry.net) | --server https://skysolver.app/api/ --apikey loquesea; el script en línea de CCDciel lo usa |
| AstroImageJ | Plate solve → custom server https://skysolver.app, clave vacía |
| SGP | el solucionador ANSVR, Server URL https://skysolver.app/api (las rutas que llama SGP están ahí; no probado con el propio SGP) |
from astroquery.astrometry_net import AstrometryNet
ast = AstrometryNet()
ast.URL, ast.API_URL, ast.api_key = "https://skysolver.app", "https://skysolver.app/api", "anything"
wcs_header = ast.solve_from_image("m31.jpg") # or ast.solve_from_source_list(x, y, width, height)| Ruta | Qué hace aquí |
|---|---|
POST /api/login | Una sesión para cualquier clave. |
POST /api/upload | Una imagen (JPEG, PNG, TIFF, FITS, XISF, BMP, GIF, WebP), una lista x,y (una tabla FITS con X e Y, o texto con un x y por línea), o listas x e y en request-json. Hasta 96 MB. |
POST /api/url_upload | Solo listas x e y (tal como las envía astroquery): no se descarga ninguna URL. |
/api/submissions/ID | El envío y su trabajo: el trabajo está ahí desde la primera consulta. |
/api/jobs/ID | processing, solving, success o failure; todo trabajo acaba en uno de los dos últimos. |
/api/jobs/ID/calibration/ | ra, dec, radius, pixscale, orientation, parity, width_arcsec, height_arcsec, calculados como lo hace nova. |
/api/jobs/ID/info/ · tags/ · machine_tags/ · objects_in_field/ · annotations/ | Los objetos de cielo profundo del campo, con sus posiciones y radios en píxeles en annotations. |
/wcs_file/ID | La solución TAN-SIP como archivo FITS de solo cabecera (wcs.fits). |
/corr_file/ID · /axy_file/ID · /rdls_file/ID | Las estrellas emparejadas, las estrellas detectadas, las estrellas de catálogo emparejadas: tablas FITS con las columnas de nova. |
/joblog/ID | Qué hizo el trabajo, como texto. |
- Siempre a ciegas. Las pistas de escala, posición y paridad se aceptan y se ignoran: el solucionador no necesita ninguna, y una pista errónea no puede estropear una solución.
- Los píxeles son los de nova:
(1, 1)es el centro del primer píxel almacenado, el superior izquierdo de un JPEG o PNG (sin aplicar su orientación EXIF) o la primera fila de un archivo FITS, sea cual sea suROWORDER. Laorientationconserva la peculiaridad de nova para subidas JPEG, PNG y GIF, de modo que los programas que la deshacen obtienen el mismo ángulo que de nova. - Los panoramas y las imágenes de todo el cielo resueltos con un modelo de proyección tienen calibración pero no
wcs_file: ningún TAN-SIP los abarca. - No se conserva ninguna imagen. Una subida se descarta en cuanto se encuentran sus estrellas, así que
new_fits_filey las imágenes anotada, rojo-verde y de extracción no se ofrecen. Los resultados de un trabajo se guardan en memoria durante 30 minutos y luego se olvidan. - Límites: subidas, 20 de golpe y 6 por minuto por dirección; las demás rutas cuentan como peticiones ligeras (60 de golpe, 60 por minuto).
Historial de cambios
- 1.2 (19 de octubre de 2026): resolución de la Luna:
/api/v1/solve/moon. - 1.1 (17 de octubre de 2026): la API compatible con Astrometry.net.
- 1.0 (16 de octubre de 2026): resolver una imagen (base64) o posiciones de estrellas, anotar como SVG o JSON, con el Sol, la Luna y los planetas.
¿Preguntas, un error, una cuota mayor? [email protected]. Al usar la API aceptas los términos; lo que hace con tus datos está en la página de privacidad.