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.
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.
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.
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"} 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 is specifically an upload that was never started: a
presigned URL was handed out and the bytes never arrived. 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.
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 LIMIT 5", "restrict_tables": ["world_countries"], "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 the reason phrase for that status. 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.
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.
Two failures skip 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. The global
rate-limit rejection has its own shape too; see Rate limits.
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. Every value below is an admin setting (Network tab), so an instance you do not run may be tuned differently — these are the shipped defaults.
| Limit | Default | Applies to |
|---|---|---|
| Global | 60/second | every route without its own limit |
| Login | 5/minute | POST /auth/login |
| Semantic search | 30/minute | /search/datasets/, /datasets/{id}/related/ |
| Basemap list | 120/minute | GET /settings/basemaps/ |
| SQL sandbox | 30/minute per user, 60/minute per IP | POST /query/ |
A route that declares its own limit is exempt from the global one, so the two never stack.
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 is enforced once per worker rather than once for the instance.
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 a per-route limit 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+jsonOver the global limit the answer is thinner: a 429 with
Content-Type: application/json, a body of
{"error": "Rate limit exceeded: 60 per 1 second"}, and no Retry-After. That
window is one second, so a caller that hits it should pause about a second and
resume, rather than looking for a header that will not be there. Treat any 429
as back-off; read Retry-After when present and fall back to your own delay
when it is not, 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.
One limit lives outside the API: the bundled frontend nginx, which is the
application edge in the standard deployment, throttles anonymous raster tile
requests at /raster-tiles/... to 600/minute per IP with a burst of 200. It
answers with a 503 rather than a 429, and the body is nginx’s, not the
API’s.
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 LoginGET /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}/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 RunsGET /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 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 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/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