API · v1

A API do SkySolver

Resolva a astrometria de uma foto do céu noturno, ou de uma lista das suas estrelas, e desenhe a sua anotação, como SVG para sobrepor à foto ou como JSON para desenhar você mesmo; ou resolva uma foto da Lua: os mesmos solvers e as mesmas anotações da oficina. É gratuita e não precisa de chave, e programas feitos para o solver online do Astrometry.net, como N.I.N.A. e KStars, podem usá-la mudando um endereço: veja como.

Visão geral

Sem chave
Gratuita e anônima: sem conta nem chave de API.
Com limite de requisições
Por endereço do cliente, conforme o peso do endpoint.
Nada é guardado
Imagens, listas de estrelas e resultados não são armazenados nem registrados.
  • URL base https://skysolver.app/api/v1. Requisições e respostas são JSON (UTF-8); a anotação também pode vir como SVG.
  • Quatro endpoints: resolver uma imagem enviada em base64, resolver posições de estrelas que você mesmo mediu, resolver uma foto da Lua e anotar uma imagem resolvida.
  • CORS está aberto: você pode chamar a API a partir de uma página web.
  • Versões: mudanças incompatíveis ganham um novo caminho (/api/v2); a v1 só ganha campos opcionais. O documento OpenAPI descreve todos os modelos.
  • Uso justo: o serviço é gratuito e roda num servidor pequeno. Para grandes lotes, resolva listas de estrelas que você mesmo detecta, ou pergunte em [email protected].

Início rápido

Resolva uma foto, depois obtenha a sua anotação como um SVG do tamanho da foto, para sobrepor a ela:

shell
# 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.svg

O mesmo em JavaScript (Node 18 ou posterior; num navegador só a leitura do arquivo é diferente):

javascript
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();
}

E em Python:

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"})

Limites

Cada endereço de cliente tem um balde de requisições por endpoint: até burst de uma vez, recarregado a um ritmo constante. Uma requisição além disso é respondida de imediato com 429 e Retry-After. Toda resposta traz RateLimit-Limit (o burst), RateLimit-Remaining, RateLimit-Reset (segundos até o balde estar cheio) e RateLimit-Policy.

EndpointBurstRecargaCorpo da requisição
POST /solve/image101 por minuto28 MB (um arquivo de 20 MB em base64)
POST /solve/stars3030 por minuto4 MB
POST /solve/moon2010 por minuto28 MB (um arquivo de 20 MB em base64)
POST /annotate3030 por minuto2 MB
GET /health6060 por minuto–
  • Imagens: no máximo 20 MB e 120 megapixels. O solver busca durante no máximo time_limit_ms (1–30 s, 12 s por padrão). Uma foto da Lua é resolvida com até 2048 pixels no lado maior (as maiores são reduzidas antes; a resposta vem nos pixels do arquivo) e leva no máximo alguns segundos.
  • Listas de estrelas: 5 a 10.000 estrelas; as 3.000 mais brilhantes são usadas.
  • Ocupado: o servidor executa algumas resoluções de cada vez (max_concurrent em estado). Além disso, uma requisição é respondida de imediato com 429, error: "busy" e Retry-After: espere esse tempo, mais cerca de um segundo aleatório, e envie-a de novo.
  • GET /health devolve os limites em vigor.

Convenções

  • Coordenadas celestes são graus no ICRS (J2000): RA 0–360, Dec −90–90.
  • Pixels contam a partir de 0 no centro do pixel superior esquerdo; x cresce para a direita e y para baixo. O canto superior esquerdo da imagem é portanto (−0.5, −0.5) e o seu centro (largura/2 − 0.5, altura/2 − 0.5). O FITS conta a partir de 1: as listas de estrelas podem dizê-lo (pixel_origin), e fits_header usa a convenção do próprio FITS.
  • Horas são ISO 8601 com deslocamento UTC ou Z: 2024-10-12T21:34:05+02:00. Uma hora sem ele é recusada, nunca adivinhada.
  • Erros são {"error": código, "message": texto}, com details para campos inválidos: veja Erros.

Resolver uma imagem

POST/api/v1/solve/image10 de uma vez · 1 por minuto

Detecta as estrelas de uma imagem e descobre para onde no céu ela aponta: às cegas, sem nenhuma dica de posição, escala ou rotação, para campos de alguns minutos de arco até panoramas de todo o céu. A imagem é decodificada e resolvida em memória e não é guardada.

