Authentication
JWT bearer tokens, API keys (header and query forms), and OAuth/OIDC. Start here if your client is making its first request.
The GeoLens REST API exposes the full catalog, search, map, and standards endpoints. This reference is auto-generated from a committed OpenAPI snapshot of a running GeoLens instance. Every endpoint, parameter, and response schema is derived directly from the FastAPI application.
Authentication
JWT bearer tokens, API keys (header and query forms), and OAuth/OIDC. Start here if your client is making its first request.
OGC & Standards Endpoints
OGC API Common, Records, Features, STAC 1.0, and tile endpoints with QGIS, GDAL, and pystac-client examples.
Endpoints by Tag
Browse the full reference grouped by FastAPI tag. Each operation includes parameters, request body, and response schemas. The sidebar lists all 25 tag groups, and the index at the bottom of this page names every operation so you can search for one by method and path.
QGIS
Add a GeoLens dataset to QGIS over OGC API Features, push CQL2 filters down to the server, and paste vector-tile URLs directly.
Client SDKs
Prefer typed code over raw HTTP? The Python and TypeScript SDKs are auto-generated from this same contract.
Ingest & jobs
Writing to the catalog: upload, preview, commit, then poll the job. Real endpoint paths and the 202-then-poll contract.
Errors & rate limits
The RFC 7807 body every failure returns, and what a 429 looks like when you have asked for too much too fast.
Runnable examples
Single-file pages and scripts that run against the public demo: MapLibre, Leaflet, OpenLayers, ArcGIS JS, QGIS, STAC, DuckDB, GeoPandas, the SDKs, the CLI, and MCP. CI replays them against the demo on every change.
Reading the catalog is one half of the API; the ingest lane is the other. The
write endpoints under /ingest require a credential carrying the upload
capability; GET /ingest/upload/config needs only an authenticated user, and
GET /jobs/{job_id} is limited to the job’s owner (or an admin). A read_only
API key authenticates GET, HEAD, and OPTIONS only, so it cannot drive this
sequence — use a full key or a JWT (see
Authentication). Paths below are relative to the API base,
http://localhost:8080/api on a default install.
1. Ask what the instance accepts. GET /ingest/upload/config returns
allowed_extensions, max_file_size_bytes, presigned_uploads, and
presigned_threshold_bytes. The extension list is an admin setting
(upload_allowed_extensions, Admin -> Storage); the shipped default is
.zip, .gpkg, .geojson, .json, .csv, .tif, .tiff, .xlsx, .xls, .parquet, .fgb, .kml, .kmz, .3tz, .laz.
Standalone .vrt uploads are rejected at every upload door — a VRT is assembled
from raster datasets already in the catalog, via POST /ingest/vrt/create. Create
and add-source answer 422 when the VRT would reach people who cannot read one
of its members, which the VRT’s owner does not also own.
2. Send the bytes. POST /ingest/upload as multipart/form-data with a
file part returns 201 and a job_id. Nothing is queued yet.
Add a kind field for the 3D types: tiles3d for a 3D Tiles .zip or .3tz
archive, pointcloud for a COPC .laz. Without it a .3tz or .laz is
refused, and a tileset .zip is read as ordinary geospatial data. Omit kind
for every other file. See 3D Tiles and point clouds.
On an instance backed by S3 storage (presigned_uploads: true in the config
response), the payload can skip the API entirely: POST /ingest/upload/presigned
with {"filename", "file_size", "content_type"} (plus kind for the 3D types) returns 201 with a job_id
and one or more presigned urls. PUT the bytes yourself — a single URL below
presigned_threshold_bytes, part_size-sized parts above it — then
POST /ingest/upload/presigned/{job_id}/complete, passing
{"parts": [{"etag", "part_number"}]} for the multipart case.
3. Preview. POST /ingest/preview/{job_id}, callable only while the job is
pending. Vector sources come back with columns, CRS, geometry type, feature
count, sample rows, and the layer list; rasters with band count, CRS,
resolution, and COG compliance. Add ?layer_name= to inspect one layer of a
multi-layer source.
4. Commit. POST /ingest/commit/{job_id} with a body of at least
{"title": "..."} returns 202 Accepted and queues the ingest task. For a
multi-layer source, POST /ingest/commit-fan-out/{job_id} turns each requested
layer into its own dataset — run the preview first, because the endpoint
validates every layer_name against the layer list the preview recorded.
5. Poll the job. GET /jobs/{job_id} reports status — one of pending,
running, complete, failed, cancelled, fanned_out — plus progress
(0 to 1), current_step, error_message, and dataset_id once the dataset
exists. cancelled means the job was cancelled with
POST /jobs/{job_id}/cancel, or it was an upload nobody committed or completed,
which the stale-job sweep settles as cancelled with the reason
upload_abandoned. failed means work was attempted and broke.
Already have the data in PostGIS? GET /ingest/discover/ lists tables that
aren’t in the catalog yet, and POST /ingest/register/ catalogs one in place
without moving any bytes. These two are admin-only: they need the
manage_settings permission rather than upload, so an editor gets 403.
Request and response schemas for all of these live in the generated reference: the ingest operations under the Datasets tag, the job endpoints under the Admin tag.
POST /query/ runs one SELECT through a read-only sandbox and returns
{columns, rows, row_count, truncated}. It is a POST that is semantically a
read, so a read_only API key is accepted; the caller must be authenticated
either way and hold the use_ai_chat permission, which editors and admins have
by default and viewers do not.
restrict_tables is required and non-empty. It names every data.* table the
statement may touch, without the data. prefix, and it can only narrow what
your credential already sees — it never widens it. A dataset’s table name is the
table_name field of GET /datasets/{dataset_id}.
curl -sS -X POST "$GEOLENS_URL/api/query/" \ -H "X-Api-Key: $GEOLENS_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"sql": "SELECT name, pop_est FROM data.world_countries_natural_earth_1_50m LIMIT 5", "restrict_tables": ["world_countries_natural_earth_1_50m"], "row_limit": 5}'The sandbox refuses anything that is not a single SELECT, along with writes,
other schemas, and functions outside its allowlist. Each query runs under a
5-second statement timeout and a row_limit of at most 1000 (default 100), and
one caller runs one query at a time. Rejections come back as 422 (invalid or
too expensive), 404 (a table you named that you cannot see — denial and
non-existence deliberately share one answer), or 429 (your previous query is
still running, or the instance is at its concurrency ceiling). The full budget —
the self-join cap, the blocked output-amplifying functions, the response-size
ceiling — is written out under
Using query, because the MCP server’s query
tool is the same endpoint.
Errors raised by the application answer as RFC 7807 problem details:
Content-Type: application/problem+json, with a four-field body.
{ "type": "about:blank", "title": "Not Found", "status": 404, "detail": "Dataset not found"}All four fields are always present. type is about:blank on every error —
GeoLens does not mint per-error type URIs, so branch on status, never on
type. title is a short label, normally the reason phrase for that status
(Validation Error on a 422). detail is normally a
string; a validation failure names the offending parameter
(query.limit: Input should be a valid integer), and a handful of endpoints put
an object or an array there instead, so parse it defensively rather than
assuming a string. A refused workflow transition, for one, answers 422 with an
object carrying code, message, current_stage, requested_stage and
allowed_stages.
The standards surface — /, /conformance, /collections*, /stac* — uses
the same envelope with one difference: OGC API Common requires malformed
parameters to be reported as 400, where the native routes report 422. Same
body, different number. A client that treats 422 as “I sent something bad”
should treat 400 the same way.
One failure skips the envelope. A request that matches no route at all, or uses
a method a matched path does not answer, is rejected by the framework before any
handler and comes back as plain application/json — {"detail": "Not Found"}
with a 404, {"detail": "Method Not Allowed"} with a 405.
Responses carry an X-Request-ID. A 500 body is deliberately generic — the
exception, the path, and the caller are written to the server log against that
id — so quote it when reporting one. It is not on the CORS expose list, so a
cross-origin browser client cannot read it; same-origin and server-side callers
can.
Limits are keyed on the client IP, except the SQL sandbox, which additionally
buckets per user, and the failed sign-in limit, which counts per account (with
a separate budget for each browser that has signed in to it before). The global,
semantic search and basemap limits are admin settings on the Network tab,
and the login limit is on the Authentication tab (LOGIN_RATE_LIMIT), so an
instance you do not run may be tuned differently. The SQL sandbox limits and the
per-account failed sign-in limit are fixed. The values below are the shipped defaults.
| Limit | Default | Applies to |
|---|---|---|
| Global | 60/second | every route except the tile routes and the AI routes below |
| Login | 5/minute | POST /auth/login |
| Failed sign-ins per account | 10/hour | POST /auth/login, for a client the account does not know; a browser that has signed in before has its own budget, and API keys are not affected (see Sign-in throttling) |
| Semantic search | 30/minute | /search/datasets/, /search/facets/, /datasets/{id}/related/ |
| Basemap list | 120/minute | GET /settings/basemaps/ |
| SQL sandbox | 30/minute per user, 60/minute per IP | POST /query/ |
The login, semantic search, basemap and SQL sandbox limits apply on top of the global one, so a request to those routes counts against both. Tile routes are exempt from the global limit, and the AI generation and metadata routes have fixed limits of their own instead (10/minute and 20/minute).
These figures are per instance only where the instance is configured for it.
From 1.19.0 the counting is shared across API workers when REDIS_URL is set,
and per worker when it is not, so on a multi-worker instance without the store
each limit above except the failed sign-in limit is enforced once per worker
rather than once for the instance. The sign-in limit is counted in the database,
so it is shared across workers either way.
The same holds for as long as a configured store is unreachable. Read the table
as the operator’s intent rather than as something to calibrate a client
against, and back off on 429 either way.
Over any limit, global or per-route, you get a 429 in the usual problem+json
envelope, with a Retry-After header giving the limiter’s window in seconds:
HTTP/1.1 429 Too Many RequestsRetry-After: 60Content-Type: application/problem+jsonThe global window is one second, so Retry-After is 1 there and a caller that
hits it should pause about a second and resume. Read Retry-After and fall back
to your own delay when it is missing, with jitter so a fleet of clients does not
resynchronise.
Retry-After is named in Access-Control-Expose-Headers on both CORS policies
— the credentialed one and the credential-free one the anonymous public routes
get — so a browser client reads the retry window cross-origin instead of seeing
an opaque failure.
Two limits live outside the API, in the bundled frontend nginx, which is the
application edge in the standard deployment. It throttles raster tile requests
at /raster-tiles/... to 600/minute per IP with a burst of 200, for anonymous
and credentialed callers alike, and answers with a 503 rather than a 429.
The body is nginx’s, not the API’s. It also limits vector and cluster tile
requests (/api/tiles/data.* and /api/tiles/clusters/data.*) to 5400/minute
with a burst of 720, and answers 429 with Retry-After: 2 and a CORS header.
That limit applies only when TRUSTED_PROXY_CIDRS is set. With it empty, the
default, the frontend’s entrypoint leaves the limit key blank, and nginx does not
count requests with an empty key.
Every operation in the snapshot, grouped and ordered the way the sidebar is — tag groups A to Z — with the operations inside each group sorted by path. Search finds this page by method, path, or summary; the generated operation pages themselves are not indexed.
GET /admin/ai-status/ — Get Ai StatusPATCH /admin/ai-status/ — Update Ai StatusGET /admin/api-keys/ — List Api KeysPOST /admin/api-keys/ — Create Api KeyDELETE /admin/api-keys/{key_id} — Revoke Api KeyGET /admin/audit-logs/ — List Audit LogsGET /admin/audit-logs/export/{format} — Download audit recordsPOST /admin/backfill-embeddings/ — Trigger BackfillGET /admin/embedding-stats/ — Get Embedding StatsGET /admin/infrastructure/ — Get InfrastructureGET /admin/jobs/ — List Admin JobsGET /admin/share-tokens/ — List Share Tokens EndpointDELETE /admin/share-tokens/{token_id} — Admin Revoke Share TokenGET /admin/stats/ — Get Catalog StatsGET /admin/users/ — List UsersPOST /admin/users/ — Create UserDELETE /admin/users/{user_id} — Delete UserGET /admin/users/{user_id} — Get UserPATCH /admin/users/{user_id} — Update UserPOST /admin/users/{user_id}/approve/ — Approve UserPOST /admin/users/{user_id}/deactivate/ — Deactivate UserPOST /admin/users/{user_id}/reject/ — Reject UserPOST /admin/users/{user_id}/reset-password/ — Reset User PasswordGET /admin/users/export.csv — Export registered users as CSVGET /admin/users/names/ — List User NamesGET /jobs/{job_id} — Get Job StatusPOST /jobs/{job_id}/cancel — Cancel JobPOST /jobs/{job_id}/retry — Retry JobGET /jobs/by-dataset/{dataset_id} — Get Job Status By DatasetPOST /jobs/cleanup/stale/ — Cleanup Stale JobsPUT /settings/ — Update SettingsGET /settings/all/ — Get All SettingsGET /settings/api-key-status/ — Get Api Key StatusGET /settings/basemaps/ — Get BasemapsGET /settings/branding/ — Get BrandingGET /settings/config-mode/ — Get Config ModePOST /settings/detect-embedding-dims/ — Detect Embedding DimsGET /settings/edition/ — Get runtime capabilitiesGET /settings/enabled-plugins/ — Get Enabled PluginsGET /settings/enterprise-tabs/ — List restricted settings tabsGET /settings/feature-flags/ — Get Feature FlagsGET /settings/map-defaults/ — Get Map DefaultsGET /settings/notifications/status/ — Get Notification StatusPOST /settings/notifications/test/ — Send Test NotificationGET /settings/oauth-providers/ — List Oauth ProvidersPOST /settings/oauth-providers/ — Create Oauth ProviderDELETE /settings/oauth-providers/{provider_id} — Delete Oauth ProviderPUT /settings/oauth-providers/{provider_id} — Update Oauth ProviderPOST /settings/reset/ — Reset SettingsGET /settings/tile-config/ — Get Tile ConfigGET /admin/embed-tokens/ — List All Embed TokensPOST /admin/embed-tokens/bulk-revoke/ — Bulk RevokeGET /audit/datasets/{dataset_id}/column-ddl — Get Column Ddl FeedGET /auth/api-keys/ — List My Api KeysPOST /auth/api-keys/ — Create My Api KeyDELETE /auth/api-keys/{key_id} — Revoke My Api KeyPOST /auth/change-password/ — Change PasswordGET /auth/config/ — ConfigPOST /auth/download-token/{dataset_id} — Create Download Token EndpointPOST /auth/login — LoginPOST /auth/logout/ — LogoutPOST /auth/logout/session/ — Logout Current SessionGET /auth/me/ — MeGET /auth/me/permissions/ — Me PermissionsGET /auth/me/usage/ — Me UsageGET /auth/oauth/{provider_slug}/callback — Oauth CallbackGET /auth/oauth/{provider_slug}/login — Oauth LoginPOST /auth/oauth/exchange/ — Exchange Sign In CodeGET /auth/oauth/providers/ — List Public ProvidersPOST /auth/refresh/ — RefreshPOST /auth/register/ — RegisterPOST /auth/resend-verification/ — Resend VerificationPOST /auth/verify-email/ — Verify EmailPOST /config-ops/dry-run/ — Dry Run ConfigurationGET /config-ops/export/ — Export ConfigurationPOST /config-ops/import/ — Import ConfigurationPOST /config-ops/validate/ — Validate ConfigurationGET /catalog/collections/ — List Collections EndpointPOST /catalog/collections/ — Create Collection EndpointDELETE /catalog/collections/{collection_id} — Delete Collection EndpointGET /catalog/collections/{collection_id} — Get Collection EndpointPATCH /catalog/collections/{collection_id} — Update Collection EndpointGET /catalog/collections/{collection_id}/datasets/ — Get Collection Datasets EndpointPOST /catalog/collections/{collection_id}/datasets/ — Add Datasets EndpointDELETE /catalog/collections/{collection_id}/datasets/{dataset_id} — Remove Dataset EndpointGET /datasets/ — List All DatasetsDELETE /datasets/{dataset_id} — Delete Dataset EndpointGET /datasets/{dataset_id} — Get Single DatasetPATCH /datasets/{dataset_id} — Update Dataset MetadataGET /datasets/{dataset_id}/api-keys — List Dataset Api KeysPOST /datasets/{dataset_id}/api-keys — Create Dataset Api KeyDELETE /datasets/{dataset_id}/api-keys/{key_id} — Revoke Dataset Api KeyGET /datasets/{dataset_id}/copc/{attempt_id}/{name}.copc.laz — Get Pointcloud FileGET /datasets/{dataset_id}/export — Export Dataset EndpointGET /datasets/{dataset_id}/history — Get Dataset HistoryGET /datasets/{dataset_id}/quicklook — Get QuicklookGET /datasets/{dataset_id}/refresh-runs — List Dataset Refresh RunsPUT /datasets/{dataset_id}/retention/ — Set Dataset RetentionGET /datasets/{dataset_id}/tiles3d/{path} — Get Tileset FilePOST /datasets/bulk-delete/ — Bulk Delete Datasets EndpointPOST /datasets/create/ — Create Empty Dataset EndpointPOST /ingest/commit-fan-out/{job_id} — Commit Fan OutPOST /ingest/commit/{job_id} — Commit ImportGET /ingest/discover/ — Discover TablesPOST /ingest/manifest/apply — Apply Manifest EndpointPOST /ingest/preview/{job_id} — Preview FilePOST /ingest/register/ — Register TablePOST /ingest/register/bulk/ — Bulk Register TablesPOST /ingest/upload — Upload FileGET /ingest/upload/config — Get Upload ConfigPOST /ingest/upload/presigned — Request Presigned UploadPOST /ingest/upload/presigned/{job_id}/complete — Complete Presigned UploadPOST /ingest/upload/url — Upload From UrlPOST /ingest/vrt/{dataset_id}/sources/ — Add Vrt SourceDELETE /ingest/vrt/{dataset_id}/sources/{source_dataset_id}/ — Remove Vrt SourcePOST /ingest/vrt/create — Create VrtPOST /services/arcgis/signin/ — Arcgis SigninGET /services/connectors/ — List Connectors EndpointPOST /services/connectors/{connector_name}/discover/ — Discover Connector Resources EndpointPOST /services/connectors/{connector_name}/ingest/ — Dispatch Connector Ingest EndpointPOST /services/preview/ — Preview Service LayerPOST /services/probe/ — Probe Service UrlPOST /datasets/{dataset_id}/analysis/materialize/ — Analysis Materialize EndpointPOST /datasets/{dataset_id}/analysis/preview/ — Analysis Preview EndpointGET /datasets/{dataset_id}/maps/ — Dataset MapsGET /datasets/{dataset_id}/related/ — List Related DatasetsGET /datasets/{dataset_id}/rows/ — Get Dataset Rows EndpointPATCH /datasets/{dataset_id}/status/ — Update Publication StatusPATCH /datasets/{dataset_id}/target-status/ — Set Target StatusGET /datasets/{dataset_id}/validate/ — Validate DatasetGET /datasets/{dataset_id}/dcat-us/3.0/ — Get Dcat Us3 RecordGET /datasets/{dataset_id}/dcat-us/3.0/validation/ — Validate Dcat Us3 RecordGET /datasets/{dataset_id}/dcat/ — Get Dcat RecordGET /datasets/{dataset_id}/dcat/validation/ — Validate Dcat3 RecordGET /datasets/{dataset_id}/download/cog — Download CogGET /datasets/{dataset_id}/geodcat-ap/ — Get Geodcat Ap RecordGET /datasets/{dataset_id}/geodcat-ap/validation/ — Validate Geodcat Ap RecordGET /datasets/dcat-us/3.0/ — Get Dcat Us3 CatalogGET /datasets/dcat-us/3.0/validation/ — Validate Dcat Us3 CatalogGET /datasets/dcat/ — Get Dcat CatalogGET /datasets/dcat/validation/ — Validate Dcat3 CatalogGET /datasets/geodcat-ap/ — Get Geodcat Ap CatalogGET /datasets/geodcat-ap/validation/ — Validate Geodcat Ap CatalogGET /datasets/{dataset_id}/attributes/ — List Attributes EndpointGET /datasets/{dataset_id}/attributes/{attribute_id}/ — Get Attribute EndpointPATCH /datasets/{dataset_id}/attributes/{attribute_id}/ — Update Attribute EndpointPOST /datasets/{dataset_id}/attributes/{attribute_id}/reset/ — Reset Attribute EndpointGET /datasets/{dataset_id}/columns/{column_name}/stats/ — Get Column Stats EndpointGET /datasets/{dataset_id}/columns/{column_name}/values/ — Get Column ValuesGET /datasets/{dataset_id}/features/{gid}/related/{relationship_id}/ — Get Feature Related RecordsGET /datasets/{dataset_id}/relationships/ — List Dataset RelationshipsPOST /datasets/{dataset_id}/relationships/ — Create Dataset RelationshipGET /datasets/{dataset_id}/versions/ — Get Dataset Versions EndpointDELETE /datasets/relationships/{relationship_id}/ — Delete Dataset RelationshipDELETE /datasets/{dataset_id}/previous-version — Delete Previous VersionPOST /datasets/{dataset_id}/previous-version/restore — Restore Previous VersionPOST /datasets/{dataset_id}/refresh — Refresh DatasetPOST /datasets/{dataset_id}/reupload — Reupload DatasetPOST /datasets/{dataset_id}/reupload/{job_id}/commit — Reupload CommitPOST /datasets/{dataset_id}/reupload/{job_id}/preview — Reupload PreviewPOST /datasets/{dataset_id}/reupload/presigned — Request Presigned ReuploadPOST /datasets/{dataset_id}/reupload/presigned/{job_id}/complete — Complete Presigned ReuploadPOST /datasets/{dataset_id}/reupload/service/preview — Reupload Service PreviewPOST /datasets/{dataset_id}/source-health/ — Check Source HealthGET /datasets/{dataset_id}/vrt-sources/ — List Vrt SourcesGET /datasets/{dataset_id}/vrt/generations/ — List Vrt GenerationsPOST /datasets/{dataset_id}/vrt/regenerate/ — Regenerate Vrt EndpointGET /datasets/{dataset_id}/vrt/status/ — Get Vrt StatusGET /maps/{map_id}/embed-tokens/ — List Embed Tokens EndpointPOST /maps/{map_id}/embed-tokens/ — Create Embed Token EndpointDELETE /maps/{map_id}/embed-tokens/{token_id}/ — Revoke Embed Token EndpointPATCH /maps/{map_id}/embed-tokens/{token_id}/ — Update Embed Token EndpointGET /datasets/{dataset_id}/features.geojson — Get Features Geojson Z EndpointGET /datasets/{dataset_id}/features/ — List FeaturesPOST /datasets/{dataset_id}/features/ — Create FeatureDELETE /datasets/{dataset_id}/features/{gid} — Delete Single FeatureGET /datasets/{dataset_id}/features/{gid} — Get Single FeaturePATCH /datasets/{dataset_id}/features/{gid} — Patch Single FeaturePUT /datasets/{dataset_id}/features/{gid} — Replace Single FeaturePOST /datasets/{dataset_id}/features/delete/ — Delete Features BatchPOST /datasets/{dataset_id}/features/dry-run/ — Dry Run Create FeatureGET /health — HealthGET /ai/availability/ — Ai Availability EndpointPOST /ai/chat/ — Chat EndpointPOST /ai/chat/dataset/stream/ — Dataset Chat Stream EndpointPOST /ai/chat/stream/ — Chat Stream EndpointPOST /ai/generate-map/ — Generate Map EndpointPOST /ai/generate-map/stream/ — Generate Map Stream EndpointPOST /ai/metadata/keywords/ — Generate Metadata KeywordsPOST /ai/metadata/lineage/ — Generate Metadata LineagePOST /ai/metadata/quality-statement/ — Generate Metadata Quality StatementPOST /ai/metadata/summary/ — Generate Metadata SummaryPOST /layers/ — Create Layer EndpointPOST /layers/{dataset_id}/columns/ — Add Column EndpointDELETE /layers/{dataset_id}/columns/{column_name} — Drop Column EndpointPATCH /layers/{dataset_id}/columns/{column_name}/name — Rename Column EndpointGET /layers/{dataset_id}/columns/{column_name}/references — Column References EndpointPATCH /layers/{dataset_id}/columns/{column_name}/type — Alter Column Type EndpointGET /maps/ — List Maps EndpointPOST /maps/ — Create Map EndpointDELETE /maps/{map_id} — Delete Map EndpointGET /maps/{map_id} — Get Map EndpointPATCH /maps/{map_id} — Patch Map EndpointPUT /maps/{map_id} — Update Map EndpointGET /maps/{map_id}/access/ — Get Map Access EndpointPOST /maps/{map_id}/duplicate/ — Duplicate Map EndpointGET /maps/{map_id}/history — Get Map History EndpointPATCH /maps/{map_id}/layers — Patch Map Layers EndpointPOST /maps/{map_id}/layers — Add Layer EndpointDELETE /maps/{map_id}/layers/{layer_id} — Remove Layer EndpointPOST /maps/{map_id}/layers/bulk-delete — Bulk Delete Layers EndpointGET /maps/{map_id}/og-image/ — Get Og ImagePUT /maps/{map_id}/og-image/ — Upload Og ImageDELETE /maps/{map_id}/share/ — Revoke Map Share EndpointGET /maps/{map_id}/share/ — Get Map Share Token EndpointPATCH /maps/{map_id}/share/ — Update Map Share Token EndpointPOST /maps/{map_id}/share/ — Share Map EndpointGET /maps/{map_id}/style.json — Export Map Style EndpointGET /maps/{map_id}/thumbnail/ — Get ThumbnailPUT /maps/{map_id}/thumbnail/ — Upload ThumbnailGET /maps/{map_id}/visibility-check/ — Visibility Check EndpointGET /maps/icons — List Map Icons EndpointPOST /maps/icons — Upload Map Icon EndpointGET /maps/icons/{icon_id}/asset — Get Map Icon Asset EndpointPOST /maps/import — Import Map Style EndpointGET /maps/shared/{token} — Get Shared Map EndpointGET /maps/sprites/geolens.json — Get Geolens Sprite Index EndpointGET /maps/sprites/geolens.png — Get Geolens Sprite Png EndpointGET / — Landing PageGET /collections — List CollectionsGET /collections/{dataset_id} — Get Dataset CollectionGET /collections/{dataset_id}/items — Get Collection ItemsGET /collections/{dataset_id}/items/{feature_id} — Get Collection Item FeatureGET /collections/{dataset_id}/queryables — Get Collection QueryablesGET /collections/datasets — Get Collection MetadataGET /collections/datasets/items — Collection ItemsGET /collections/datasets/items/{record_id} — Get Collection ItemGET /collections/datasets/queryables — Get QueryablesGET /collections/datasets/schema — Get Record SchemaGET /collections/datasets/sortables — Get SortablesGET /conformance — ConformancePOST /query/ — Run a read-only SQL queryGET /records/{record_id}/contacts/ — List Contacts EndpointPOST /records/{record_id}/contacts/ — Create Contact EndpointDELETE /records/{record_id}/contacts/{contact_id}/ — Delete Contact EndpointPATCH /records/{record_id}/contacts/{contact_id}/ — Update Contact EndpointGET /records/{record_id}/distributions/ — List Distributions EndpointPOST /records/{record_id}/distributions/ — Create Distribution EndpointDELETE /records/{record_id}/distributions/{distribution_id}/ — Delete Distribution EndpointPATCH /records/{record_id}/distributions/{distribution_id}/ — Update Distribution EndpointGET /records/{record_id}/keywords/ — List Keywords EndpointPOST /records/{record_id}/keywords/ — Create Keyword EndpointDELETE /records/{record_id}/keywords/{keyword_id}/ — Delete Keyword EndpointGET /records/{record_id}/translations/ — List Translations EndpointDELETE /records/{record_id}/translations/{language}/ — Delete Translation EndpointPUT /records/{record_id}/translations/{language}/ — Upsert Translation EndpointGET /search/datasets/ — Search Datasets EndpointGET /search/facets/ — Search Facets EndpointGET /search/saved/ — List Saved Searches EndpointPOST /search/saved/ — Create Saved Search EndpointDELETE /search/saved/{search_id} — Delete Saved Search EndpointGET /search/saved/{search_id} — Get Saved Search EndpointGET /stac/ — Landing PageGET /stac/collections — Get CollectionsGET /stac/collections/{collection_id} — Get CollectionGET /stac/collections/{collection_id}/items — Get Collection ItemsGET /stac/collections/{collection_id}/items/{item_id} — Get Collection ItemGET /stac/conformance — ConformanceGET /stac/items/{item_id} — Get ItemGET /stac/search — Search GetPOST /stac/search — Search PostPOST /services/stac/asset-sizes — Stac Asset SizesPOST /services/stac/collections — Stac CollectionsPOST /services/stac/connect — Stac ConnectPOST /services/stac/import — Stac ImportPOST /services/stac/search — Stac SearchGET /tiles/{table_path}/{z}/{x}/{y}.pbf — Tile EndpointGET /tiles/clusters/{table_path}/{z}/{x}/{y}.pbf — Cluster Tile EndpointGET /tiles/raster-proxy/{dataset_id}/{z}/{x}/{y}.{fmt} — Raster Tile ProxyGET /tiles/token/{dataset_id}/ — Get Tile TokenPOST /tiles/tokens/ — Get Tile Tokens Batch