API reference
The read-model REST API returns recent crossmatches for objects that had an alert in a time window, grouped by object, at a caller-selected detail level. Responses are JSON.
Endpoint
GET /api/recent-crossmatches
Results are keyset (cursor) paged, newest first. Follow the top-level
next_cursor to page through the whole window; it is
null when the window is exhausted.
Query parameters
| Parameter | Values | Description |
|---|---|---|
start |
ISO-8601 timestamp (UTC) | Window start. Defaults to end minus 12 hours. |
end |
ISO-8601 timestamp (UTC) | Window end. Defaults to now. |
time_field |
ingest_time (default), event_time |
Which alert timestamp the window filters on: arrival time or observation time. |
detail |
ids, position, matches (default), full |
Cumulative detail level per object (see below). |
page_size |
positive integer | Objects per page, clamped down to the server maximum. |
cursor |
opaque token | A next_cursor from a prior page. It pins start, end, time_field, and detail; supplying any of those with a conflicting value is a 400. |
Detail levels
Detail levels are cumulative, each adding to the one before it:
ids— thediaObjectIdonly.position— adds the object'sra/dec.matches— adds a summary per match (catalog, source id, separation).full— adds the complete published payload for each match.
Response envelope
Every successful response wraps the objects with the resolved query metadata:
{
"window": {"start": "...", "end": "..."},
"time_field": "ingest_time",
"detail": "matches",
"page_size": 1000,
"count": 2,
"next_cursor": null,
"objects": [ ... ]
}
count is the number of objects on this page (not a whole-set
total). objects contains one entry per matched
diaObjectId (objects with no match are omitted).
Example request
curl "https://example.org/api/recent-crossmatches?detail=matches&page_size=2"
Success (200)
{
"window": {"start": "2026-08-10T00:00:00+00:00", "end": "2026-08-10T12:00:00+00:00"},
"time_field": "ingest_time",
"detail": "matches",
"page_size": 2,
"count": 1,
"next_cursor": "eyJ0MCI6IC4uLn0=",
"objects": [
{
"diaObjectId": 1234567890123456789,
"ra": 150.113,
"dec": 2.205,
"matches": [
{
"catalog_name": "gaia_dr3",
"catalog_source_id": "987654321098765432",
"separation_arcsec": 0.42
}
]
}
]
}
Error — invalid parameter (400)
An unparseable timestamp, unknown detail/time_field, non-positive page_size, malformed or conflicting cursor, or an out-of-range window returns a 400 with a JSON error body:
{
"error": "detail must be one of ('ids', 'position', 'matches', 'full'), got 'everything'"
}
Error — wrong method (405)
Only GET is supported. Any other method returns a 405:
{
"error": "method not allowed"
}