Issue Nº 23 — Sep 7, 2026
LAPIS answers a genomics query with a request ID and a GitHub link
Issue twenty-three covers LAPIS, the keyless read API behind covSPECTRUM's SARS-CoV-2 genomic data. This session queried it live. Every response, success or not, carries a data-version stamp, a request ID, and an invitation to file a GitHub issue. An unknown country name does not return an error. It returns a real count of zero.
What it covers
LAPIS serves aggregated counts, sequence details, and mutation queries over public SARS-CoV-2 genomic data, drawn from sources such as GenBank and Nextstrain. No key and no sign-up are needed.
GET /open/v2/sample/aggregated?country=Switzerland, queried live this session, returned 200 with a real case count. GET /open/v2/sample/details?country=Switzerland&limit=1 also returned 200, with one full GenBank record: a strain name, a collection date, a Nextclade lineage call, and a submitting lab. Both responses carried an access-control-allow-origin: * header. That matches the catalogue's stored cors: yes.
A count query grouped by a field works the same way: GET /open/v2/sample/aggregated?country=Iceland&fields=division, queried live, returned one row per division value with its own count.
Every response carries its own paper trail
Each response body, live and re-checked this session, carries an info block: a dataVersion stamp, a requestId, a requestInfo string naming the dataset and the host that answered, and a reportTo field that asks the caller to file a GitHub issue at GenSpectrum/LAPIS and to quote the request ID and requestInfo back in the report.
That GitHub issues page resolved live with a 200 this session. So did the docs page at /open/v2/docs/ and the covSPECTRUM frontend at cov-spectrum.org.
A query for a country name LAPIS does not recognize, tried live as country=Atlantis, still returns HTTP 200. The body reads {"data":[{"count":0}]}. There is no error field and no distinct not-found status. An unrecognized filter value and a real filter value that happens to match nothing look identical on the wire.
A genuinely bad request behaves differently. Passing an unsupported filter key, tried live as bogusField=xyz, returns an error body naming the bad key and listing every valid one LAPIS knows about for that endpoint. A plain HTTP request to the non-HTTPS host redirects with a 301, so the API only ever answers over HTTPS in practice.
The spec matches what the API returns
The published OpenAPI document at /open/v2/api-docs, fetched live this session, is version 3.1.0 and just under 700 KB. It documents both hero endpoints this catalogue entry lists, sample/aggregated and sample/details, alongside the query parameters this session exercised directly: country, fields, and limit.
LAPIS, by the numbers
- GET/sample/aggregated
- GET/sample/details