NUFORC APInuforc.org ↗
Access UFO sighting reports from the NUFORC database. Browse by month, search by year, and retrieve full witness descriptions, shapes, locations, and images.
What is the NUFORC API?
The NUFORC API provides structured access to the National UFO Reporting Center database through 4 endpoints, covering report summaries, full witness accounts, and monthly indexes. The get_report endpoint returns 10 discrete fields per sighting including description, shape, duration, location, and attached images. The search_reports endpoint lets you query by year alone or narrow to a specific month without needing a pre-fetched month ID.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/b54cbf1c-e649-4ebc-a83a-358f0ca15102/list_months' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace nuforc-org-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: NUFORC UFO Sighting Reports — browse months, list reports, get details."""
from parse_apis.nuforc_ufo_sighting_reports_api import Nuforc, ReportNotFound
client = Nuforc()
# List the most recent months available in the databank
for month in client.months.list(limit=5):
print(month.id, month.name)
# Drill into the first month's reports via the sub-resource
month = client.months.list(limit=1).first()
for report_summary in month.reports.list(limit=3):
print(report_summary.city, report_summary.state, report_summary.shape)
# Get full details from a report summary
detail = report_summary.details()
print(detail.location, detail.duration, detail.description[:80])
# Search by year and month
result = client.yearsearches.search(year=2024, month=6)
print(result.year, result.month_id)
# Handle a report that doesn't exist
try:
bad_detail = client.months.list(limit=1).first().reports.list(limit=1).first().details()
print(bad_detail.shape)
except ReportNotFound as exc:
print(f"Report not found: {exc}")
print("exercised: months.list / month.reports.list / report_summary.details / yearsearches.search")List all available months in the NUFORC databank. Each month has an ID (e.g., 'e202401') used as input for list_reports and search_reports endpoints. Returns months ordered from newest to oldest.
No input parameters required.
{
"type": "object",
"fields": {
"months": "array of month objects with id, name, and url"
},
"sample": {
"data": {
"months": [
{
"id": "e202606",
"url": "https://nuforc.org/subndx/?id=e202606",
"name": "2026/06"
},
{
"id": "e202605",
"url": "https://nuforc.org/subndx/?id=e202605",
"name": "2026/05"
}
]
},
"status": "success"
}
}About the NUFORC API
Browsing and Searching Reports
The list_months endpoint returns the full index of available months in the NUFORC databank, each with an id field (e.g., e202401), a human-readable name (e.g., 2024/01), and a url. Those month IDs are the primary key passed to list_reports, which returns report summaries for that month — including city, state, occurred, and a short summary text for each sighting.
The search_reports endpoint provides an alternative entry point: supply only a year integer and it returns the available_months array for that year. Add an optional month integer (1–12) and it behaves like list_reports, returning reports and a month_id for the matched period.
Detailed Report Data
The get_report endpoint accepts a numeric report_id from any listing result and returns the full record. Fields include occurred, reported, posted, location, shape, color, duration, description (the full witness narrative), and an images array of URLs when photos are attached. Not all fields are populated on every report — color, images, and explanation may be empty depending on what the witness submitted.
Coverage and Data Shape
Reports span multiple decades of NUFORC submissions. Month identifiers follow the pattern eYYYYMM, so January 2024 is e202401. The list_months response is ordered newest to oldest, which makes it straightforward to paginate backward through historical data. Report IDs are numeric strings; passing one to get_report returns data for that single incident with no pagination required.
The NUFORC API is a managed, monitored endpoint for nuforc.org — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when nuforc.org changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official nuforc.org API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Map UFO sightings by
cityandstatefields to visualize geographic clustering over time - Analyze
shapeanddurationfields across thousands of reports to identify statistical patterns - Build a sighting archive browser that lets users navigate by year and month using
search_reports - Extract and index
descriptiontext fromget_reportfor NLP or keyword analysis on witness language - Filter sightings with attached
imagesto build a photo gallery of documented incidents - Track monthly report volume over time using the
list_monthsindex andlist_reportscounts - Research sighting frequency by state for a given year using the
search_reportsyear+month combination
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does NUFORC provide an official developer API?+
What does `get_report` return versus `list_reports`?+
list_reports returns summary-level fields for all reports in a given month: id, occurred, city, state, and a brief summary. get_report fetches a single report by its numeric ID and returns the full record, including the witness description, shape, color, duration, images, reported, and posted dates. You need a report ID from a listing call to use get_report.Are reports from countries outside the United States included?+
location field on individual reports can reflect international locations. However, the state field on summary records is oriented toward US state codes, so international reports may have an empty or non-standard state value.Can I filter reports by shape, city, or witness-reported color?+
list_reports or search_reports; filtering by fields like shape, city, or color is not available as a query parameter. You can fork this API on Parse and revise it to add a filtered-search endpoint using those fields.Is there a way to retrieve the most recent reports without knowing the current month ID?+
list_months returns months ordered newest to oldest with no required parameters, so the first item in the response is always the most recent available month. Pass its id to list_reports or search_reports to get the latest sightings.