Parâmetros
image
stringobrigatório
O arquivo de imagem, codificado em base64 (alfabeto padrão ou URL-safe; um prefixo data:image/…;base64, é aceito). No máximo 20 MB decodificados e 120 megapixels. Formatos: JPEG, PNG (8/16 bits), TIFF (8/16/32 bits e float; sem compressão, LZW, ZIP, PackBits), FITS (inteiro ou float; cinza, RGB ou o mosaico bruto de uma câmera colorida), XISF (sem compressão ou zlib), BMP, GIF, TGA e PSD. Dados lineares (empilhamentos, FITS, XISF) são esticados antes da detecção.
time_limit_ms
integeropcional
Por quanto tempo o solver pode buscar antes de desistir.
Padrão 12000Permitido 1000–30000
requisição
{
  "image": "/9j/4AAQSkZJRgABAQEASABIAAD…",
  "time_limit_ms": 12000
}

A resposta é a solução, mais image (format, width, height) e capture: quando e onde a foto foi tirada, segundo os seus metadados (EXIF, XMP, IPTC, cabeçalhos FITS, propriedades XISF).

capture
time
object | null
A hora de captura, ou null quando o arquivo não tem uma.
└utc
string | null
O instante em UTC: null quando o arquivo dá uma leitura de relógio sem o seu fuso horário (EXIF anterior a 2.31, XMP do Lightroom).
└local
string
A leitura do relógio como escrita: a hora local da câmera para EXIF, UTC para FITS.
└utc_offset
string | null
O deslocamento do relógio, +02:00; null quando desconhecido.
└source
string
De onde foi lida: EXIF DateTimeOriginal, FITS DATE-OBS, XISF Observation:Time:Start…
└exposure_s
number
A exposição (ou, num empilhamento, do primeiro início ao último fim) quando conhecida; a hora é então o seu meio.
└note
string
Algo a conferir: um empilhamento datado por um dos seus frames, uma câmera que pode não ter tido o fuso definido.
└date_only
boolean
true quando o arquivo dá uma data sem hora do dia.
location
object | null
Onde foi tirada, do GPS ou das palavras-chave de local do FITS: {lat, lon, height, source}, graus leste e norte, metros.
other_dates
array
Outras datas no arquivo que podem não ser a hora de captura (criação, modificação), com a forma de time.
resposta (abreviada)
{
  "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 posições de estrelas

POST/api/v1/solve/stars30 de uma vez · 30 por minuto

Resolve a partir de posições de estrelas que você mesmo mediu (SExtractor, SEP, photutils, o StarDetector do PixInsight, os seus próprios centroides): a imagem nunca sai da sua máquina, e a requisição tem alguns kilobytes. É assim que a oficina resolve.

Parâmetros
width
integerobrigatório
Largura da imagem em pixels.
Permitido 8–100000
height
integerobrigatório
Altura da imagem em pixels.
Permitido 8–100000
stars
arrayobrigatório
Posições das estrelas, cada uma [x, y], [x, y, flux] ou {"x": …, "y": …, "flux": …}. flux é qualquer medida positiva de brilho (soma, pico, …): dê-a para todas as estrelas ou para nenhuma, e sem ela liste as estrelas da mais brilhante para a mais fraca. 30 a 300 estrelas é bastante; as 3.000 mais brilhantes são usadas. As posições têm de estar dentro da imagem.
Permitido 5–10000 items
pixel_origin
integeropcional
0: o centro do primeiro pixel é (0, 0), como em numpy e OpenCV. 1: é (1, 1), como em FITS, SExtractor, astrometry.net e DS9. As respostas são sempre baseadas em 0.
Padrão 0Permitido 0 · 1
time_limit_ms
integeropcional
Por quanto tempo o solver pode buscar.
Padrão 12000Permitido 1000–30000
requisição
{
  "width": 6000,
  "height": 4000,
  "stars": [
    [3735.37, 69.14, 51230],
    [2120.04, 1987.51, 48810],
    { "x": 812.6, "y": 3020.9, "flux": 47002 },
    …
  ]
}

A resposta é a solução.

A solução

Os dois endpoints de campos de estrelas respondem com este objeto.

campos
solved
boolean
Se uma solução foi encontrada. Uma foto que não pode ser resolvida ainda é uma resposta 200, com solved: false e um error.
width, height
integer
O tamanho da imagem em pixels.
center
object | null
O céu no meio da imagem: {ra, dec} em graus. null quando o meio de uma imagem de todo o céu não está no céu.
corners
array
Os quatro cantos externos da imagem, top-left, top-right, bottom-right, bottom-left: cada um {name, x, y, ra, dec}, com ra e dec null onde um canto está fora do céu.
fov
object
{width_deg, height_deg}: o comprimento angular das linhas médias horizontal e vertical da imagem.
scale_arcsec
number
Segundos de arco por pixel no centro.
rotation_deg
number
Para onde aponta o topo da imagem: graus do norte para leste (0: norte para cima, 90: leste para cima).
parity
string
Imagens espelhadas (invertidas no processamento, ou através de uma diagonal) também são resolvidas.
Permitido normal · mirrored
wcs
object | null
A solução como TAN ou TAN-SIP: crval (RA, Dec do pixel de referência), crpix (o pixel de referência, baseado em 0), cd (graus por pixel) e sip (polinômios de distorção, termos [p, q, coeficiente]). null para soluções de projeção.
projection
object | null
A solução como modelo de projeção, para panoramas, olho de peixe e vistas de todo o céu que nenhum TAN-SIP ajusta; null caso contrário. Passe-o, ou a solução inteira, a /annotate.
stats
object
stars (detectadas ou fornecidas), matches, rms_px (a que distância do modelo estão as estrelas identificadas), log_odds (a evidência da correspondência, um logaritmo natural: uma solução precisa de 25 e de 10 estrelas identificadas), e detalhes da busca.
fits_header
string | null
A solução TAN-SIP como cabeçalho FITS WCS (cartões de 80 caracteres; CRPIX baseado em 1, do FITS), pronto para ser incorporado num arquivo FITS. null para soluções de projeção.
matched
array
As estrelas de catálogo (Gaia DR3) que a solução identificou, até alguns milhares: [x, y, ra, dec, magnitude] cada, a magnitude sendo o G do Gaia.
timing_ms
object
decode (leitura do arquivo), detect, solve, e o total do server para a requisição, em milissegundos.
error
string
Por que não há solução (quando solved é false).
api_version
string
1.0

Resolver uma foto da Lua

POST/api/v1/solve/moon20 de uma vez · 10 por minuto

Encontra a Lua numa foto e ajusta o seu disco: às cegas, em qualquer escala, rotação e espelhamento, em qualquer fase, quer o enquadramento contenha o disco inteiro, uma parte dele ou um close-up de algumas crateras. A foto filtrada em banda é comparada, em todas as posições, rotações e paridades, como uma mistura de três mapas fixos da face visível (o albedo e as suas duas inclinações), que é o que qualquer direção do Sol faz do terreno; a fração da foto que a mistura explica é a confiança, e o limbo, quando há um, fixa a libração. A resposta coloca cada ponto da foto sobre a Lua: o centro, o raio e a orientação do disco, a libração, e o Sol e a fase lidos do terminador. Close-ups se resolvem com confiança até regiões de cerca de 250 km de largura; um campo com menos de cerca de 150 km, uma cratera preenchendo o enquadramento, muitas vezes volta como unsure. A imagem é decodificada e resolvida em memória e não é guardada.

Parâmetros
image
stringobrigatório
A foto, codificada em base64 (alfabeto padrão ou URL-safe; um prefixo data:image/…;base64, é aceito). No máximo 20 MB decodificados e 120 megapixels. Formatos: JPEG, PNG (8/16 bits), TIFF, WebP, BMP e GIF; a cor é convertida em luminância, dados de 16 bits esticados pelo seu pixel mais brilhante. Os pixels são lidos como estão armazenados (uma orientação EXIF não é aplicada), portanto a resposta corresponde ao que mostra um visualizador de imagens que a ignora.
requisição
{
  "image": "/9j/4AAQSkZJRgABAQEASABIAAD…"
}
campos
solved
boolean
Se a Lua foi encontrada com um veredito diferente de unsure. Uma foto sem Lua ainda é uma resposta 200, com solved: false e um error.
verdict
string
verified: uma resposta confiante que passou nas verificações cruzadas (um close-up fica bem acima da segunda melhor resposta da própria foto e concorda com o limbo quando há um no enquadramento). plausible: provável mas não confirmada. unsure: não resolvida; o melhor palpite ainda é informado em view, pelo que vale.
Permitido verified · plausible · unsure
path
string
Como foi resolvida: pelo limbo do disco (a Lua inteira, ou uma grande parte dela, no enquadramento) ou pela busca de close-up sobre a face visível.
Permitido disk · closeup · none
confidence
number
A fração da energia da foto filtrada em banda que o modelo de iluminação explica na resposta.
Permitido 0–1
runner_up
number
A mesma medida para a melhor resposta diferente (outro lugar, rotação, escala ou paridade).
width, height
integer
O tamanho da imagem em pixels. Todos os valores em pixels abaixo estão neste referencial.
view
object | null
O disco na foto, null quando nada foi encontrado: cx, cy, R são o centro e o raio do disco em pixels (centros de pixel baseados em 0; para um close-up ficam bem fora do enquadramento); rho é o ângulo na tela do norte lunar, graus no sentido anti-horário a partir do topo da imagem; par é 1 para uma vista direta e -1 para uma espelhada; lon0, lat0 são o ponto sub-observador em graus selenográficos (longitude positiva para leste), isto é, a libração.
scale_km_px
number
Quilômetros por pixel no centro do disco: 1737,4 km divididos por R.
sun
object | null
O ponto subsolar, {lon, lat, score, terminator}, lido da foto: onde o terreno iluminado encontra o não iluminado no enquadramento, a longitude do Sol que melhor prevê qual é qual (lat é 0; o valor real está sempre dentro de 1,6°); score é a fração das amostras do enquadramento que ela prevê corretamente. Um disco inteiro sem terminador é uma Lua cheia (terminator: false, o Sol no ponto sub-observador). null para um close-up sem terminador: a fase não pode ser deduzida dele.
phase
object | null
De view e sun: angle_deg (o ângulo de fase: 0 cheia, 180 nova), fraction (iluminada), waxing, colongitude (a colongitude selenográfica do Sol: 0 no quarto crescente, 90 na cheia, 180 no quarto minguante) e name (new moon, waxing crescent, first quarter, waxing gibbous, full moon, waning gibbous, last quarter, waning crescent). null sem sun.
limb
object | null
A borda brilhante do disco como medida na foto, {cx, cy, R, arc, refined, locked} (pixels como em view; arc é a parte do círculo que foi medida), null quando nenhum limbo foi encontrado. locked: true significa que o círculo da vista é esta borda; caso contrário a textura da superfície posicionou a esfera por si, que fica dentro da borda transbordada de uma Lua superexposta.
frame
object | null
As coordenadas selenográficas sob o enquadramento: center e corners (top-left, top-right, bottom-right, bottom-left), cada um {lon, lat} ou null onde o ponto está fora do disco (os cantos de uma foto do disco inteiro).
stats
object
hyps (posições tentadas pela busca de close-up) e octaves (oitavas de escala buscadas); ambos 0 quando o limbo resolveu a questão.
timing_ms
object
decode, limb, disk, closeup, solve e o total do server, em milissegundos.
image
object
format (como o decodificador o nomeia: JPEG, PNG, …), width, height.
error
string
Por que não há solução (quando solved é false).
api_version
string
1.0
resposta (um close-up de Sinus Iridum ao nascer do Sol)
{
  "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 desenhar sobre a foto, projete um ponto selenográfico (lon, lat) com a vista: com p = (cos lat cos lon, cos lat sin lon, sin lat), e_z o mesmo vetor para (lon0, lat0), e_y o eixo da Lua tornado perpendicular a e_z e 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 ρ); o ponto está no lado visível quando p·e_z > 0.

Anotar uma imagem resolvida

POST/api/v1/annotate30 de uma vez · 30 por minuto

Desenha a grade de coordenadas, as constelações, os objetos de céu profundo (20.000 deles: Messier, NGC, IC, Sharpless, Barnard, Lynds, van den Bergh, Caldwell, os catálogos de aglomerados de estrelas, nebulosas planetárias, remanescentes de supernova, grupos de galáxias Arp, Hickson e Abell, RCW e Cederblad), as estrelas com nome e designação e, dada uma hora, o Sol, a Lua, os planetas, asteroides e cometas, como o Salvar imagem da oficina os desenha: os mesmos objetos, rótulos e estilos. Você envia o modelo de céu, não a imagem. A anotação não é recortada ao céu: a oficina encontra o horizonte na própria foto.

Parâmetros
sky model
one ofobrigatório
Exatamente um de corners, wcs, fits_header, projection ou solution: veja Modelos de céu.
width, height
integeropcional
O tamanho da imagem em pixels. Obrigatório com corners, wcs e projection; tirado de solution ou de NAXIS1/NAXIS2 do cabeçalho FITS caso contrário.
Permitido 8–100000
format
stringopcional
svg: um documento SVG do tamanho da imagem, transparente, para sobrepor à foto. json: os objetos, corpos, linhas e rótulos posicionados como dados (Saída JSON).
Padrão "svg"Permitido svg · json
time
stringopcional
Quando a foto foi tirada (ISO 8601 com deslocamento ou Z). Com ela, o Sol, a Lua, os planetas e Plutão são desenhados onde estavam (dentro de 1″ para 1850–2150), e os asteroides mais brilhantes e os cometas (dentro de cerca de 1″ para 1990–2041).
location
objectopcional
Onde foi tirada: a Lua se desloca em até um grau com o lugar do observador (a sua paralaxe). Sem um, a Lua é posicionada como vista do centro da Terra.
└lat
numberobrigatório
Latitude, graus norte.
Permitido -90–90
└lon
numberobrigatório
Longitude, graus leste.
Permitido -180–180
└height
numberopcional
Metros acima do nível do mar.
Permitido -500–10000
layout_width
integeropcional
A anotação é disposta como para a foto mostrada com esta largura em pixels, depois escalada ao seu tamanho: as larguras de linha e os tamanhos de fonte são pixels dessa vista. Maior: rótulos menores e mais deles.
Padrão 1400Permitido 200–8000
detail
numberopcional
Quanto mais mostrar, como ampliar faz na oficina: 0 a seleção padrão (objetos proeminentes), 1 todos os objetos que o filtro deixa passar.
Padrão 0Permitido 0–1
view
objectopcional
Camadas e estilos: veja Opções.
filter
objectopcional
Quais grupos e magnitudes aparecem: veja Opções.
edits
objectopcional
Objetos isolados ocultos ou renomeados: veja Opções.
requisição
{
  "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" } }
}

