MPC Orbits API¶
This tutorial provides information on how to use the Minor Planet Center's Orbits API.¶
The Minor Planet Center's Orbits service returns orbital elements and related parameters for solar system objects.
This is useful when you want to:
- Retrieve the best-fit orbital elements for an asteroid or comet
- Access orbital uncertainties and covariance information
- Get orbit-derived quantities like absolute magnitude, epoch, and orbital classification
- Perform ephemeris calculations or orbit propagation
The Orbits API is a REST endpoint. You can send GET requests to:
https://data.minorplanetcenter.net/api/get-orb
In the examples below we use Python code to query the API.
Further information and documentation can be found at:
- https://docs.minorplanetcenter.net/mpc-ops-docs/apis/get-orb
- https://github.com/Smithsonian/mpc-public/tree/main/mpc_orb (Python package for working with mpc_orb format)
Import Packages¶
Here we import the standard Python packages needed to call the API and interpret the returned data.
import requests
import json
API Parameters¶
The Orbits API accepts the following parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
desig |
String | Yes | Name, permanent number, or provisional designation of the object |
Note: Both packed and unpacked designation formats are supported. Currently limited to single object queries.
Response Format¶
The API returns data in the mpc_orb JSON format, which contains comprehensive orbital information including:
- Keplerian orbital elements (a, e, i, node, argperi, meananomaly)
- Epoch and coordinate system information
- Physical parameters (absolute magnitude H, slope G)
- Orbital uncertainties and covariance matrix
- Object classification and identifiers
Basic Query: By Name¶
Here we query for the orbital elements of asteroid Ceres, the first discovered asteroid.
# Query orbit for Ceres by name
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "Ceres"}
)
if response.ok:
result = response.json()
mpc_orb = result[0]['mpc_orb'][0]
print(json.dumps(mpc_orb, indent=4))
else:
print(f"Error: {response.status_code}")
print(response.content)
Query by Permanent Number¶
You can also query using the asteroid's permanent number.
# Query orbit by permanent number
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "433"} # 433 Eros
)
if response.ok:
mpc_orb_dict = response.json()[0]['mpc_orb'][0]
cartesian_coefficient_names = mpc_orb_dict['CAR']['coefficient_names']
cartesian_coefficient_values = mpc_orb_dict['CAR']['coefficient_values']
print(f"{cartesian_coefficient_names=}\n{cartesian_coefficient_values=}")
else:
print(f"Error: {response.status_code}")
Query by Provisional Designation¶
Provisional designations work too, in either packed or unpacked format.
# Query by unpacked provisional designation
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "2023 BU"} # Famous close-approach asteroid
)
if response.ok:
mpc_orb = response.json()[0]['mpc_orb'][0]
desig_data = mpc_orb.get('designation_data', {})
print(f"Primary designation: {desig_data.get('unpacked_primary_provisional_designation')}")
print(f"Packed designation: {desig_data.get('packed_primary_provisional_designation')}")
else:
print(f"Error: {response.status_code}")
Extracting Orbital Elements¶
The mpc_orb format contains detailed orbital elements. Here's how to extract the key Keplerian elements.
# Get orbit for Bennu (OSIRIS-REx target)
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "Bennu"}
)
if response.ok:
# Extract a dictionary containing all orbit information & print all dictionary keys:
mpc_orb = response.json()[0]['mpc_orb'][0]
print("Orbit data keys:")
for key in mpc_orb: print(f"\t{key}")
# Extract "cometarian" orbital data into another dictionary
cometarian_data = mpc_orb['COM']
print("Cometarian data keys:")
for key in cometarian_data: print(f"\t{key}")
# Print the "cometarian" orbital quantities and associated uncertainties
print("Cometarian element data:")
for (name, value, unc) in zip(cometarian_data["coefficient_names"],cometarian_data["coefficient_values"],cometarian_data["coefficient_uncertainties"]):
print(f"{name, value, unc=}")
else:
print(f"Error: {response.status_code}")
Understanding the mpc_orb Structure¶
The mpc_orb format is hierarchically organized. Let's explore its structure.
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "Apophis"}
)
if response.ok:
mpc_orb = response.json()[0]['mpc_orb'][0]
print("Top-level keys in mpc_orb:")
for key in mpc_orb.keys():
value = mpc_orb[key]
if isinstance(value, dict):
print(f" {key}: dict with {len(value)} keys")
elif isinstance(value, list):
print(f" {key}: list with {len(value)} items")
else:
print(f" {key}: {type(value).__name__}")
else:
print(f"Error: {response.status_code}")
Designation Data¶
The designation_data section contains identifiers and naming information.
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": "Apophis"}
)
if response.ok:
mpc_orb = response.json()[0]['mpc_orb'][0]
desig_data = mpc_orb.get('designation_data', {})
print("Designation Data for Apophis:")
print(json.dumps(desig_data, indent=2))
else:
print(f"Error: {response.status_code}")
Physical Parameters¶
Absolute magnitude (H) and slope parameter (G) are included when available.
# Compare H magnitudes of different asteroids
asteroids = ["Ceres", "Vesta", "Bennu", "Apophis"]
print("Absolute Magnitudes (H):")
print("-" * 30)
for asteroid in asteroids:
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": asteroid}
)
if response.ok:
mpc_orb = response.json()[0]['mpc_orb'][0]
# H magnitude location may vary in the structure
h_mag = mpc_orb.get('magnitude_data', {}).get('H')
if h_mag is None:
# Try alternative location
h_mag = mpc_orb.get('H')
print(f"{asteroid:10s}: H = {h_mag}")
else:
print(f"{asteroid:10s}: Error {response.status_code}")
Error Handling¶
When querying for an object that doesn't exist, the API does NOT return an error, but returns an empty mpc_orb component as illustrated below.
# Query for an existing object & a non-existent object:
for desig in ["Ceres", "NotAnAsteroidName"]:
# Make the query
response = requests.get( "https://data.minorplanetcenter.net/api/get-orb", json={"desig": desig})
print(f"Queried {desig=}, {response.status_code=}, {response.ok=}")
# Extract the mpc-orb component from the response
mpc_orb_list = response.json()[0]['mpc_orb']
# Use the extracted list to check for content/existence
print( "\tOrbit data found\n" if response.json()[0]['mpc_orb'] else "\tNo data found\n")
Helper Function¶
Here's a convenient helper function for querying orbits.
def get_orbit(designation):
"""
Retrieve orbital elements for an object from the MPC.
Parameters
----------
designation : str
Object designation (name, number, or provisional designation)
Returns
-------
dict or None
The mpc_orb dictionary, or None if not found
"""
response = requests.get(
"https://data.minorplanetcenter.net/api/get-orb",
json={"desig": designation}
)
if not response.ok:
return None
result = response.json()
if result and 'mpc_orb' in result[0] and result[0]['mpc_orb']:
return result[0]['mpc_orb'][0]
return None
def get_orbital_period(designation):
"""
Calculate the orbital period in years from semi-major axis.
Uses Kepler's third law: P^2 = a^3 (with P in years, a in AU)
"""
orbit = get_orbit(designation)
if orbit is None:
return None
# Extract coordinates and use to get the semi-major axis
try:
coords = { name:value for name,value in zip(orbit["COM"]['coefficient_names'],orbit["COM"]['coefficient_values'])}
a = coords['q']/(1-coords['e'])
return a ** 1.5 # Kepler's third law
except:
return None
# Example usage: `get_orbit`
orbit = get_orbit("Eros")
if orbit:
print(f"Successfully retrieved orbit for Eros")
print(f"Designation data: {orbit['designation_data']['permid']}")
else:
print("Failed to retrieve orbit")
# Example usage: `get_orbital_period`
period = get_orbital_period("Ceres")
print(f"{period=}")
if period:
print(f"Successfully retrieved period for Ceres: {period=}")
else:
print("Failed to retrieve period data")
Using the mpc_orb Python Package¶
The MPC provides a Python package for working with mpc_orb format files. You can install it with:
pip install mpc-orb
This package provides validation and parsing utilities for the mpc_orb JSON format.
Further information on using this package can be found at:
- https://github.com/Smithsonian/mpc-public/tree/main/mpc_orb
<insert link to future mpc-orb tutorial>
Summary¶
The MPC Orbits API provides access to orbital elements for solar system objects.
Key points:
- Endpoint:
https://data.minorplanetcenter.net/api/get-orb - Required parameter:
desig- object designation (name, number, or provisional) - Response format:
mpc_orbJSON format with comprehensive orbital data - Current limitation: Single object queries only
The mpc_orb format includes:
- Orbital elements in multiple coordinate systems
- Epoch and time system information
- Designation data (names, numbers, provisional designations)
- Physical parameters (H, G when available)
- Uncertainty information
For questions or feedback, contact the MPC via the Jira Helpdesk.