# SCiMMA Rubin Crossmatch Service API

Read-only JSON queries over the Rubin alert objects this service has ingested and their positional crossmatches. Service version 0.16.2; contract version 1.0.0. Every configured fact on this page is read from the live configuration of the running service.

Machine-readable: [OpenAPI 3.1 document](https://crossmatch.scimma.org/openapi.json), [llms.txt](https://crossmatch.scimma.org/llms.txt). For people: [HTML reference](https://crossmatch.scimma.org/api-docs).

## Connect from a chat assistant

Ask Claude.ai or ChatGPT about Rubin transients by TNS name, diaObjectId, or sky position and get this service's answer in the chat, without writing code. The assistant calls three read-only tools on this service's MCP endpoint, which answer from the same lookups as the API. A lookup takes up to 100 identifiers and a position search at most a 60 arcsec radius; an answer summarizes at most 20 objects, and a larger result comes back as the first part plus a ready-to-run API request for the full set.

- [Connector URL](https://crossmatch.scimma.org/mcp): https://crossmatch.scimma.org/mcp (MCP over HTTP POST, no authentication). Tools: `lookup_rubin_transients`, `search_rubin_transients_near_position`, `describe_crossmatch_service`.
- Custom connectors need a paid plan: Claude.ai Pro, Max, Team or Enterprise, or ChatGPT Plus, Pro, Business, Enterprise or Education (on the web).
- Claude.ai: In Settings, under Connectors, choose Add custom connector. Paste the connector URL, give it a name, and leave authentication empty; none is needed. Start a new conversation; the connector and its tools are available there.
- ChatGPT: In Settings, under Security and login (or Apps & Connectors), turn on Developer mode. Add a new app or connector with the connector URL and No Authentication. Start a new conversation in Developer mode and select the connector so its tools are available.
- In a ChatGPT workspace, an admin must first allow Developer mode and custom MCP connectors. Menu labels in both apps change from time to time; look for Connectors or Developer mode in Settings.

## Conventions

- Rubin object positions (ra, dec, and searched positions) are ICRS right ascension and declination in degrees; radii and separations are in arcsec. A coincident source position is the catalog's own, in degrees, read from its coordinate columns (gaia_dr3: ra, dec; des_y6_gold: RA, DEC; delve_dr3_gold: RA, DEC; skymapper_dr4: raj2000, dej2000), in the frame and epoch the catalog publishes: the crossmatch compares positions as stored, with no proper motion applied and no epoch propagation. gaia_dr3 positions are at the reference epoch in the ref_epoch payload column (J2016.0 for Gaia DR3). skymapper_dr4 coordinate columns carry a J2000 suffix (raj2000, dej2000) and are published under those names; see the SkyMapper DR4 documentation for their epoch.
- For each object and each catalog, the crossmatch keeps only the nearest catalog source within the crossmatch radius, so an object has at most one coincident source per catalog; other sources inside the radius are not reported. A coincident source is not a host association.
- A coincident source is a catalog source within the crossmatch radius of the object position; it is not a host association. The host galaxy of an offset supernova is generally not a coincident source, so the absence of a coincident source is not evidence of a hostless transient.
- "Not in this service" (status not_in_service, or no_rubin_object for a position) is not evidence that the object failed a reliability cut or does not exist in Rubin: reliability filtering happens before an alert is stored (at the broker, or at ingest for the cut this service enforces; see reliability_cuts), and the service holds only alerts its brokers delivered.
- A cursor pins the object set of a paged walk, not the objects' state: an object's status and coincident sources can advance between pages as crossmatching proceeds. as_of bounds ingest time, it is not a snapshot: ingest time is set before an ingest commits, so an object whose ingest commits during the walk can still appear on a later page if its ingest time is at or before as_of.
- Every successful response carries a `provenance` block: `service_version`, `contract_version`, `crossmatch_radius_arcsec`, `catalogs` (name and release), and `reliability_cuts` (per broker). Together they are the methods sentence for a paper.
- `diaObjectId` is a 64-bit integer; read `diaObjectId_str` in JavaScript, which loses precision above 2^53.

## Crossmatch configuration

- Crossmatch radius: 1.0 arcsec
- TNS search radius: default 1.0 arcsec, at most 60.0 arcsec
- Provenance recorded per object from service release 0.15.0
- Reliability cuts (minimum LSST reliability per broker; a broker-enforced value is declared by the maintainer, not observed by this service):
  - `antares`: 0.6; enforced by `broker`; status `declared`; as of 2026-10-05
  - `lasair`: 0.6; enforced by `broker`; status `declared`; as of 2026-10-05
  - `pittgoogle`: 0.6; enforced by `service`; status `service_setting`

## Catalogs

### `gaia_dr3` (Gaia DR3)

- `catalog_source_id` (column `source_id`): The Gaia DR3 source_id: the unique identifier of the Gaia source, a 64-bit integer served as a decimal string. Identifiers are unique only within one catalog_name.
- Coverage map: Searched means the position was inside the catalog footprint at the resolution of its HATS coverage map (HEALPix order 8, pixels about 13.7 arcmin across). Objects in footprint holes or near edges smaller than that may be recorded as searched even though the catalog has no data there.
- Filterable fields:
  - `parallax` (mas): gaia_dr3 catalog column parallax, as stored with the match. Parameters: `gaia_dr3.parallax_min`, `gaia_dr3.parallax_max`
  - `parallax_error` (mas): gaia_dr3 catalog column parallax_error, as stored with the match. Parameters: `gaia_dr3.parallax_error_min`, `gaia_dr3.parallax_error_max`
  - `pmra` (mas/yr): gaia_dr3 catalog column pmra, as stored with the match. Parameters: `gaia_dr3.pmra_min`, `gaia_dr3.pmra_max`
  - `pmdec` (mas/yr): gaia_dr3 catalog column pmdec, as stored with the match. Parameters: `gaia_dr3.pmdec_min`, `gaia_dr3.pmdec_max`
  - `ruwe` (dimensionless): gaia_dr3 catalog column ruwe, as stored with the match. Parameters: `gaia_dr3.ruwe_min`, `gaia_dr3.ruwe_max`
  - `classprob_dsc_combmod_star` (probability): gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match. Parameters: `gaia_dr3.classprob_dsc_combmod_star_min`, `gaia_dr3.classprob_dsc_combmod_star_max`
  - `classprob_dsc_combmod_galaxy` (probability): gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match. Parameters: `gaia_dr3.classprob_dsc_combmod_galaxy_min`, `gaia_dr3.classprob_dsc_combmod_galaxy_max`
  - `classprob_dsc_combmod_quasar` (probability): gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match. Parameters: `gaia_dr3.classprob_dsc_combmod_quasar_min`, `gaia_dr3.classprob_dsc_combmod_quasar_max`
  - `parallax_over_error` (dimensionless): gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0). Parameters: `gaia_dr3.parallax_over_error_min`, `gaia_dr3.parallax_over_error_max`

### `des_y6_gold` (DES Y6 Gold)

- `catalog_source_id` (column `COADD_OBJECT_ID`): The DES Y6 Gold COADD_OBJECT_ID: the unique identifier of the coadd object in the DES Y6 Gold catalog, served as a decimal string. Identifiers are unique only within one catalog_name.
- Coverage map: Searched means the position was inside the catalog footprint at the resolution of its HATS coverage map (HEALPix order 6, pixels about 55 arcmin across). Objects in footprint holes or near edges smaller than that may be recorded as searched even though the catalog has no data there.
- Filterable fields:
  - `dnf_z` (dimensionless): des_y6_gold catalog column DNF_Z, as stored with the match. Parameters: `des_y6_gold.dnf_z_min`, `des_y6_gold.dnf_z_max`
  - `dnf_zsigma` (dimensionless): des_y6_gold catalog column DNF_ZSIGMA, as stored with the match. Parameters: `des_y6_gold.dnf_zsigma_min`, `des_y6_gold.dnf_zsigma_max`
  - `ext_mash` (class code (0-4)): des_y6_gold catalog column EXT_MASH, as stored with the match. Parameters: `des_y6_gold.ext_mash_min`, `des_y6_gold.ext_mash_max`

### `delve_dr3_gold` (DELVE DR3 Gold)

- `catalog_source_id` (column `COADD_OBJECT_ID`): The DELVE DR3 Gold COADD_OBJECT_ID: the unique identifier of the coadd object in the DELVE DR3 Gold catalog, served as a decimal string. Do not assume it names the same source as an equal DES COADD_OBJECT_ID. Identifiers are unique only within one catalog_name.
- Coverage map: Searched means the position was inside the catalog footprint at the resolution of its HATS coverage map (HEALPix order 10, pixels about 3.4 arcmin across). Objects in footprint holes or near edges smaller than that may be recorded as searched even though the catalog has no data there.
- Filterable fields:
  - `dnf_z` (dimensionless): delve_dr3_gold catalog column DNF_Z, as stored with the match. Parameters: `delve_dr3_gold.dnf_z_min`, `delve_dr3_gold.dnf_z_max`
  - `dnf_zsigma` (dimensionless): delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match. Parameters: `delve_dr3_gold.dnf_zsigma_min`, `delve_dr3_gold.dnf_zsigma_max`
  - `ext_mash` (class code (0-4)): delve_dr3_gold catalog column EXT_MASH, as stored with the match. Parameters: `delve_dr3_gold.ext_mash_min`, `delve_dr3_gold.ext_mash_max`

### `skymapper_dr4` (SkyMapper DR4)

- `catalog_source_id` (column `object_id`): The SkyMapper DR4 object_id: the unique identifier of the object in the SkyMapper DR4 master table, served as a decimal string. Identifiers are unique only within one catalog_name.
- Coverage map: Searched means the position was inside the catalog footprint at the resolution of its HATS coverage map (HEALPix order 8, pixels about 13.7 arcmin across). Objects in footprint holes or near edges smaller than that may be recorded as searched even though the catalog has no data there.
- Filterable fields: none

## Limits

- Request budget: 5.0 s (over it: 400 `query_too_expensive`)
- IDs per request: 1000
- Positions and TNS names per request: 200
- Search radius: at most 60.0 arcsec
- Objects listed per position: 100; per request: 2000
- recent-crossmatches: default window 12 h, at most 168 h; page size default 1000, at most 10000

## Detail levels

Cumulative; the default is `matches`.

- `ids`: diaObjectId, status, and the crossmatch block (per-catalog search outcomes and recorded provenance).
- `position`: ids plus the object position (ra, dec, degrees), reliability, ingest_time, event_time, and delivering brokers.
- `matches`: position plus the coincident sources: catalog_name, catalog_source_id, and separation_arcsec.
- `full`: matches plus each source as published on Hopskotch: the catalog payload columns (lowercased keys) and the TNS enrichment.

## Response modes

- `objects`: The listing of results and objects (default).
- `count`: Counts by input status, object status, and qualifies for the same inputs and filters, without objects and uncapped by the listing limits.

## Generic filters

Catalog property filters are listed per catalog above.

- `catalog`, match filter: Match filter: only coincident sources from this catalog count. It names a catalog, so it cannot be combined with a filter on another catalog.
- `separation_arcsec_max` (arcsec), match filter: Match filter: only coincident sources at most this far from the object count, arcsec (inclusive).
- `reliability_min` (probability), object filter: Object filter: inclusive minimum of the object's stored LSST reliability; an object with none does not qualify.
- `reliability_max` (probability), object filter: Object filter: inclusive maximum of the object's stored LSST reliability; an object with none does not qualify.

## Operations

### `get_openapi`

`GET /openapi.json`

This OpenAPI document.

The OpenAPI 3.1 document for every operation, built per request from the live configuration, so its radius, catalogs, reliability cuts, limits, and version describe the running service. Numeric fields name their unit in x-unit. Start here, or at /llms.txt.

Responses:

- `200`: The OpenAPI 3.1 document.
- `405`: Method not allowed.

### `get_object`

`GET /api/objects/{diaObjectId}`

Look up one Rubin object by diaObjectId.

What the service knows about one object: its status, per-catalog search outcomes, provenance, and coincident sources. The response has the lookup_objects shape with one result. "Not in this service" (status not_in_service, or no_rubin_object for a position) is not evidence that the object failed a reliability cut or does not exist in Rubin: reliability filtering happens before an alert is stored (at the broker, or at ingest for the cut this service enforces; see reliability_cuts), and the service holds only alerts its brokers delivered.

Parameters:

- `diaObjectId` (path, required): The diaObjectId, as a decimal string.
- `detail` (query, optional): Cumulative detail level (default matches).
- `catalog` (query, optional): Match filter: only coincident sources from this catalog count. It names a catalog, so it cannot be combined with a filter on another catalog.
- `separation_arcsec_max` (query, optional, arcsec): Match filter: only coincident sources at most this far from the object count, arcsec (inclusive).
- `reliability_min` (query, optional, probability): Object filter: inclusive minimum of the object's stored LSST reliability; an object with none does not qualify.
- `reliability_max` (query, optional, probability): Object filter: inclusive maximum of the object's stored LSST reliability; an object with none does not qualify.
- `gaia_dr3.parallax_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `response` (query, optional): objects (default): the listing. count: counts by input status, object status, and qualifies for the same inputs and filters, without objects (CountResponse).

Responses:

- `200`: The object, or counts for response=count.
- `400`: Invalid diaObjectId, detail, filter, or response; filters_span_catalogs; or query_too_expensive.
- `405`: Method not allowed.
- `503`: Service unavailable; see Retry-After.

### `lookup_objects`

`POST /api/lookup`

Look up a list of tagged inputs in one request.

Read-only and idempotent. Every input produces exactly one result, in input order, echoing the input as sent and its normalized form. A malformed input is reported as invalid_input in its own result and does not fail the others; request-level problems are a 400 naming the parameter. "Not in this service" (status not_in_service, or no_rubin_object for a position) is not evidence that the object failed a reliability cut or does not exist in Rubin: reliability filtering happens before an alert is stored (at the broker, or at ingest for the cut this service enforces; see reliability_cuts), and the service holds only alerts its brokers delivered.

Request body: `LookupRequest` (JSON; see the OpenAPI document).

Responses:

- `200`: One result per input, or counts for response=count.
- `400`: Invalid request: body, Content-Type, inputs, detail, a filter, response, or an unknown field; filters_span_catalogs; or query_too_expensive.
- `405`: Method not allowed.
- `503`: Service unavailable; see Retry-After.

### `cone_search`

`GET /api/cone`

Search one position for every Rubin object within a radius.

Every Rubin object the service has seen within the radius of the position, crossmatched or not, across the whole archive, each with its own status. A position with no object reports no_rubin_object. Objects whose position could not be indexed at ingest (null HEALPix index) are not reachable by position search; look them up by diaObjectId. Paged in (ingest_time, diaObjectId) order: follow next_cursor until null. The first page pins the object set with as_of. A cursor pins the object set of a paged walk, not the objects' state: an object's status and coincident sources can advance between pages as crossmatching proceeds. as_of bounds ingest time, it is not a snapshot: ingest time is set before an ingest commits, so an object whose ingest commits during the walk can still appear on a later page if its ingest time is at or before as_of. A coincident source is a catalog source within the crossmatch radius of the object position; it is not a host association. The host galaxy of an offset supernova is generally not a coincident source, so the absence of a coincident source is not evidence of a hostless transient.

Parameters:

- `ra` (query, optional, deg): Center RA, degrees (ICRS). Required without cursor.
- `dec` (query, optional, deg): Center Dec, degrees (ICRS). Required without cursor.
- `radius_arcsec` (query, optional, arcsec): Radius, arcsec. Required without cursor. At most 60 arcsec.
- `detail` (query, optional): Cumulative detail level (default matches).
- `page_size` (query, optional, count): Objects per page (default 100); clamped to 2000.
- `cursor` (query, optional): Opaque next_cursor from a prior page; pins ra, dec, radius_arcsec, detail, and as_of. Filters are not pinned: pass them on every page. Not allowed with response=count. A cursor pins the object set of a paged walk, not the objects' state: an object's status and coincident sources can advance between pages as crossmatching proceeds. as_of bounds ingest time, it is not a snapshot: ingest time is set before an ingest commits, so an object whose ingest commits during the walk can still appear on a later page if its ingest time is at or before as_of.
- `catalog` (query, optional): Match filter: only coincident sources from this catalog count. It names a catalog, so it cannot be combined with a filter on another catalog.
- `separation_arcsec_max` (query, optional, arcsec): Match filter: only coincident sources at most this far from the object count, arcsec (inclusive).
- `reliability_min` (query, optional, probability): Object filter: inclusive minimum of the object's stored LSST reliability; an object with none does not qualify.
- `reliability_max` (query, optional, probability): Object filter: inclusive maximum of the object's stored LSST reliability; an object with none does not qualify.
- `gaia_dr3.parallax_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `response` (query, optional): objects (default): the listing. count: counts by input status, object status, and qualifies for the same inputs and filters, without objects (CountResponse).

Responses:

- `200`: One page, or counts for response=count.
- `400`: Invalid parameter, filter, or cursor (param names it), filters_span_catalogs, or query_too_expensive.
- `405`: Method not allowed.
- `503`: Service unavailable; see Retry-After.

### `resolve_tns`

`GET /api/tns/{name}`

Look up a TNS name as a position search around it.

Resolves the name through the TNS snapshot and returns every Rubin object within the radius of the TNS position, echoing the TNS record and snapshot epoch. The response has the lookup_objects shape with one result. Not paged: at most 100 objects, with truncated and total when capped. When the snapshot is stale or absent the result is resolver_unavailable (still a 200). A coincident source is not a host association, and the absence of one is not evidence of a hostless transient.

Parameters:

- `name` (path, required): The TNS name, e.g. 2026abc or SN 2026abc.
- `radius_arcsec` (query, optional, arcsec): Radius around the TNS position, arcsec (default 1); at most 60.
- `detail` (query, optional): Cumulative detail level (default matches).
- `catalog` (query, optional): Match filter: only coincident sources from this catalog count. It names a catalog, so it cannot be combined with a filter on another catalog.
- `separation_arcsec_max` (query, optional, arcsec): Match filter: only coincident sources at most this far from the object count, arcsec (inclusive).
- `reliability_min` (query, optional, probability): Object filter: inclusive minimum of the object's stored LSST reliability; an object with none does not qualify.
- `reliability_max` (query, optional, probability): Object filter: inclusive maximum of the object's stored LSST reliability; an object with none does not qualify.
- `gaia_dr3.parallax_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_min` (query, optional, mas): Match filter: inclusive minimum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_error_max` (query, optional, mas): Match filter: inclusive maximum of gaia_dr3 catalog column parallax_error, as stored with the match; unit: mas. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmra_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmra, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_min` (query, optional, mas/yr): Match filter: inclusive minimum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.pmdec_max` (query, optional, mas/yr): Match filter: inclusive maximum of gaia_dr3 catalog column pmdec, as stored with the match; unit: mas/yr. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.ruwe_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 catalog column ruwe, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_star_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_star, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_galaxy_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_galaxy, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_min` (query, optional, probability): Match filter: inclusive minimum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.classprob_dsc_combmod_quasar_max` (query, optional, probability): Match filter: inclusive maximum of gaia_dr3 catalog column classprob_dsc_combmod_quasar, as stored with the match; unit: probability. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_min` (query, optional, dimensionless): Match filter: inclusive minimum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `gaia_dr3.parallax_over_error_max` (query, optional, dimensionless): Match filter: inclusive maximum of gaia_dr3 parallax / parallax_error, computed from the stored values (signed; unusable, so never qualifying, when either is missing or the denominator is 0); unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of des_y6_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `des_y6_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of des_y6_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_z_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_Z, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_min` (query, optional, dimensionless): Match filter: inclusive minimum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.dnf_zsigma_max` (query, optional, dimensionless): Match filter: inclusive maximum of delve_dr3_gold catalog column DNF_ZSIGMA, as stored with the match; unit: dimensionless. A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_min` (query, optional, class code (0-4)): Match filter: inclusive minimum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `delve_dr3_gold.ext_mash_max` (query, optional, class code (0-4)): Match filter: inclusive maximum of delve_dr3_gold catalog column EXT_MASH, as stored with the match; unit: class code (0-4). A null or non-numeric stored value never qualifies.
- `response` (query, optional): objects (default): the listing. count: counts by input status, object status, and qualifies for the same inputs and filters, without objects (CountResponse).

Responses:

- `200`: One result, or counts for response=count.
- `400`: Invalid name, radius_arcsec, detail, filter, or response; filters_span_catalogs; or query_too_expensive.
- `405`: Method not allowed.
- `503`: Service unavailable; see Retry-After.

### `service_status`

`GET /api/status`

Service availability, version, and TNS-resolution availability.

Always 200 for a GET: an unreachable or unresponsive database is reported as database: unavailable rather than as an error. tns_resolution reports whether TNS-name inputs can be resolved now (the TNS snapshot is current).

Responses:

- `200`: The service status.
- `405`: Method not allowed.

### `describe_service`

`GET /api/describe`

Catalogs, vocabulary, and per-request limits.

The catalogs in service (release, what catalog_source_id means, filterable fields with units, coverage-map resolution), the crossmatch and TNS radii, per-request maximums and budget, detail levels, response modes, generic filters, the broker reliability cut table, and the provenance recording release. Read from the live configuration; needs no database.

Responses:

- `200`: The description.
- `405`: Method not allowed.

### `recent_crossmatches`

`GET /api/recent-crossmatches`

Crossmatches for objects with alerts in a time window.

One keyset page of matched objects whose alert falls in the window, newest first. Matches-only: an object with no catalog match is not listed. Follow next_cursor until null; the walk is pinned by as_of. Does not filter or count: a filter-named parameter (<catalog>.<column>_min|_max, catalog, separation_arcsec_max, reliability_min|_max, or any name with a dot or ending _min/_max) or response is a 400 unsupported_parameter; other unknown parameters are ignored. Runs under the per-request budget of 5 s: a large page at detail=full can exceed it (400 query_too_expensive); use a smaller page_size.

Parameters:

- `start` (query, optional): Window start (inclusive), ISO-8601; naive means UTC. Default: end minus 12 hours. The window may span at most 168 hours.
- `end` (query, optional): Window end (exclusive), ISO-8601. Default: now.
- `time_field` (query, optional): Which alert timestamp the window filters on.
- `detail` (query, optional): Cumulative detail level (default matches).
- `page_size` (query, optional, count): Maximum objects on the page (default 1000); clamped to the operator maximum of 10000.
- `cursor` (query, optional): Opaque next_cursor from a prior page; pins start, end, time_field, and detail.

Responses:

- `200`: One page.
- `400`: invalid_parameter (a bad start, end, time_field, detail, page_size, or cursor, or a cursor conflict); unsupported_parameter (a filter or response parameter, which this operation does not support); or query_too_expensive. error repeats message, as in the original error-only body.
- `405`: Method not allowed.
- `503`: Service unavailable; see Retry-After.

## Codes

Codes are fixed snake_case values; branch on them, not on messages.

### Object status (`ObjectStatus`)

- `not_in_service`: The service has no record of this object. This is not evidence that the object failed a reliability cut or does not exist in Rubin: reliability filtering happens before alerts reach the service.
- `crossmatch_pending`: Ingested, not yet crossmatched.
- `coincident_sources`: Crossmatched; at least one catalog source lies within the crossmatch radius. A coincident source is not a host association.
- `no_coincident_source`: Crossmatched; no source within the crossmatch radius in any catalog that was actually searched. Not evidence of a hostless transient.
- `not_searched`: Crossmatched, but no catalog was actually searched (every catalog was skipped, outside its footprint, or not searched because of an invalid position).

### Input status (`InputStatus`)

- `no_rubin_object`: No Rubin object in this service lies within the radius.
- `objects_found`: One or more Rubin objects matched this input.
- `tns_name_not_found`: The TNS name is not in the current TNS snapshot (the snapshot epoch is reported).
- `resolver_unavailable`: TNS-name resolution is unavailable right now; other inputs are unaffected.
- `invalid_input`: This input is malformed; it is reported here and does not fail the other inputs.

### Per-catalog search outcome (`CatalogOutcome`)

- `searched`: The catalog was searched at this position: the position was inside the catalog footprint at the resolution of its HATS coverage map (see coverage_map in api/describe), so an object in a footprint hole or near an edge may be recorded as searched even though the catalog has no data there.
- `outside_footprint`: The position is outside the catalog footprint.
- `skipped_read_failure`: The catalog was skipped after a read failure.
- `not_searched_invalid_position`: Not searched because the object position is invalid.
- `not_recorded`: No search outcome is recorded for this object; the release that started recording is named.
- `not_in_service_at_crossmatch`: The catalog was added after this object was crossmatched.

### Qualifies reason (`QualifiesReason`)

- `meets_filters`: Qualifies: meets every filter in the request.
- `object_filters_not_met`: Does not qualify: the object fails an object filter (reliability); an object with no stored reliability never meets one.
- `no_source_meets_filters`: Does not qualify: the object has coincident sources, but no single current source satisfies every match filter. A null or non-numeric stored value never satisfies a filter.
- `no_object_meets_filters`: Does not qualify: Rubin objects lie within the radius, but none qualifies.
- `not_in_service`: The service has no record of this object. This is not evidence that the object failed a reliability cut or does not exist in Rubin: reliability filtering happens before alerts reach the service.
- `crossmatch_pending`: Ingested, not yet crossmatched.
- `no_coincident_source`: Crossmatched; no source within the crossmatch radius in any catalog that was actually searched. Not evidence of a hostless transient.
- `not_searched`: Crossmatched, but no catalog was actually searched (every catalog was skipped, outside its footprint, or not searched because of an invalid position).
- `no_rubin_object`: No Rubin object in this service lies within the radius.
- `tns_name_not_found`: The TNS name is not in the current TNS snapshot (the snapshot epoch is reported).
- `resolver_unavailable`: TNS-name resolution is unavailable right now; other inputs are unaffected.
- `invalid_input`: This input is malformed; it is reported here and does not fail the other inputs.

### Error code (`ErrorCode`)

- `invalid_parameter`: A request parameter is invalid; see param or params.
- `method_not_allowed`: The HTTP method is not supported on this path.
- `query_too_expensive`: The request exceeded its server-side cost bound. Narrow it; retrying the same request will not help.
- `service_unavailable`: The service or its database is unavailable. Retry after the Retry-After interval.
- `filters_span_catalogs`: The match filters name more than one catalog. Match filters apply within one catalog's source; params lists the conflicting parameters.
- `unsupported_parameter`: This operation does not support the named parameter (for example a filter or response on recent-crossmatches); the request was not run, so unfiltered results are never mistaken for filtered ones.

### Reliability cut enforced by (`CutEnforcedBy`)

- `service`: Enforced by this service.
- `broker`: Enforced by the broker before alerts reach this service.

### Reliability cut status (`CutStatus`)

- `service_setting`: The value is this service's own live setting.
- `declared`: The value is declared by the maintainer as of the stated date; the service does not observe it.
- `not_declared`: The maintainer has not declared a value.