Com format: "svg" a resposta é image/svg+xml: <svg width="2048" height="1366" viewBox="0 0 2048 1366">…, nos pixels da foto. Um aviso sobre o modelo de céu, se houver, vem no cabeçalho SkySolver-Warning.

Modelos de céu

Envie o que você tiver; todos descrevem como os pixels da imagem se mapeiam no céu.

um de
corners
object
O céu no centro da imagem e nos seus quatro cantos externos, cada um {ra, dec}: center, top_left, top_right, bottom_right, bottom_left. Uma projeção gnomônica (TAN) é ajustada a eles; para lentes grande-angulares que distorcem, a resposta avisa a que distância os cantos ficam dela. Cada canto tem de estar a menos de 87° do centro: vistas mais largas precisam do projection do solver.
wcs
object
TAN ou TAN-SIP como o solver o dá: crval [RA, Dec], crpix [x, y] (baseado em 0), cd [[CD1_1, CD1_2], [CD2_1, CD2_2]] em graus por pixel e, opcionalmente, sip {order, a, b, inv_order, ap, bp} com termos [p, q, coeficiente].
fits_header
string
Um cabeçalho FITS WCS como texto (cartões de 80 caracteres, ou um cartão por linha): CTYPE1 = 'RA---TAN' ou 'RA---TAN-SIP', CRVAL, CRPIX (baseado em 1, como no FITS), e CD, ou PC com CDELT, ou CDELT com CROTA2; A_*, B_*, AP_*, BP_* do SIP. O que astrometry.net, ASTAP, PixInsight e este solver escrevem.
projection
object
O modelo de projeção do solver (panoramas, olho de peixe e imagens de todo o céu), como /solve o devolve.
solution
object
Uma resposta inteira de /solve: o seu tamanho e o seu wcs ou projection são usados.

