API and agentsAPI reference
Tables
Uploaded data as queryable tables.
37 operations on 21 paths.
/api/tables/{name}/geometry
GETInspect a dataset's geometry choices
Sign-in Session cookie or Bearer tokenMCP tool inspect_table_geometry
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. For file uploads and URL imports only. SQL-save, workflow, PostGIS, OSM, Overture and sketch datasets refuse with 409 geometry_not_supported and a sentence. Unknown or reclaimed dataset identity answers 404 not_found; a stale artifact revision answers 409 input_changed. Column names are identifiers, never SQL expressions or file paths. Reads current stored schema, record, choice, opaque revision and candidates using the same first-1,000-row recognition and full safety evidence as CSV upload. Does not apply a proposal, fetch a source or invent legacy provenance. Repeated inspections reuse candidates while the artifact is unchanged. Historical consumed names and generated outputs are not new source columns.
Parameters
namePathrequiredStored dataset SQL name.
string
Responses
200
Success.
application/json400401403404409422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
DELETE, GET, HEAD, OPTIONS, PUT
PUTSet or change a dataset's geometry
Sign-in Session cookie or Bearer tokenMCP tool set_table_geometry
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. For file uploads and URL imports only. SQL-save, workflow, PostGIS, OSM, Overture and sketch datasets refuse with 409 geometry_not_supported and a sentence. Unknown or reclaimed dataset identity answers 404 not_found; a stale artifact revision answers 409 input_changed. Column names are identifiers, never SQL expressions or file paths. Original values and rows remain. WKT/EWKT, GeoJSON geometry objects, WKB hex/EWKB, validated H3 boundaries and x/y pairs from numeric or text-typed columns are supported. Pair values are read tolerantly per row on preview, first set, change and replay. Declared CRS wins: an explicit differing EPSG refuses with conflicting_crs; mixed/unknown declarations refuse. H3 and GeoJSON have inherent WGS84 and take no projection. Undeclared WKT/WKB/pairs assume WGS84 unless EPSG is explicit. Transformation produces WGS84 longitude/latitude. Under WGS84, mixed out-of-range rows are unreadable; only when no decoded nonempty row fits degrees does projection_required block application. Missing inputs do not count as unreadable. All-bad/empty inputs otherwise retain a geometry identity with null class and extent. Builds and re-measures an artifact, then publishes record and saved choice together. Retained sources permit repeated changes with one managed output. A first projection change is allowed on assumed native/consumed geometry; a further change without source values refuses with geometry_choice_invalid and source_unavailable. Last-run time, projects, dataset identity, layer SQL/style, undo and redo remain intact. Dependent tiles become stale; captured readers finish on old artifacts. A competing writer in the same table or URL group answers 409 geometry_in_flight. Malformed/unknown fields and incompatible types answer 400 invalid_request; missing columns answer 400 column_unavailable. Unusable choices answer 422 geometry_choice_invalid with issues. Post-commit cleanup failure does not reverse success. A saved manual geometry choice on a URL import replays against fresh source columns before automatic conversion, survives restart, and commits with the artifact and geometryRecord. Missing selected columns fail atomically with 400 column_unavailable; bad rows remain null geometries and are counted. Each container member keeps its own choice and the group downloads once and publishes together. Clear removes the override: the next refresh resumes automatic recognition, records its fresh result and resets geometry mode to unmodified. An unusable saved choice refuses atomically with 422 geometry_choice_invalid, including projection_required or conflicting_crs issues. A changed generation refuses with 409 input_changed.
Parameters
namePathrequiredStored dataset SQL name.
string
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
Responses
200
Success.
application/json400401403404409413422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
DELETE, GET, HEAD, OPTIONS, PUT
DELETEClear a dataset's generated geometry
Sign-in Session cookie or Bearer tokenMCP tool clear_table_geometry
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. For file uploads and URL imports only. SQL-save, workflow, PostGIS, OSM, Overture and sketch datasets refuse with 409 geometry_not_supported and a sentence. Unknown or reclaimed dataset identity answers 404 not_found; a stale artifact revision answers 409 input_changed. Column names are identifiers, never SQL expressions or file paths. Removes the managed output and applied record, retaining originals, identity, row count and last-run time. Repeated clear is a no-op; later set remains available. A clear that removes native/consumed geometry refuses with 422 geometry_choice_invalid and source_unavailable. History and layer SQL/style stay intact; dependent tiles become stale. Requires expectedRevision in the query. Competing edits/refreshes in the same provenance unit answer 409 geometry_in_flight. Clear removes a URL override; its next refresh runs automatic recognition and mode becomes unmodified.
Parameters
namePathrequiredStored dataset SQL name.
string
expectedRevisionQueryrequiredOpaque revision returned by geometry inspection.
stringmin length
1
Responses
200
Success.
application/json400401403404409422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
DELETE, GET, HEAD, OPTIONS, PUT
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 400, 401, 403, 404, 405, 409, 422, 503, defaultAllow
DELETE, GET, HEAD, OPTIONS, PUTAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/tables/{name}/geometry/preview
POSTPreview an explicit geometry choice
Sign-in Session cookie or Bearer tokenMCP tool preview_table_geometry
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. For file uploads and URL imports only. SQL-save, workflow, PostGIS, OSM, Overture and sketch datasets refuse with 409 geometry_not_supported and a sentence. Unknown or reclaimed dataset identity answers 404 not_found; a stale artifact revision answers 409 input_changed. Column names are identifiers, never SQL expressions or file paths. Original values and rows remain. WKT/EWKT, GeoJSON geometry objects, WKB hex/EWKB, validated H3 boundaries and x/y pairs from numeric or text-typed columns are supported. Pair values are read tolerantly per row on preview, first set, change and replay. Declared CRS wins: an explicit differing EPSG refuses with conflicting_crs; mixed/unknown declarations refuse. H3 and GeoJSON have inherent WGS84 and take no projection. Undeclared WKT/WKB/pairs assume WGS84 unless EPSG is explicit. Transformation produces WGS84 longitude/latitude. Under WGS84, mixed out-of-range rows are unreadable; only when no decoded nonempty row fits degrees does projection_required block application. Missing inputs do not count as unreadable. All-bad/empty inputs otherwise retain a geometry identity with null class and extent. No artifact, metadata, history, tile or saved-choice writes and no URL fetch. Returns the first 50 rows with corresponding feature ids and row outcomes, including null geometries; indexes belong only to the returned revision. Counts, geometry class, degree compatibility and extent are sampled from those first 50 rows, without extrapolation. CRS declarations are still checked across the full source column. Apply validates and counts the full input independently and may refuse a choice that the sample accepted. Map geometries are simplified for preview; text and geometry-valued grid cells longer than 512 characters end in an ellipsis after a 512-character excerpt. Original stored values are unchanged. A syntactically valid unusable projection or unavailable H3 returns 200 with canApply false and issues; unsupported ownership changes refuse with 422 and source_unavailable. Invalid JSON/unknown fields/types answer 400 invalid_request; missing columns answer 400 column_unavailable. The complete uncompressed UTF-8 JSON answer, including metadata, grid rows and map features together, is limited to 33,554,432 bytes (32 MiB); each non-geometry column value after excerpts, including nested values, to 2,097,152 bytes (2 MiB). Equality is admitted. Native geometry WKT excerpts and evaluated native map geometry count only toward the result ceiling. Source text and JSON remain non-geometry. Exceeding either fixed bound refuses the whole preview with HTTP 422 query_result_too_large and no partial sample. Preview is optional before apply.
Parameters
namePathrequiredStored dataset SQL name.
string
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
Responses
200
Success.
application/json400401403404409413422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/geometry/projections
GETList geometry projections or resolve an EPSG code
Sign-in Session cookie or Bearer tokenMCP tool list_geometry_projections
The seven drawn projections in order: WGS 84, Web Mercator, ETRS89 / UTM 32N, ETRS89 / UTM 33N, ETRS89 / LAEA Europe, British National Grid, NAD83. The optional lookup accepts decimal digits with an EPSG: prefix, validates engine transformation support, and includes custom codes outside the shortlist. Custom entries return the bare EPSG code as name and null unit; curated names share recognition's label map. No query gives resolved null. Invalid syntax answers 400 invalid_request; unsupported codes answer 422 geometry_choice_invalid.
Parameters
epsgQueryNumeric EPSG code, optionally prefixed EPSG:.
string
Responses
200
Success.
application/json400401403422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 400, 401, 403, 405, 422, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/tables
GETList tables
Sign-in Session cookie or Bearer tokenMCP tool list_tables
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit.
Parameters
projectQueryNarrow to one project's members by project id: any project the caller reaches, its own or one shared with it, whoever owns what is filed there; "none" narrows to the caller's own items filed in no project at all (one still filed in a project the caller no longer reaches is not none). Omitted, everything the caller reaches answers. An unknown or unreached project is not found, never an empty list.
string
Responses
200
Success.
application/json401403404503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS, POST
Example
List your datasets
Needs a token. Lists world_cities, the dataset the upload made.
curl
curl -s http://localhost:3000/api/tables \ -H "Authorization: Bearer <YOUR_TOKEN>"JavaScript
const response = await fetch("http://localhost:3000/api/tables", { headers: { Authorization: "Bearer <YOUR_TOKEN>" },});console.log(JSON.stringify(await response.json(), null, 2));Answers 200 application/json
[ { "geometryRecord": { "columns": [ "longitude", "latitude" ], "format": "pair", "signal": "name", "rule": "exact-pair", "crs": { "stance": "assumed", "srid": null, "label": "WGS 84 assumed" }, "unreadableCount": 0 }, "geometryCandidates": [ { "columns": [ "longitude", "latitude" ], "format": "pair", "signal": "name", "rule": "exact-pair", "strength": "strong", "sample": { "rows": 48, "nonNull": 48, "readable": 48 }, "crs": { "stance": "assumed", "srid": null, "label": "WGS 84 assumed" }, "degreeCompatible": true, "reasons": [], "applied": true, "sourceRetained": true, "orientations": [ { "lon": "longitude", "lat": "latitude" } ] } ], "id": "7d4b2e91-3f6a-4c58-8e12-9a0b5c6d7e2f", "name": "world_cities", "sourceFilename": "world-cities.csv", "format": "csv", "file": "tables/7d4b2e91-3f6a-4c58-8e12-9a0b5c6d7e2f.parquet", "geometryColumn": "geometry", "geometryType": "POINT", "crsAssumed": true, "headerSuspect": false, "rowCount": 48, "createdAt": "2026-10-20T09:00:01.283Z", "source": "upload", "sourceParams": null, "importedAt": "2026-10-20T09:00:01.283Z", "owner": { "name": "Ana Diaz", "sqlName": "ana_diaz" }, "qualifiedName": "world_cities", "projectIds": [], "sizeBytes": 3839 }]POSTUpload a file as one or more tables
Sign-in Session cookie or Bearer tokenMCP tool upload_table
Created resources belong to the authenticated account. Submitted owner identities cannot assign or transfer ownership. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. multipart/form-data with exactly one file part, named file — a request with several file parts, or a file under another field name, is refused without importing anything. To upload a batch, repeat the request once per file. Accepts GeoParquet, GeoJSON, CSV, Shapefile (as .zip), GeoPackage, and KML/KMZ. A container holding several spatial layers creates one table per layer; the answer enumerates them. Reception and processing each get the Data processing time limit captured when receiving begins, with separate deadlines. Changing the setting during receipt changes neither budget. No body byte for 60 seconds, including before the first byte, answers 408 upload_stalled. Reception or processing expiry answers 408 data_processing_timeout, naming the work and admitted limit. The first refusal is delivered without waiting for another byte or draining the body; the refused connection closes within five seconds. Incomplete reception cancels on departure and removes its partial file. Complete uploads continue processing after departure. CSV geometry recognition uses names first, in order: a text column named wkt/geometry/geom is parsed as WKT; lon/lat, lng/lat, long/lat, or longitude/latitude pairs become point geometry when each member is numeric or contains no non-blank values; when a member qualifies only by being blank, a numeric prefixed pair takes precedence. Empty and quoted-empty fields are blank; whitespace-only text is not. A row missing either member has null geometry. A prefixed pair (origin_lon/origin_lat, pickup_longitude/…) becomes the point when it is the origin pair or the only one. Safe prefixed x/y retains that name priority; bare x/y and easting/northing are weak candidates. Unsafe names yield to the next eligible name, then to content. A named WKT column with sampled non-null values but none readable stays weak with an unreadable reason and retains its source text; a strong content reading of that same column may apply instead. Content recognition samples the first 1,000 reader rows, excluding NULLs from each format's denominator. WKT/EWKT, GeoJSON geometry objects (not Features or FeatureCollections), WKB hex including EWKB SRIDs, and validated H3 cells are supported. An H3 cell becomes its boundary polygon; unavailable validation yields only an unvalidated weak hint. A content column is strong only when every sampled non-null value reads in that format, with at least one readable value. When some but not all read, it is weak with its sampled count. Strong ties use source column order. Content numeric pairs are always weak; unnamed pairs need at least 50% of complete sampled rows in a possible degree orientation, and ambiguous axes remain marked. The chosen mapping is checked over the entire input for finite longitude/x in [-180,180] and latitude/y in [-90,90], including every geometry vertex and values after the sample. A consistent declared CRS is reprojected to WGS84 under the file-ingest contract; conflicting declarations and untransformable SRIDs stay weak with reasons. Unknown declarations never become a WGS84 assumption. Undeclared degree-compatible WKT/WKB and eligible named pairs assume WGS84; GeoJSON and H3 are inherently WGS84 and declarations are not assumptions. Selected unreadable non-null values keep their rows with NULL geometry and a full-input unreadable count; missing inputs do not increment that count. Content roads retain source columns and add a distinct geometry column; named WKT keeps its replacement behavior. The geometryCandidates evidence retains alternatives, source identities, sample observations, axis roles, CRS and reasons. The geometryRecord identifies the applied choice, source CRS stance and full unreadable count, persisted for table inspection. Legacy records remain absent. Without an eligible mapping the CSV lands as a plain table with all source rows and columns and no CRS assumption. Local and URL CSV imports share these rules; refresh replaces automatic evidence with its artifact atomically, and failure keeps both old versions. A CSV whose detected column names betray a broken read: a name containing a comma (the header was never split), or most names numeric or blank (the first data row was taken as the header) imports with headerSuspect: true. The warning is advisory: it refuses nothing and changes nothing about recognition. MCP accepts at most 16,777,216 bytes for the entire JSON envelope, including base64. The raw file must be below 12 MiB, reduced by envelope and metadata overhead and by the configured upload cap. For canonical base64, subtract the serialized empty-content envelope bytes from 16,777,216, round down to whole groups of four, and allow three file bytes per group.
Parameters
projectQueryThe project every created table joins — a query parameter because the body is the file itself. An unknown project refuses before the upload is received. It must be a project the caller owns or edits, whose owner is active: one the caller only views refuses with forbidden, and one they cannot reach refuses as an unknown one.
string
Request body
multipart/form-data
object
filestringrequiredformatbinaryMCP accepts at most 16,777,216 bytes for the entire JSON envelope, including base64. The raw file must be below 12 MiB, reduced by envelope and metadata overhead and by the configured upload cap. For canonical base64, subtract the serialized empty-content envelope bytes from 16,777,216, round down to whole groups of four, and allow three file bytes per group.
Responses
201
Created.
application/json401403404503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS, POST
Example
Upload world-cities.csv
Needs a token and the file world-cities.csv: 48 cities with latitude and longitude columns. The form's one field, file, carries the file's bytes; the dataset takes its name from the file.
curl
curl -s http://localhost:3000/api/tables \ -H "Authorization: Bearer <YOUR_TOKEN>" \JavaScript
import { openAsBlob } from "node:fs";
const form = new FormData();form.append("file", await openAsBlob("world-cities.csv"), "world-cities.csv");
const response = await fetch("http://localhost:3000/api/tables", { method: "POST", headers: { Authorization: "Bearer <YOUR_TOKEN>" }, body: form,});console.log(JSON.stringify(await response.json(), null, 2));Answers 201 application/json
{ "id": "7d4b2e91-3f6a-4c58-8e12-9a0b5c6d7e2f", "sourceFilename": "world-cities.csv", "format": "csv", "file": "tables/7d4b2e91-3f6a-4c58-8e12-9a0b5c6d7e2f.parquet", "geometryColumn": "geometry", "geometryType": "POINT", "crsAssumed": true, "headerSuspect": false, "geometryRecord": { "columns": [ "longitude", "latitude" ], "format": "pair", "signal": "name", "rule": "exact-pair", "crs": { "stance": "assumed", "srid": null, "label": "WGS 84 assumed" }, "unreadableCount": 0 }, "geometryCandidates": [ { "columns": [ "longitude", "latitude" ], "format": "pair", "signal": "name", "rule": "exact-pair", "strength": "strong", "sample": { "rows": 48, "nonNull": 48, "readable": 48 }, "crs": { "stance": "assumed", "srid": null, "label": "WGS 84 assumed" }, "degreeCompatible": true, "reasons": [], "applied": true, "sourceRetained": true, "orientations": [ { "lon": "longitude", "lat": "latitude" } ] } ], "rowCount": 48, "createdAt": "2026-10-20T09:00:01.283Z", "source": "upload", "sourceParams": null, "importedAt": "2026-10-20T09:00:01.283Z", "name": "world_cities", "projectIds": []}HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 404, 405, 503, defaultAllow
GET, HEAD, OPTIONS, POSTAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/url
POSTImport a remote file as one or more tables
Sign-in Session cookie or Bearer tokenMCP tool import_table_from_url
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Created resources belong to the authenticated account. Submitted owner identities cannot assign or transfer ownership. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Reads a remote Parquet, CSV, GeoJSON, Shapefile-zip, GeoPackage, or KML/KMZ file — https://, s3://, gs://, or az:// — and materializes it as GeoParquet tables (a snapshot, not a live link; one table per spatial layer for container formats). Private buckets use credentials configured in the server environment. The URL is stored as the tables' provenance, so the import can be re-run with the refresh operation.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
urlstringrequiredRemote file URL (https/http/s3/gs/az) ending in a supported extension.
namestringOptional table name; derived from the URL when omitted.
projectIdstringor nullThe project every created table joins; omitted or null, unfiled. An unknown project refuses before the source is contacted. It must be a project the caller owns or edits, whose owner is active: one the caller only views refuses with forbidden, and one they cannot reach refuses as an unknown one.
Responses
201
Created.
application/json401403404413503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/imports/overture
POSTImport Overture Maps data as a table
Sign-in Session cookie or Bearer tokenMCP tool import_table_from_overture
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Created resources belong to the authenticated account. Submitted owner identities cannot assign or transfer ownership. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Reads one Overture theme (places, buildings, transportation, divisions, base, addresses) for a scope straight from the public S3 release and materializes it as a GeoParquet table. The scope is a named area (country, state, or a division found via the search operation) or a drawn shape (bbox or polygon ring). Semantics decide how a drawn or boundary area applies: "within" keeps only features entirely inside (the default for most themes), "intersect" also keeps edge-crossers (default for transportation and base). Divisions take a level (an Overture subtype, e.g. region, county — discover them via the levels operation) and exclude maritime areas. Places accept a category filter. The full set of import parameters is stored as provenance for refresh. Example: all states of Germany = {theme: "divisions", level: "region", scope: {type: "country", code: "DE"}}.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
themestringrequiredOne of
places,buildings,transportation,divisions,base,addressesscopeOvertureScopesemanticsstringHow the area applies; defaulted per theme when omitted.
One of
within,intersectlevelstringDivisions only: the subtype to import (e.g. region, county, locality).
bboxarray of numbermin items4max items4[west, south, east, north], WGS84 — legacy alternative to scope; imports as an intersect rectangle.
releasestringOverture release (e.g. 2026-06-17.0); newest known when omitted.
categorystringPlaces-only category filter.
namestringOptional table name.
projectIdstringor nullThe project every created table joins; omitted or null, unfiled. An unknown project refuses before the source is contacted. It must be a project the caller owns or edits, whose owner is active: one the caller only views refuses with forbidden, and one they cannot reach refuses as an unknown one.
Responses
Also on this path: OPTIONS under System.
/api/imports/overture/count
POSTPreview an Overture import's row count
Sign-in Session cookie or Bearer tokenMCP tool preview_overture_import
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Counts what an import with the same body would land — same scope resolution, same filters — and returns the source query. Use it to sanity-check a selection before importing. With byLevel: true (divisions only) it returns every admin level's count under the scope in one call — the level picker's numbers — instead of a single count.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
themestringrequiredscopeOvertureScopesemanticsstringOne of
within,intersectlevelstringbyLevelbooleanDivisions only: return per-level scoped counts with samples instead of one number.
bboxarray of numbermin items4max items4releasestringcategorystring
Responses
200
The count and the source query — or, with byLevel, the per-level counts (levels with zero matches are absent).
application/jsonobject
countintegerquerystringlevelsarray(each item)objectsubtypestringlabelstringcountintegersamplesarray of string
401403413503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/imports/overture/preview
POSTRun an Overture query and return its features
Sign-in Session cookie or Bearer tokenMCP tool run_overture_query
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Runs exactly the query an import with the same body would run and returns the matching features as GeoJSON — capped by the render cap with truncation stated — so a selection can be inspected on a map before importing (the dialog's Run Query button). The answer, envelope included, is bounded by Bytes drawn per layer (renderCapBytes), counted as it is built; above it the preview answers 422 render_bytes_exceeded with no partial result. The import is not held to that limit.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
themestringrequiredscopeOvertureScopesemanticsstringOne of
within,intersectlevelstringreleasestringcategorystring
Responses
200
The matching features, capped.
application/json401403413422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/imports/overture/divisions/countries
GETList countries in Overture divisions
Sign-in Session cookie or Bearer tokenMCP tool list_overture_countries
Countries present in a release's division data, by ISO code — the roots of the scope picker.
Parameters
releaseQueryRelease; newest known when omitted.
string
Responses
200
Countries.
application/jsonobject
releasestringcountriesarray(each item)objectcodestringnamestringbboxarray of numbermin items4max items4[west, south, east, north] extent.
401403503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/overture/divisions/levels
GETList a country's division levels
Sign-in Session cookie or Bearer tokenMCP tool list_overture_division_levels
The admin levels that actually exist in a country's division data, with counts and sample names — Overture's vocabulary lands differently per country (German municipalities are one subtype, French communes another), so levels are discovered, never assumed.
Parameters
countryQueryrequiredTwo-letter ISO country code.
string
releaseQueryRelease; newest known when omitted.
string
Responses
200
Levels, coarse to fine.
application/jsonobject
releasestringcountrystringlevelsarray(each item)objectsubtypestringlabelstringcountintegersamplesarray of string
401403503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/overture/divisions/states
GETList a country's states
Sign-in Session cookie or Bearer tokenMCP tool list_overture_states
The country's state/region divisions with ISO 3166-2 codes — each is a scope: {type: "state", code}. Empty when the country has no region level.
Parameters
countryQueryrequiredTwo-letter ISO country code.
string
releaseQueryRelease; newest known when omitted.
string
Responses
200
States, alphabetical.
application/jsonobject
releasestringstatesarray(each item)objectcodestringnamestringbboxarray of numbermin items4max items4[west, south, east, north] extent.
401403503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/overture/divisions/search
GETFind a division by name
Sign-in Session cookie or Bearer tokenMCP tool search_overture_divisions
Name search over a country's divisions (cities, municipalities, counties) for the typed city scope — matched against the division data itself, never a geocoder. The returned id is a scope: {type: "division", id}.
Parameters
countryQueryrequiredTwo-letter ISO country code.
string
qQueryrequiredName text; prefix matches rank first.
string
releaseQueryRelease; newest known when omitted.
string
Responses
200
Ranked matches.
application/jsonobject
releasestringmatchesarray(each item)objectidstringnamestringsubtypestringkindstringregionstringor nullbboxarray of numbermin items4max items4[west, south, east, north] extent.
401403503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/osm
POSTImport OpenStreetMap data as tables
Sign-in Session cookie or Bearer tokenMCP tool import_table_from_osm
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Created resources belong to the authenticated account. Submitted owner identities cannot assign or transfer ownership. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Queries the configured Overpass endpoint and lands the result as GeoParquet tables split by geometry class (stem_points / stem_lines / stem_polygons, non-empty classes only) — one import group with one stored query, refreshed together. Provide selectors (tag filters like ["amenity=restaurant"]) with a bbox, or a raw OverpassQL query (the escape hatch; overpass-turbo's {{bbox}} is honoured). Either way the server applies its safety envelope (output format, timeout, size). Tags land as one JSON column plus promoted plain columns for name and the queried keys. Identical queries within the cache window do not re-hit the endpoint.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
selectorsarray of stringTag selectors: "key" or "key=value" entries.
qlstringRaw OverpassQL (alternative to selectors); the safety envelope replaces any declared settings.
bboxarray of numbermin items4max items4[west, south, east, north], WGS84.
ringarray of arrayDrawn polygon [[lng, lat], …] (≤ 500 points) — alternative to bbox; becomes an Overpass poly filter.
(each item)array of numbermin items2max items2
geometryobjectA GeoJSON Polygon or MultiPolygon (≤ 20,000 vertices) as the area — e.g. a feature from an existing table. Each part becomes an Overpass poly filter; holes apply in the post-fetch within filter. Takes precedence over ring/bbox.
semanticsstringwithin keeps only features entirely inside the drawn shape (enforced server-side after geometry assembly — Overpass itself returns intersections); the default is intersect.
One of
within,intersectnamestringOptional table-name stem.
projectIdstringor nullThe project every created table joins; omitted or null, unfiled. An unknown project refuses before the source is contacted. It must be a project the caller owns or edits, whose owner is active: one the caller only views refuses with forbidden, and one they cannot reach refuses as an unknown one.
Responses
201
Created tables, one per non-empty geometry class.
401403404413503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/imports/osm/preview
POSTRun an OSM query and return its features
Sign-in Session cookie or Bearer tokenMCP tool run_osm_query
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Runs exactly the Overpass fetch an import with the same body would run — same assembly and within filter — and returns the features as GeoJSON, capped by the render cap. The response is served from the query cache when possible, and a following import reuses it. The answer, envelope included, is bounded by Bytes drawn per layer (renderCapBytes), counted while the features are assembled; above it the preview answers 422 render_bytes_exceeded with no partial result. The import is not held to that limit.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
selectorsarray of stringqlstringbboxarray of numbermin items4max items4ringarray of array(each item)array of numbermin items2max items2
geometryobjectGeoJSON Polygon/MultiPolygon area (≤ 20,000 vertices).
semanticsstringOne of
within,intersectnamestring
Responses
200
The matching features, capped.
application/json401403413422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
OPTIONS, POST
Also on this path: OPTIONS under System.
/api/imports/overture/releases
GETList Overture releases
Sign-in Session cookie or Bearer tokenMCP tool list_overture_releases
Available releases, newest first.
Responses
200
Releases.
application/jsonobject
releasesarray of stringlateststring
401403503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/imports/postgis
POSTImport a PostGIS table as a snapshot
Sign-in Session cookie or Bearer tokenMCP tool import_table_from_postgis
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. Created resources belong to the authenticated account. Submitted owner identities cannot assign or transfer ownership. Connections are private to the authenticated account, including for administrators. Names are unique only within that account. Hidden or missing connection references return not_found before reading credentials, contacting the source or changing stored health. Imports and refreshes recheck connection ownership and account activity before committing. Snapshots and their project memberships include only the caller's datasets. A project grant never reaches a connection: one behind a dataset shared with the caller is listed, browsed, tested and used by nobody but its owner, answering not_found as one that does not exist; refreshing such a dataset is its owner's act alone; no operation transfers a connection. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Materializes the table as a GeoParquet snapshot — read-only against the source, geometry normalized to WGS84 on the source side. An optional attribute filter and row limit narrow the import and become part of the stored import parameters, so refresh honours them. Live federation is deliberately not offered.
Request body
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
connectionIdstringrequiredschemastringrequiredtablestringrequirednamestringOptional table name.
filterstringOptional WHERE expression evaluated on the source.
limitintegerOptional row limit.
projectIdstringor nullThe project every created table joins; omitted or null, unfiled. An unknown project refuses before the source is contacted. It must be a project the caller owns or edits, whose owner is active: one the caller only views refuses with forbidden, and one they cannot reach refuses as an unknown one.
Responses
Also on this path: OPTIONS under System.
/api/tables/{name}/refresh
POSTRefresh an imported table
Sign-in Session cookie or Bearer tokenMCP tool refresh_table
At most 16,777,216 wire bytes; a larger body is refused with request_body_too_large before JSON parsing. A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Re-runs the table's stored import (URL, Overture, and OSM imports) and replaces its data atomically. A failed refresh leaves the previous data fully intact. Dependent layers pick up the refreshed data on their next render. Overture tables accept an optional release ("latest" or a specific one) to move the stored import parameters — an explicit choice, never implicit. Refreshing any table of an OSM import group re-runs the stored query once (bypassing the cache) and updates every table of the group together. Refresh is single-flight per table (per group for OSM): while one runs, a second request answers 409 refresh_in_flight without starting another build; retry when the running refresh completes. A table deleted while its refresh runs answers 404 not_found and nothing is replaced. A saved manual geometry choice on a URL import replays against fresh source columns before automatic conversion, survives restart, and commits with the artifact and geometryRecord. Missing selected columns fail atomically with 400 column_unavailable; bad rows remain null geometries and are counted. Each container member keeps its own choice and the group downloads once and publishes together. Clear removes the override: the next refresh resumes automatic recognition, records its fresh result and resets geometry mode to unmodified. An unusable saved choice refuses atomically with 422 geometry_choice_invalid, including projection_required or conflicting_crs issues. A changed generation refuses with 409 input_changed.
Parameters
namePathrequiredTable name.
string
Request body (optional)
At most 16,777,216 bytes (16 MiB); a larger body is refused with request_body_too_large.
application/json
object
releasestringOverture only: "latest" or a release like 2026-06-17.0.
Responses
Also on this path: OPTIONS under System.
/api/tables/{name}/features
GETRead a table's features as GeoJSON
Sign-in Session cookie or Bearer tokenMCP tool get_table_features
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. The table's features as a GeoJSON FeatureCollection, for drawing it as a reference layer (the import dialog's map legend and Select from Layer use this). A table that cannot draw — no geometry column, more features than the render cap, or a complete uncompressed answer over Bytes drawn per layer — returns ok:false with a plain-language reason and no features instead of an error. With sample=1 an over-cap table draws its first cap-many features and flags the response as sampled, unless that sample is itself over the byte limit.
Parameters
namePathrequiredTable name.
string
sampleQueryDraw a capped subset of an over-cap table instead of refusing; the response carries sampled + totalCount. A sample over Bytes drawn per layer is still refused.
string
One of
1
Responses
200
The features, or an honest refusal.
application/jsonobject
okbooleanrequirednamestringrequiredgeometryTypestringor nullfeatureCountintegergeojsonobjectFeatureCollection when ok; features carry a stable numeric id.
sampledbooleanTrue when a capped subset was drawn.
totalCountintegerThe table's real row count when sampled.
reasonstringWhy the table cannot draw, when not ok.
401403404503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 404, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/tables/{name}/export
GETDownload a table
Sign-in Session cookie or Bearer token
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. The table as a file download: geoparquet streams the stored artifact byte-for-byte; geojson (spatial tables only) and csv (geometry as WKT) are converted on the fly. The response is an attachment named <table>.<ext>.
Parameters
namePathrequiredTable name.
string
formatQueryDownload format; geoparquet when omitted.
stringdefault
geoparquetOne of
geoparquet,geojson,csv
Responses
200
The file, as an attachment.
application/octet-streamstringformat
binary400
Unknown format, or GeoJSON asked of a non-spatial table.
401403404503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 400, 401, 403, 404, 405, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/tables/{name}
GETInspect a table
Sign-in Session cookie or Bearer tokenMCP tool inspect_table
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Schema, row count, and a fifty-row preview. Preview text values, and the registered geometry column's WKT, longer than 512 characters show their first 512 characters followed by an ellipsis (…); other values, nested values, additional geometry columns, the schema, the row count and the stored data are never excerpted. The complete uncompressed UTF-8 JSON answer, including metadata, schema and envelope, is limited to 33,554,432 bytes (32 MiB); a non-geometry column value after excerpts, including nested values and escaping, to 2,097,152 bytes (2 MiB). Equality is admitted. Only the registered native geometry column, emitted as WKT, is exempt from the cell ceiling. Exceeding either bound refuses the whole inspection with HTTP 422 query_result_too_large, without partial data. The limits have no setting and do not apply to layer reads, dataset map features, file exports or owner deletion. A refused inspection leaves the dataset detail and its set-geometry panel unavailable.
Parameters
namePathrequiredTable name.
string
Responses
200
Success.
application/json401403404422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
DELETE, GET, HEAD, OPTIONS
DELETEDelete a table
Sign-in Session cookie or Bearer tokenMCP tool delete_table
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit.
Parameters
namePathrequiredTable name.
string
Responses
HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 401, 403, 404, 405, 422, 503, defaultAllow
DELETE, GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
/api/catalogue/tables
GETRead the schema-only table catalogue
Sign-in Session cookie or Bearer tokenMCP tool read_table_catalogue
A dataset is reached by its owner and by the owner and people of every project it is filed in. Lists, schema discovery and counts cover exactly the reached datasets and name each one's owner and the name the caller would type for it: the plain name for the caller's own, <sql name>.<name> for another owner's. Another owner's dataset is shown without connection facts and without links to what the caller cannot reach: a PostGIS snapshot shows its origin kind, with neither its connection nor its remote schema and table. A bare dataset name in a path or parameter is the caller's own dataset. On dataset reads, features, downloads and operation parameters, another owner's dataset the caller reaches is addressed by its qualified name, and in a /api/tables path also by its identifier; changing one by any address answers forbidden. Datasets change, refresh and go only by their owner; administrators reach nothing more. Upload and sketch suffixes ignore other accounts' names. Unreached and missing datasets, maps and project references return not_found before source or artifact access; a refused change leaves resources unchanged. Refresh and geometry changes preserve the dataset's identity and owner and recheck account activity at commit. Names, stable identities, owners, the reached projects each dataset is filed in, recorded row counts and geometry facts with stored artifact column names and types. Reads metadata only, without evaluating row previews or healing geometry records. Recorded geometry identity is separate from the physical column type. Ordered by qualifiedName, the name the caller would type, which is unique within the caller's reach: two same-named datasets of different owners each appear exactly once. At most 32 tables and 64 columns per table per page. after continues tables; columnOffset continues columns for a named table. total counts matching tables, columnCount counts each table’s columns. Incomplete collections carry nextAfter or nextColumnOffset. A missing artifact fails the read instead of returning a false empty schema. Responses are bounded to 96 KiB; a response that cannot fit answers 422 catalogue_too_large so the caller can request fewer tables or columns. No artifact paths, source configuration, credentials, row samples or attachment bytes are returned.
Parameters
afterQueryExclusive qualifiedName cursor from nextAfter.
string
namesQueryComma-separated exact names as the caller would type them (qualifiedName), at most 32: a plain name is the caller's own dataset, <sql name>.<name> another owner's. Missing or unreached names answer not_found.
string
projectQueryOnly this reached project's datasets, whoever owns them; none means the caller's own datasets filed in no project at all. An unknown or unreached project answers not_found.
string
limitQueryTables per page, 1 to 32; default 32.
integerminimum
1maximum32columnsQueryColumns per table, 0 to 64; default 64. Zero returns identities and recorded facts with the column count.
integerminimum
0maximum64columnOffsetQueryZero-based column cursor, default 0.
integerminimum
0
Responses
200
Success.
application/json400401403404422503default
Error with a machine-readable code and human message.
application/json405
method_not_allowed: the method is unsupported for this path.
application/jsonAllowHeaderExactly the documented methods for this path.
stringalways
GET, HEAD, OPTIONS
Example
Read a page of one dataset with its columns
Needs a token, and the datasets world_cities and big_cities. nextAfter is the cursor for the next page: send it as after.
curl
curl -s "http://localhost:3000/api/catalogue/tables?limit=1" \ -H "Authorization: Bearer <YOUR_TOKEN>"JavaScript
const response = await fetch("http://localhost:3000/api/catalogue/tables?limit=1", { headers: { Authorization: "Bearer <YOUR_TOKEN>" },});console.log(JSON.stringify(await response.json(), null, 2));Answers 200 application/json
{ "tables": [ { "id": "c2e8f4a1-6b3d-4f97-a5c0-1d2e3f4a5b6c", "name": "big_cities", "qualifiedName": "big_cities", "owner": { "name": "Ana Diaz", "sqlName": "ana_diaz" }, "projectIds": [], "rowCount": 15, "geometryColumn": "geometry", "geometryType": "POINT", "crsAssumed": true, "columns": [ { "name": "name", "type": "VARCHAR" }, { "name": "country", "type": "VARCHAR" }, { "name": "population", "type": "BIGINT" }, { "name": "geometry", "type": "GEOMETRY('EPSG:4326')" } ], "columnCount": 4, "nextColumnOffset": null } ], "total": 2, "nextAfter": "big_cities"}HEADRead response headers
Sign-in Session cookie or Bearer tokenAnswers 200, 400, 401, 403, 404, 405, 422, 503, defaultAllow
GET, HEAD, OPTIONSAutomatic HEAD uses GET with no response body.
Also on this path: OPTIONS under System.
7439201b