Skip to content

Public Dataset API

The Public Dataset API has two data paths:

  • Query returns a bounded JSON result: up to 10,000 rows a page with a key, paged to the end of the table; up to 100 rows a page without one at POST /api/public/tables/{table_id}/query. Use it for application reads and analytical questions.
  • Current returns the complete current Parquet snapshot. Use it for model training, bulk analysis, and scheduled local refreshes.

For a copy-paste walk through the whole surface — catalog search, dataset, schema, anonymous preview, query, Parquet — see For agents.

Both take a personal mr_use_… key, created under Settings → Access. The key reads any public dataset and your own workspace’s tables; the first request over a public dataset connects it to your workspace, with no step of your own.

mr_use_… is distinct from the legacy SDK/hosted-table mr_live_… subscription key and the mr_cli_… device credential; neither legacy key type is accepted by the Public Dataset API.

GET /api/v2/public/datasets?q=weather&limit=20

Catalog metadata is public. It returns dataset identity, publisher, licence, tables, public schema metadata, and canonical URLs. It does not reveal which workspaces use a dataset.

POST /api/v2/public/tables/{table_id}/query
x-api-key: mr_use_…
content-type: application/json
{
"columns": ["city", "date", "temperature"],
"filters": [
{ "column": "date", "operator": "gte", "value": "2026-08-01" }
],
"order_by": [{ "column": "temperature", "direction": "desc" }],
"limit": 100
}

Successful responses are JSON:

{
"schema_version": "mostlyright-public-table-query.v1",
"query_id": "qry_…",
"table": {
"id": "…",
"version_id": "…",
"content_digest": "sha256:…",
"published_at": "2026-08-23T10:00:00Z"
},
"columns": [{ "name": "temperature", "type": "float64" }],
"rows": [{ "temperature": 31.2 }],
"execution": {
"returned_rows": 1,
"scanned_bytes": 184320,
"elapsed_ms": 42,
"truncated": false
}
}

The request is a closed query grammar. It is not SQL. Unknown columns, unsupported operators, and invalid values are rejected before a table is scanned.

Every page answers with next_cursor. Send it back as cursor with the same columns, filters and order_by to get the next page; it is null on the last page. The cursor carries the window and the immutable version the walk started on, so you never mix two versions of a table.

GET /api/v2/public/tables/{table_id}/current
x-api-key: mr_use_…

The response body is application/vnd.apache.parquet. It carries a strong ETag, Content-Digest, Content-Length, and X-Request-Id. Send If-None-Match to refresh efficiently. See Use a public dataset for a DuckDB example.

All JSON errors contain schema_version, error, and request_id.

Status Meaning
401 Missing, invalid, revoked, or wrong key type.
404 The table is unavailable to this workspace, no longer public, or unknown. These cases are intentionally indistinguishable.
413 The requested artifact or result is too large. Refine the query or use Current for bulk data.
429 Rate limit reached. Respect Retry-After.
503, 504 Temporary service condition. Retry with backoff.

Query results have row, byte, and time limits: with a key, 10,000 rows and 8 MiB a page, 60 queries a minute and 5,000 a day; without one, 100 rows and 64 KiB a page, 30 a minute and 600 a day per address; 15 seconds of execution either way. The response tells you when a result was truncated. Use Current and local DuckDB when one request should return everything.

The machine-readable OpenAPI document is the source for REST request and response schemas. This API remains the application and script path and uses a workspace mr_use_ key. The legacy SDK and hosted-table API continue to use mr_live_… separately. MCP is an OAuth connection that delegates to the same bounded query services; it never accepts a pasted API key. See Connect an AI tool.