Saída JSON

Com format: "json": o que a anotação desenha, em pixels da imagem (baseados em 0, y para baixo), e os rótulos como posicionados.

campos
width, height
integer
O tamanho da imagem para o qual a anotação foi desenhada.
field
object
center {ra, dec}, scale_arcsec (no centro), diagonal_deg (null para vistas de todo o céu).
layout
object
width (o layout_width usado) e scale: pixels da imagem por pixel de layout, pelo qual tamanhos e larguras foram multiplicados.
objects
array
Os objetos de céu profundo que o filtro e a vista selecionam, ocultos incluídos (shown: false).
└id, label
string
Designação (M 42, NGC 1977), como edits a aceita, e o rótulo desenhado (M42).
└name, catalogue_name
string | null
O nome desenhado (Orion Nebula, ou o dado em edits) e o próprio do catálogo.
└type, group, catalogs
string, string, array
Tipo legível, o seu grupo (emission…) e todos os grupos de catálogo em que está.
└other_designations
array
As suas outras designações: ["Mel 22", "LBN 770"].
└ra, dec, mag
number
Posição e magnitude (null quando desconhecida).
└size_arcmin, position_angle
array, number
[maior, menor] e o ângulo do norte para leste, quando conhecidos.
└x, y, radius_px
number
Onde está na imagem, e o seu raio em pixels.
└outline, closed
array | null, boolean
A sua forma como anéis [x0, y0, x1, y1, …] em pixels (um contorno traçado, ou a elipse do catálogo); closed é false quando a forma sai do domínio de uma vista de todo o céu e só pedaços dela são desenhados.
└shown
boolean
false quando edits.hidden o oculta.
bodies
array
Com time: o Sol, a Lua, os planetas, asteroides e cometas no enquadramento: id, name, kind (star, moon, planet, dwarf planet, asteroid, comet), ra, dec, mag (para um cometa, uma previsão grosseira), diameter_arcsec (null para asteroides e cometas), distance_au, phase (fração iluminada), elongation_deg, topocentric (posicionado como visto de location), uncertainty_arcsec (asteroides e cometas: quanto a posição pode estar errada), x, y, radius_px, outline, shown.
constellations
array
id, name, lines (polilinhas em pixels), stars, label_at.
grid
array
Linhas de RA e Dec: kind (ra ou dec), value (graus), label, lines.
lines
array
As linhas de referência ligadas: kind (ecliptic, galactic, borders), lines, label_at.
labels
array
Cada rótulo como posicionado, sem sobrepor os outros: text, of (o objeto), kind, x, y (a âncora da linha de base do texto), size, anchor (start, middle, end), color, opacity.
warnings, time, location
array, string, object
Avisos sobre o modelo de céu; a hora (UTC) e o lugar usados.

