MPC Observatory Codes API¶
This tutorial provides information on how to use the Minor Planet Center's Observatory Codes API.¶
The Minor Planet Center's Observatory Codes service returns information about observatories registered with the MPC.
This is useful when you want to:
- Look up details about a specific observatory by its code
- Get the geographic location (longitude, parallax constants) of an observatory
- Find the full name of an observatory from its code
- Retrieve a list of all registered observatories
The Observatory Codes API is a REST endpoint. You can send GET requests to:
https://data.minorplanetcenter.net/api/obscodes
In the examples below we use Python code to query the API.
Further information and documentation can be found at:
Import Packages¶
Here we import the standard Python packages needed to call the API and interpret the returned data.
import requests
import json
import pandas as pd
API Parameters¶
The Observatory Codes API accepts the following parameters:
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
obscode |
String | No | Three-character observatory code | None (returns all) |
format |
String | No | Output format: JSON or ObsCodes.html |
JSON |
If no obscode is provided, the API returns information for all observatories.
Query Single Observatory¶
Here we query for information about a specific observatory. Observatory code 500 is the geocenter.
# Query for observatory 500 (Geocentric)
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={"obscode": "500"}
)
if response.ok:
result = response.json()
print(json.dumps(result, indent=4))
else:
print(f"Error: {response.status_code}")
Response Fields¶
The JSON response includes these fields:
| Field | Description |
|---|---|
obscode |
Three-character observatory code |
longitude |
Longitude (east of prime meridian) |
rhocosphi |
Parallax constant: ρ cos(φ') |
rhosinphi |
Parallax constant: ρ sin(φ') |
name |
Observatory name (ASCII) |
name_utf8 |
Observatory name (Unicode) |
name_latex |
Observatory name (LaTeX) |
short_name |
Abbreviated name |
firstdate / lastdate |
Date range of observations (YYYYMMDD) |
web_link |
Observatory website URL |
observations_type |
Type: optical, radar, satellite, etc. |
Famous Observatories¶
Let's look up some well-known observatories.
# Some notable observatory codes
observatories = {
"675": "Palomar Mountain",
"568": "Mauna Kea",
"G96": "Mt. Lemmon Survey",
"F51": "Pan-STARRS 1",
"703": "Catalina Sky Survey",
"C51": "WISE",
"250": "Hubble Space Telescope"
}
print(f"{'Code':<6} {'Name':<40} {'Type':<12}")
print("-" * 60)
for code, expected_name in observatories.items():
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={"obscode": code}
)
if response.ok:
data = response.json()
name = data.get('name', 'Unknown')[:38]
obs_type = data.get('observations_type', 'Unknown')
print(f"{code:<6} {name:<40} {obs_type:<12}")
else:
print(f"{code:<6} Error: {response.status_code}")
Query All Observatories¶
To get a list of all observatories, call the API with an empty JSON object.
# Get all observatories
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={}
)
if response.ok:
all_obs = response.json()
print(f"Total observatories: {len(all_obs)}")
# Show first 5 entries
print("\nFirst 5 entries:")
for i, (code, data) in enumerate(list(all_obs.items())[:5]):
print(f" {code}: {data.get('name', 'Unknown')}")
else:
print(f"Error: {response.status_code}")
Working with Pandas¶
Convert the observatory data to a pandas DataFrame for easier analysis.
# Get all observatories and convert to DataFrame
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={}
)
if response.ok:
all_obs = response.json()
# Convert to DataFrame
df = pd.DataFrame.from_dict(all_obs, orient='index')
# df.index.name = 'obscode'
# df = df.reset_index()
print(f"DataFrame shape: {df.shape}")
print(f"\nColumns: {list(df.columns)}")
print("\nSample rows & columns ... :")
print(df[['obscode', 'name', 'longitude', 'observations_type']].head(10))
else:
print(f"Error: {response.status_code}")
Observatory Types¶
Observatories are classified by their observation type.
# Count observatories by type
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={}
)
if response.ok:
all_obs = response.json()
# Count by type
type_counts = {}
for code, data in all_obs.items():
obs_type = data.get('observations_type', 'unknown')
type_counts[obs_type] = type_counts.get(obs_type, 0) + 1
print("Observatories by type:")
print("-" * 30)
for obs_type, count in sorted(type_counts.items(), key=lambda x: -x[1]):
print(f" {obs_type:<15}: {count:>5}")
else:
print(f"Error: {response.status_code}")
Space-Based Observatories¶
Let's find all satellite/space-based observatories.
# Find space-based observatories
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={}
)
if response.ok:
all_obs = response.json()
# Filter for satellite observatories
space_obs = [
(code, data) for code, data in all_obs.items()
if data.get('observations_type') == 'satellite'
]
print(f"Found {len(space_obs)} space-based observatories:")
print("-" * 50)
for code, data in sorted(space_obs, key=lambda x: x[0])[:15]:
name = data.get('name', 'Unknown')[:40]
print(f" {code}: {name}")
if len(space_obs) > 15:
print(f" ... and {len(space_obs) - 15} more")
else:
print(f"Error: {response.status_code}")
Understanding Parallax Constants¶
The rhocosphi and rhosinphi values are parallax constants used for astrometric reduction. They encode the observatory's position relative to Earth's center.
ρ cos(φ')- horizontal componentρ sin(φ')- vertical component
Where ρ is the geocentric distance in Earth radii and φ' is the geocentric latitude.
import math
# Get parallax data for some observatories
codes = ["675", "568", "G96"] # Palomar, Mauna Kea, Mt. Lemmon
print(f"{'Code':<6} {'Name':<25} {'ρcos(φ\')':>10} {'ρsin(φ\')':>10} {'Lat (approx)':>12}")
print("-" * 70)
for code in codes:
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={"obscode": code}
)
if response.ok:
data = response.json()
name = data.get('name', 'Unknown')[:23]
rhocos = float(data.get('rhocosphi', 0))
rhosin = float(data.get('rhosinphi', 0))
# Approximate geocentric latitude
if rhocos != 0:
lat_rad = math.atan2(rhosin, rhocos)
lat_deg = math.degrees(lat_rad)
else:
lat_deg = 90.0 if rhosin > 0 else -90.0
print(f"{code:<6} {name:<25} {rhocos:>10.6f} {rhosin:>10.6f} {lat_deg:>10.2f}°")
else:
print(f"{code:<6} Error")
Helper Functions¶
Here are convenient helper functions for working with observatory data.
def get_observatory(obscode):
"""
Get information about a specific observatory.
Parameters
----------
obscode : str
Three-character observatory code
Returns
-------
dict or None
Observatory data, or None if not found
"""
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={"obscode": obscode}
)
if response.ok:
return response.json()
return None
def get_all_observatories():
"""
Get information about all observatories as a DataFrame.
Returns
-------
pandas.DataFrame
DataFrame with all observatory information
"""
response = requests.get(
"https://data.minorplanetcenter.net/api/obscodes",
json={}
)
if not response.ok:
raise Exception(f"API error: {response.status_code}")
return pd.DataFrame.from_dict(response.json(), orient='index')
def search_observatories(name_pattern):
"""
Search for observatories by name (case-insensitive).
Parameters
----------
name_pattern : str
Substring to search for in observatory names
Returns
-------
pandas.DataFrame
Matching observatories
"""
df = get_all_observatories()
mask = df['name'].str.lower().str.contains(name_pattern.lower(), na=False)
return df[mask]
# Example usages
print(f"{get_observatory('F51')=}\n") # Get a dictionary containing information regarding observatory F51
print(f"{get_all_observatories().head(2)=}\n") # Get a dataframe containing all observatory information, then print the first 2
print(f"{search_observatories("Kea")=}") # Get a dataframe containing information on all observatories with 'Kea' in their names ...
Summary¶
The MPC Observatory Codes API provides access to information about observatories registered with the MPC.
Key points:
- Endpoint:
https://data.minorplanetcenter.net/api/obscodes - Single observatory:
{"obscode": "CODE"} - All observatories:
{} - Key fields:
obscode,name,longitude,rhocosphi,rhosinphi,observations_type - Observatory types: optical, satellite, radar, roving, occultation
For questions or feedback, contact the MPC via the Jira Helpdesk.