Astronomy API Bodies API
Celestial body information and positions
Celestial body information and positions
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/astronomy-api:astronomy-api-bodies-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Astronomy Bodies API
contact:
name: AstronomyAPI
url: https://astronomyapi.com
version: '1.0'
description: 'Operations tagged Bodies across 2 of this provider''s published API definitions: astronomy-api-openapi.yml, astronomy-api-v3-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.astronomyapi.com/api/v2
description: Astronomy API v2
- url: https://api.astronomyapi.com/api/v3
description: Production
tags:
- name: Bodies
description: Celestial body information and positions
paths:
/bodies:
get:
tags:
- Bodies
summary: List supported celestial bodies
security:
- basicAuth: []
responses:
'200':
description: List of celestial bodies
'401':
description: Unauthorized
'403':
description: Forbidden
operationId: getBodies
x-operation-id-source: derived
servers:
- url: https://api.astronomyapi.com/api/v2
description: Astronomy API v2
/bodies/positions:
get:
tags:
- Bodies
summary: Get positions of all bodies for an observer
security:
- basicAuth: []
parameters:
- name: latitude
in: query
required: true
schema:
type: number
format: float
- name: longitude
in: query
required: true
schema:
type: number
format: float
- name: elevation
in: query
schema:
type: number
format: float
- name: from_date
in: query
required: true
schema:
type: string
format: date
- name: to_date
in: query
required: true
schema:
type: string
format: date
- name: time
in: query
required: true
schema:
type: string
examples:
- '12:00:00'
- name: output
in: query
schema:
type: string
enum:
- rows
- table
responses:
'200':
description: Body positions
operationId: getBodiesPositions
x-operation-id-source: derived
servers:
- url: https://api.astronomyapi.com/api/v2
description: Astronomy API v2
/bodies/positions/{body}:
get:
tags:
- Bodies
summary: Get positions of a single body for an observer
security:
- basicAuth: []
parameters:
- name: body
in: path
required: true
schema:
type: string
examples:
- sun
- moon
- mars
- name: latitude
in: query
required: true
schema:
type: number
format: float
- name: longitude
in: query
required: true
schema:
type: number
format: float
- name: elevation
in: query
schema:
type: number
format: float
- name: from_date
in: query
required: true
schema:
type: string
format: date
- name: to_date
in: query
required: true
schema:
type: string
format: date
- name: time
in: query
required: true
schema:
type: string
responses:
'200':
description: Position data for the body
operationId: getBodiesPositionsByBody
x-operation-id-source: derived
servers:
- url: https://api.astronomyapi.com/api/v2
description: Astronomy API v2
/positions:
get:
tags:
- Bodies
summary: Positions of one or more bodies over a span of time
operationId: getPositions
description: 'Returns where each requested body appears from the observer''s
location, sampled from `from` to `to` at intervals of `step`.
Sampling is the main thing v3 adds. v2 could only return one
position per day at a fixed time of day; `step` accepts any ISO
8601 duration, so an altitude curve is one request rather than
twenty-four.'
parameters:
- $ref: '#/components/parameters/Bodies'
- $ref: '#/components/parameters/Latitude'
- $ref: '#/components/parameters/Longitude'
- $ref: '#/components/parameters/Elevation'
- $ref: '#/components/parameters/From'
- $ref: '#/components/parameters/To'
- $ref: '#/components/parameters/Step'
- $ref: '#/components/parameters/Timezone'
- $ref: '#/components/parameters/Origin'
- $ref: '#/components/parameters/Refraction'
- $ref: '#/components/parameters/Include'
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Cursor'
responses:
'200':
description: Positions for each requested body.
content:
application/json:
schema:
$ref: '#/components/schemas/PositionsResponse'
examples:
singleBody:
summary: Mars from London, one instant
value:
meta:
observer:
latitude: 51.4779
longitude: -0.0015
elevation: 0
timezone: Europe/London
units:
rightAscension: hours
declination: degrees
altitude: degrees
azimuth: degrees
distance: au
frames:
equatorial: J2000
horizontal: apparent, refracted
sampling:
from: '2024-06-21T11:00:00Z'
to: '2024-06-21T11:00:00Z'
step: PT1H
count: 1
data:
- body:
id: mars
name: Mars
samples:
- time: '2024-06-21T11:00:00Z'
rightAscension: 2.44012
declination: 13.41983
altitude: 41.26454
azimuth: 232.99871
distance:
au: 1.7782248
km: 266018470.2
constellation:
abbreviation: Ari
name: Aries
elongation: 51.52915
magnitude: 1.00953
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/UnprocessableEntity'
security:
- applicationKey: []
servers:
- url: https://api.astronomyapi.com/api/v3
description: Production
/events:
get:
tags:
- Bodies
summary: Eclipses and apsides for the observer's location
operationId: getEvents
description: 'Returns the events falling between `from` and `to`, as seen from the
observer''s location.
**Eclipses** are reported for the Sun and the Moon, with the
altitude of the body at each contact so that it is clear how much of
the event happens above the horizon. A solar eclipse is reported as
this observer sees it, so the same eclipse is total from one place
and partial from another.
**Apsides** are reported for every body: the moments its distance
from the Earth stops changing direction. They alternate between
perigee and apogee. For a planet the perigee is when it appears
largest and brightest, falling within days of opposition.
v2 offered only eclipses, and only for the Sun and the Moon.'
parameters:
- $ref: '#/components/parameters/EventBodies'
- $ref: '#/components/parameters/EventTypes'
- $ref: '#/components/parameters/Latitude'
- $ref: '#/components/parameters/Longitude'
- $ref: '#/components/parameters/Elevation'
- $ref: '#/components/parameters/From'
- $ref: '#/components/parameters/To'
- $ref: '#/components/parameters/Timezone'
responses:
'200':
description: Events for each requested body.
content:
application/json:
schema:
$ref: '#/components/schemas/EventsResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/UnprocessableEntity'
security:
- applicationKey: []
servers:
- url: https://api.astronomyapi.com/api/v3
description: Production
components:
schemas:
Contact:
type: object
required:
- time
- altitude
properties:
time:
type: string
format: date-time
altitude:
type: number
description: 'Degrees above the horizon at that moment. Negative means the
stage happens with the body below the horizon and so unseen.
'
Constellation:
type: object
required:
- abbreviation
- name
properties:
abbreviation:
type: string
description: 'The IAU three-letter abbreviation, correctly capitalised.
This is the stable identifier; v2 also returned a lowercase
copy of it, which v3 drops.
'
examples:
- Ari
- CVn
name:
type: string
examples:
- Aries
Sample:
type: object
required:
- time
- rightAscension
- declination
- altitude
- azimuth
- distance
- constellation
properties:
time:
type: string
format: date-time
rightAscension:
type: number
description: Hours, in [0, 24).
declination:
type: number
description: Degrees, in [-90, 90].
altitude:
type: number
description: 'Degrees above the horizon. Negative when the body is below
it, which is a legitimate answer rather than an error.
'
azimuth:
type: number
description: Degrees clockwise from true north, in [0, 360).
distance:
$ref: '#/components/schemas/Distance'
constellation:
$ref: '#/components/schemas/Constellation'
elongation:
type: number
description: 'Degrees between the body and the Sun as seen from the
observer. Absent for the Sun.
'
magnitude:
type: number
description: Apparent visual magnitude. Smaller is brighter.
phase:
$ref: '#/components/schemas/Phase'
formatted:
$ref: '#/components/schemas/Formatted'
ApsisEvent:
type: object
description: 'The moment a body''s distance from the Earth stops changing
direction. Every body has these, and they alternate.
For the Moon they are the familiar perigee and apogee. For a planet
the perigee falls within days of opposition, or of inferior
conjunction for Mercury and Venus, and is when it appears largest
and brightest. The Sun''s perigee is the Earth''s own perihelion, in
early January.
'
required:
- type
- kind
- time
- distance
properties:
type:
type: string
enum:
- apsis
kind:
type: string
enum:
- perigee
- apogee
description: Nearest to the Earth, or farthest from it.
time:
type: string
format: date-time
altitude:
type: number
description: Degrees above the horizon at that moment.
distance:
$ref: '#/components/schemas/Distance'
PositionsResponse:
type: object
required:
- meta
- data
properties:
meta:
$ref: '#/components/schemas/Meta'
data:
type: array
description: One entry per requested body, in the order asked for.
items:
$ref: '#/components/schemas/BodySamples'
BodySamples:
type: object
required:
- body
- samples
properties:
body:
$ref: '#/components/schemas/BodyIdentity'
samples:
type: array
items:
$ref: '#/components/schemas/Sample'
EventsResponse:
type: object
required:
- meta
- data
properties:
meta:
type: object
required:
- observer
- timezone
- window
properties:
observer:
$ref: '#/components/schemas/Observer'
timezone:
type: string
window:
type: object
required:
- from
- to
properties:
from:
type: string
format: date-time
to:
type: string
format: date-time
data:
type: array
items:
type: object
required:
- body
- events
properties:
body:
$ref: '#/components/schemas/BodyIdentity'
events:
type: array
items:
$ref: '#/components/schemas/Event'
Problem:
type: object
description: 'An error, as RFC 9457 problem details. v2 returned the raw output of
its schema validator, which exposed internal paths such as
`instance.latitude` and had no stable machine-readable code.
'
required:
- type
- title
- status
properties:
type:
type: string
format: uri
description: Stable identifier for the kind of problem.
examples:
- https://astronomyapi.com/problems/invalid-parameter
title:
type: string
examples:
- Invalid parameter
status:
type: integer
examples:
- 422
detail:
type: string
examples:
- latitude must be between -90 and 90 degrees.
errors:
type: array
description: One entry per parameter at fault.
items:
type: object
required:
- parameter
- code
- detail
properties:
parameter:
type: string
examples:
- latitude
code:
type: string
examples:
- out_of_range
detail:
type: string
Contacts:
type: object
description: 'The moments the eclipse passes from one stage to the next, each with
the altitude of the body at that instant so it is clear how much of
the event is above the horizon.
v2 called this block `eventHighlights`, and named the same two
moments `fullStart` and `fullEnd` for lunar eclipses but
`totalStart` and `totalEnd` for solar ones. v3 uses the `total`
names throughout.
'
required:
- partialStart
- partialEnd
properties:
penumbralStart:
$ref: '#/components/schemas/Contact'
partialStart:
$ref: '#/components/schemas/Contact'
totalStart:
description: Null when the eclipse does not reach totality here.
oneOf:
- $ref: '#/components/schemas/Contact'
- type: 'null'
totalEnd:
oneOf:
- $ref: '#/components/schemas/Contact'
- type: 'null'
partialEnd:
$ref: '#/components/schemas/Contact'
penumbralEnd:
$ref: '#/components/schemas/Contact'
Sampling:
type: object
required:
- from
- to
- step
- count
properties:
from:
type: string
format: date-time
to:
type: string
format: date-time
step:
type: string
description: ISO 8601 duration between samples.
count:
type: integer
description: Samples returned per body.
nextCursor:
type: string
description: 'Present only when the span was truncated by `limit`. Pass it
back as `cursor` to continue.
'
Phase:
type: object
description: Returned for the Moon only.
required:
- angle
- fraction
- name
properties:
angle:
type: number
description: 'Degrees by which the Moon leads the Sun in ecliptic
longitude: 0 at new, 90 at first quarter, 180 at full.
v2 spelled this field `angel`.
'
fraction:
type: number
minimum: 0
maximum: 1
description: 'Fraction of the Moon''s disc that is lit, from 0 at new to 1
at full.
v2''s figure for this was wrong twice over: it was scaled to
a range of 0 to 0.067, and it ran backwards, reporting its
largest value at new moon.
'
name:
type: string
enum:
- New Moon
- Waxing Crescent
- First Quarter
- Waxing Gibbous
- Full Moon
- Waning Gibbous
- Last Quarter
- Waning Crescent
EclipseEvent:
type: object
required:
- type
- kind
- time
- contacts
- obscuration
properties:
type:
type: string
description: 'v2 combined this with `kind` into a single string such as
`partial_lunar_eclipse`, which had to be taken apart before
either half could be used.
'
enum:
- lunar_eclipse
- solar_eclipse
kind:
type: string
description: 'How complete the eclipse is as seen from this location.
`penumbral` occurs only for lunar eclipses and `annular`
only for solar ones.
'
enum:
- penumbral
- partial
- annular
- total
time:
type: string
format: date-time
description: The peak of the eclipse.
altitude:
type: number
description: Degrees above the horizon at peak.
contacts:
$ref: '#/components/schemas/Contacts'
obscuration:
type: number
minimum: 0
maximum: 1
description: Fraction of the body's disc covered at peak.
rise:
type: string
format: date-time
description: When the body rose on the day of the event.
set:
type: string
format: date-time
description: When the body set on the day of the event.
BodyIdentity:
type: object
required:
- id
- name
properties:
id:
$ref: '#/components/schemas/BodyId'
name:
type: string
description: Display name.
examples:
- Mars
Meta:
type: object
required:
- observer
- timezone
- units
- frames
- sampling
properties:
observer:
$ref: '#/components/schemas/Observer'
timezone:
type: string
description: IANA zone the instants below are expressed in.
examples:
- Europe/London
units:
type: object
description: 'The unit each quantity is in. Present so that no caller has
to infer that right ascension is the one field not in
degrees.
'
additionalProperties:
type: string
examples:
- rightAscension: hours
declination: degrees
altitude: degrees
azimuth: degrees
distance: au
frames:
type: object
description: 'The reference frame each set of coordinates is referred to.
Equatorial coordinates are J2000 unless stated otherwise;
horizontal coordinates are apparent, meaning corrected for
light travel time, the observer''s motion, and refraction
unless it was turned off.
'
additionalProperties:
type: string
sampling:
$ref: '#/components/schemas/Sampling'
BodyId:
type: string
description: 'Stable lowercase identifier for a body. This is the complete set.
'
enum:
- sun
- moon
- mercury
- venus
- mars
- jupiter
- saturn
- uranus
- neptune
- pluto
Distance:
type: object
required:
- au
- km
properties:
au:
type: number
description: Astronomical units from the observer.
km:
type: number
description: 'The same distance in kilometres. Returned so that callers do
not each hard-code their own value for the astronomical
unit and disagree with each other.
'
Event:
description: 'An event is one of two shapes, told apart by `type`. Eclipses carry
the moments they pass from one stage to the next; apsides carry a
distance. Neither has the other''s fields.
'
oneOf:
- $ref: '#/components/schemas/EclipseEvent'
- $ref: '#/components/schemas/ApsisEvent'
discriminator:
propertyName: type
mapping:
lunar_eclipse: '#/components/schemas/EclipseEvent'
solar_eclipse: '#/components/schemas/EclipseEvent'
apsis: '#/components/schemas/ApsisEvent'
Formatted:
type: object
description: 'Sexagesimal renderings of the angles above, present only when
`include=formatted` is given.
'
properties:
rightAscension:
type: string
examples:
- 02h 26m 24s
declination:
type: string
examples:
- 13° 25' 12"
altitude:
type: string
examples:
- 41° 15' 36"
azimuth:
type: string
examples:
- 233° 0' 0"
Observer:
type: object
required:
- latitude
- longitude
- elevation
properties:
latitude:
type: number
description: Degrees, positive north.
longitude:
type: number
description: Degrees, positive east.
elevation:
type: number
description: Metres above sea level.
parameters:
Elevation:
name: elevation
in: query
required: false
description: 'Height of the observer above sea level, in metres. Defaults to sea
level. The upper bound covers the highest permanent observatories.
'
schema:
type: number
default: 0
minimum: -500
maximum: 9000
Timezone:
name: timezone
in: query
required: false
description: 'IANA zone the returned instants are expressed in. `auto` derives it
from the observer''s coordinates, which is what v2 always did and
remains the default. `UTC` is the unambiguous choice.
'
schema:
type: string
default: auto
examples:
- auto
- UTC
- Europe/London
EventTypes:
name: types
in: query
required: false
style: form
explode: false
description: 'Which kinds of event to report. Omit for all that apply to the
bodies asked for.
'
schema:
type: array
items:
type: string
enum:
- lunar_eclipse
- solar_eclipse
- apsis
To:
name: to
in: query
required: true
description: Last instant to sample. Must not precede `from`.
schema:
type: string
examples:
- '2024-06-22T00:00:00Z'
Cursor:
name: cursor
in: query
required: false
description: Opaque cursor from `meta.sampling.nextCursor`.
schema:
type: string
EventBodies:
name: bodies
in: query
required: false
style: form
explode: false
description: 'Which bodies to report events for. Omit for all of them.
v2 accepted only the Sun and the Moon here, because eclipses were
the only events it knew about. Every body has apsides, so v3
accepts the full list.
'
schema:
type: array
items:
$ref: '#/components/schemas/BodyId'
From:
name: from
in: query
required: true
description: 'First instant to sample, as an ISO 8601 date or date-time. A bare
date means midnight UTC on that date.
'
schema:
type: string
examples:
- '2024-06-21T00:00:00Z'
- '2024-06-21'
Include:
name: include
in: query
required: false
description: 'Optional extras, comma separated. `formatted` adds a parallel block
of sexagesimal strings for each angle, which v2 always sent whether
or not the caller wanted them.
'
schema:
type: string
examples:
- formatted
Origin:
name: origin
in: query
required: false
description: 'Whether to measure from the observer''s own position or from the
centre of the Earth. The difference is parallax, worth up to about
a degree for the Moon and arcseconds for the planets.
'
schema:
type: string
default: topocentric
enum:
- topocentric
- geocentric
Step:
name: step
in: query
required: false
description: 'Interval between samples, as an ISO 8601 duration. `P1D` reproduces
v2''s one-sample-per-day behaviour, which is the default.
'
schema:
type: string
default: P1D
pattern: ^P(?!$)(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$
examples:
- PT1H
- PT15M
- P1D
Bodies:
name: bodies
in: query
required: false
style: form
explode: false
description: 'Which bodies to report, as a comma-separated list of ids. Omit to
get all of them.
The list is fixed and is given here in full, so there is nothing to
look up at runtime. v2 had a `/bodies` endpoint that returned it;
v3 does not, because a request to learn ten constants that never
change is a round trip for nothing.
`earth` is absent deliberately. Seen from the Earth it is at zero
distance and has no direction, so the numbers v2 returned for it
were whatever fell out of the arithmetic.
'
schema:
type: array
items:
$ref: '#/components/schemas/BodyId'
examples:
one:
summary: A single body
value:
- moon
several:
summary: Several bodies
value:
- mars
- venus
Longitude:
name: longitude
in: query
required: true
description: Longitude of the observer, in degrees, positive east.
schema:
type: number
minimum: -180
maximum: 180
examples:
- -0.0015
Latitude:
name: latitude
in: query
required: true
description: Latitude of the observer, in degrees, positive north.
schema:
type: number
minimum: -90
maximum: 90
examples:
- 51.4779
Refraction:
name: refraction
in: query
required: false
description: 'Whether the altitude accounts for the atmosphere bending light near
the horizon. `none` gives the geometric altitude.
'
schema:
type: string
default: standard
enum:
- standard
- none
Limit:
name: limit
in: query
required: false
description: Most samples to return per body before paginating.
schema:
type: integer
default: 1000
minimum: 1
maximum: 10000
responses:
UnprocessableEntity:
description: The request was understood but a parameter was unacceptable.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
BadRequest:
description: The request could not be parsed.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
Unauthorized:
description: The application key was missing or not recognised.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
securitySchemes:
basicAuth:
type: http
scheme: basic
description: 'HTTP Basic auth: username is the Application ID and password is the
Application Secret. The client typically sends
`Authorization: Basic base64(applicationId:applicationSecret)`.
'
applicationKey:
type: http
scheme: bearer
description: 'The application key, sent as `Authorization: Bearer <key>`. Keys are
never accepted in the query string, where they would be recorded in
logs and browser history.
'
x-refined-from:
- astronomy-api-openapi.yml
- astronomy-api-v3-openapi.yaml