Opções

Todas opcionais, e parciais: o que você omite mantém os padrões da oficina. Valores fora do intervalo, e chaves que não existem, são recusados com 422 em vez de ignorados.

view
group_by
stringopcional
Os objetos recebem estilo e filtro por tipo ou por catálogo: types ou catalogs abaixo se aplicam então.
Padrão "type"Permitido type · catalog
grid
objectopcional
A grade RA/Dec: on e um estilo de linha (padrão #96beff, tracejada).
constellations
objectopcional
Traçados e nomes: on e um estilo de linha.
borders
objectopcional
Os limites das constelações da IAU (Delporte 1930, precessados para J2000): on (desligado por padrão) e um estilo de linha.
ecliptic, galactic
objectopcional
A eclíptica e o equador galáctico, com os seus nomes: on (desligado por padrão) e um estilo de linha.
shadow
objectopcional
Uma sombra sob toda a anotação: on (desligado por padrão), color, opacity, blur (0–16 px), distance (0–12 px).
objects
booleanopcional
Desenhar os objetos (e o Sol, a Lua, os planetas, asteroides e cometas).
Padrão true
labels
booleanopcional
Desenhar os rótulos.
Padrão true
types
objectopcional
Um estilo de linha por grupo de tipo, com as chaves de Grupos e estilos: {"emission": {"color": "#ff99cc"}}.
catalogs
objectopcional
Um estilo de linha por grupo de catálogo.
um estilo de linha
color
stringopcional
Cor de linha, marcador e rótulo.
Permitido #rrggbb
opacity
numberopcional
Opacidade das linhas e dos marcadores; os rótulos são desenhados um pouco mais opacos.
Permitido 0–1
width
numberopcional
Largura da linha, em pixels da vista de layout (veja layout_width).
Permitido 0.3–6
dash
stringopcional
Estilo de linha.
Permitido solid · dashed · dotted · dashdot
size
numberopcional
Tamanho da fonte dos rótulos, em pixels da vista de layout.
Permitido 6–32
filter
types
objectopcional
Grupos ligados ou desligados (com group_by: "type"): {"dark": false}. Todos ligados por padrão.
catalogs
objectopcional
O mesmo para catálogos (com group_by: "catalog").
magnitude
string | arrayopcional
auto: objetos Messier sempre, os outros conforme a sua proeminência no enquadramento (tamanho, ou um limite de magnitude que segue a escala da imagem). Um intervalo: objetos com magnitude dentro dele; os sem magnitude (a maioria das nebulosas) pelo tamanho.
Padrão "auto"Permitido "auto" · [brightest, faintest] within -2–18
edits
hidden
arrayopcional
Objetos a omitir, pela designação como objects[].id a dá: ["NGC 1999", "Mars"].
names
objectopcional
Nomes com que rotular objetos: {"NGC 1499": "California"}; uma string vazia rotula um objeto só pela sua designação.

Grupos e estilos

As chaves de view.types, filter.types, view.catalogs e filter.catalogs, com o seu estilo padrão (cor, opacidade, largura, linha, tamanho da fonte):

chave em typesGrupoPadrão
galaxyGaláxias#f4b8700.75 · 1 px · solid · 10.5 px
openAglomerados abertos#86d3f30.75 · 1 px · solid · 10.5 px
globularAglomerados globulares#f3dc8e0.78 · 1 px · solid · 10.5 px
emissionNebulosas de emissão#d4a5ff0.78 · 1 px · solid · 10.5 px
reflectionNebulosas de reflexão#9cc3ff0.75 · 1 px · solid · 10.5 px
planetaryNebulosas planetárias#7ee8c60.78 · 1 px · solid · 10.5 px
snrRemanescentes de supernova#ff9eb40.75 · 1 px · solid · 10.5 px
darkNebulosas escuras#b5c0d40.45 · 1 px · solid · 10.5 px
starEstrelas#fde9b00.7 · 0.9 px · solid · 10 px
solarSistema solar#e4f68e0.85 · 1.2 px · solid · 12 px
otherOutros#dce3f00.65 · 1 px · solid · 10.5 px
chave em catalogsGrupoPadrão
messierMessier#f7cf4a0.85 · 1 px · solid · 12 px
ngcNGC#86d3f30.75 · 1 px · solid · 10.5 px
icIC#aab8ff0.75 · 1 px · solid · 10.5 px
sharplessSharpless (Sh2)#d4a5ff0.78 · 1 px · solid · 10.5 px
barnardBarnard (B)#b5c0d40.5 · 1 px · solid · 10.5 px
ldnLynds escuras (LDN)#93a1b80.45 · 1 px · solid · 10.5 px
lbnLynds brilhantes (LBN)#f7a8d30.72 · 1 px · solid · 10.5 px
vdbvan den Bergh (vdB, vdBH)#9cc3ff0.75 · 1 px · solid · 10.5 px
caldwellCaldwell#7ee8c60.75 · 1 px · solid · 10.5 px
clustersAglomerados de estrelas (Collinder, Melotte, Trumpler, …)#a5e4f70.72 · 1 px · solid · 10.5 px
pnNebulosas planetárias (PN G, PK, Abell)#7ee8c60.78 · 1 px · solid · 10.5 px
snrRemanescentes de supernova (SNR G)#ff9eb40.75 · 1 px · solid · 10.5 px
groupsGrupos de galáxias (Arp, Hickson, Abell/ACO)#f4c48a0.7 · 1 px · solid · 10.5 px
rcwMais nebulosas (RCW, Gum, Cederblad, DWB)#e0b3ff0.72 · 1 px · solid · 10.5 px
starsEstrelas (nomes, Bayer, Flamsteed, HR, HD)#fde9b00.7 · 0.9 px · solid · 10 px
customOs seus catálogos (arquivos)#ffb86b0.85 · 1 px · solid · 11 px
vizierOnline (VizieR)#9fe8700.7 · 0.9 px · solid · 9.5 px
solarSistema solar#e4f68e0.85 · 1.2 px · solid · 12 px
otherOutros#dce3f00.65 · 1 px · solid · 10.5 px

Erros

Toda resposta de erro tem a mesma forma: um código para agir e uma mensagem para mostrar. Requisições inválidas listam cada problema:

422
{
  "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" }
  ]
}
StatuserrorQuando
400invalid_imageA imagem não é base64 válido, ou não pode ser lida.
400unsupported_formatO arquivo não é um dos formatos acima.
413payload_too_largeO corpo da requisição, o arquivo ou o seu número de pixels passa do limite.
422invalid_requestUm campo está ausente, do tipo errado, fora do intervalo ou é desconhecido; details lista cada um.
429rate_limitedO seu endereço de cliente esgotou as suas requisições; retry_after diz quando tentar de novo.
429busyO servidor está resolvendo o máximo que consegue; tente de novo após Retry-After.
500internal_errorAlgo falhou do nosso lado.
503unavailableO solver, o solver da Lua ou o anotador não está pronto.

Uma imagem que não pode ser resolvida não é um erro: a resposta é 200 com solved: false.

Estado do serviço

GET/api/v1/health60 de uma vez · 60 por minuto

O estado do serviço, os índices de estrelas, o solver da Lua e os workers de anotação carregados, e os limites em vigor.

resposta
{
  "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 compatível com Astrometry.net

Programas que resolvem a astrometria online com o astrometry.net (nova.astrometry.net) podem usar o SkySolver no lugar dele: configure o servidor deles para https://skysolver.app. Qualquer chave de API funciona, uma vazia também; não há contas. As rotas, as respostas e os arquivos são os do nova, até os detalhes de que os seus clientes dependem, na raiz do site (/api/…, /wcs_file/…).

ProgramaConfiguração
N.I.N.A.Options → Plate solving → Astrometry.net: URL https://skysolver.app, qualquer chave de API
KStars / EkosAlign → solver options → Online (astrometry.net): API URL https://skysolver.app (https: o StellarSolver o acrescenta de qualquer forma), qualquer chave
astroqueryAstrometryNet() com URL = "https://skysolver.app", API_URL = "https://skysolver.app/api", qualquer api_key
client.py (astrometry.net)--server https://skysolver.app/api/ --apikey anything; o script online do CCDciel o usa
AstroImageJPlate solve → custom server https://skysolver.app, chave vazia
SGPo solver ANSVR, Server URL https://skysolver.app/api (as rotas que o SGP chama estão lá; não testado com o próprio SGP)
astroquery
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)
RotaO que faz aqui
POST /api/loginUma sessão para qualquer chave.
POST /api/uploadUma imagem (JPEG, PNG, TIFF, FITS, XISF, BMP, GIF, WebP), uma lista x,y (uma tabela FITS com X e Y, ou texto com um x y por linha), ou listas x e y em request-json. Até 96 MB.
POST /api/url_uploadSó listas x e y (como o astroquery as envia): uma URL não é buscada.
/api/submissions/IDA submissão e o seu job: o job está lá desde a primeira consulta.
/api/jobs/IDprocessing, solving, success ou failure; todo job termina num dos dois últimos.
/api/jobs/ID/calibration/ra, dec, radius, pixscale, orientation, parity, width_arcsec, height_arcsec, calculados como o nova faz.
/api/jobs/ID/info/ · tags/ · machine_tags/ · objects_in_field/ · annotations/Os objetos de céu profundo no campo, com as suas posições em pixels e os raios em annotations.
/wcs_file/IDA solução TAN-SIP como arquivo FITS só com cabeçalho (wcs.fits).
/corr_file/ID · /axy_file/ID · /rdls_file/IDAs estrelas identificadas, as estrelas detectadas, as estrelas de catálogo identificadas: tabelas FITS nas colunas do nova.
/joblog/IDO que o job fez, como texto.
  • Sempre às cegas. Dicas de escala, posição e paridade são aceitas e ignoradas: o solver não precisa de nenhuma, e uma dica errada não pode estragar uma solução.
  • Pixels são os do nova: (1, 1) é o centro do primeiro pixel armazenado, o canto superior esquerdo de um JPEG ou PNG (a sua orientação EXIF não aplicada) ou a primeira linha de um arquivo FITS, seja qual for o seu ROWORDER. A orientation mantém a peculiaridade do nova para envios JPEG, PNG e GIF, para que os programas que a revertem obtenham o mesmo ângulo que do nova.
  • Panoramas e imagens de todo o céu resolvidos com um modelo de projeção têm calibração mas não wcs_file: nenhum TAN-SIP os comporta.
  • Nenhuma imagem é guardada. Um envio é descartado assim que as suas estrelas são encontradas, portanto new_fits_file e as imagens anotada, vermelho-verde e de extração não são oferecidas. Os resultados de um job ficam em memória por 30 minutos, depois são esquecidos.
  • Limites: envios 20 de uma vez e 6 por minuto por endereço; as outras rotas contam como requisições leves (60 de uma vez, 60 por minuto).

Histórico de versões

  • 1.2 (19 de outubro de 2026): resolução da Lua: /api/v1/solve/moon.
  • 1.1 (17 de outubro de 2026): a API compatível com Astrometry.net.
  • 1.0 (16 de outubro de 2026): resolver uma imagem (base64) ou posições de estrelas, anotar como SVG ou JSON, com o Sol, a Lua e os planetas.

Perguntas, um bug, uma cota maior? [email protected]. Ao usar a API você aceita os termos; o que ela faz com os seus dados está na página de privacidade.