OGC API & Standards Endpoints
Ce contenu n’est pas encore disponible dans votre langue.
GeoLens implements several OGC and STAC standards alongside its REST API. This page covers the standards-based endpoints. Reach for the auto-generated reference for per-route schemas, request/response bodies, and the full conformance-class list.
Replace https://geolens.example.com with your GeoLens instance’s URL in every
example below. Authentication follows the same rules as the rest of the API.
See API Authentication for X-Api-Key, JWT, and OAuth
options.
OGC API - Common
Section titled “OGC API - Common”Provides the OGC API root, conformance declaration, and OpenAPI definition. Every OGC API client begins here.
Endpoints:
GET /api/: landing document with links to conformance, collections, and OpenAPI.GET /api/conformance: list of conformance class URIs (Records, Features, CQL2, etc.).GET /api/openapi.json: full OpenAPI definition.
Curl:
curl https://geolens.example.com/api/curl https://geolens.example.com/api/conformanceKeep the trailing slash on the landing page URL. A bare /api answers with a
301 instead of the landing document. The redirect carries no CORS header, so a
browser client drops it, and behind a reverse proxy its Location can name
the proxy’s internal port, so QGIS and other desktop clients pointed at /api
can get an error box instead of a collection list.
For the full schema of every endpoint, see the Endpoints by Tag section in the auto-generated reference.
OGC API - Records
Section titled “OGC API - Records”The catalog itself is exposed as an OGC API Records collection at
collections/datasets. Use this to list, filter, and discover datasets
programmatically.
Endpoints:
GET /api/collections/datasets/items: list catalog records (paginated, CQL2-filterable).
Curl:
curl https://geolens.example.com/api/collections/datasets/itemsCQL2 filter (one example):
curl 'https://geolens.example.com/api/collections/datasets/items?filter=title%20LIKE%20%27%25hydrology%25%27&filter-lang=cql2-text'The properties you can filter on are listed at
/api/collections/datasets/queryables. The CQL2 grammar itself is advertised
in /api/conformance (look for the cql2-text, cql2-json, and basic-cql2
conformance classes).
QGIS MetaSearch (built-in plugin):
1. Web > MetaSearch > MetaSearch (built-in, no install)2. Services tab > New3. Name: GeoLens URL: https://geolens.example.com/api/ Catalog Type: OGC API - Records4. Save -> Search tab to query records.GDAL ogr2ogr / ogrinfo (OAPIF driver):
ogrinfo OAPIF:https://geolens.example.com/api/OGC API - Features
Section titled “OGC API - Features”Per-dataset feature access for vector layers. Useful for exporting subsets to GeoPackage, Shapefile, or any GDAL-supported format.
Use Features when the result is small or bounded, when the client needs
attributes, or when it loads by viewport or filter. Use
vector tiles when the dataset is large and users pan across
all of it; the server then cuts tiles per request and the client holds only
what is on screen. A viewport loader that pages this endpoint by bbox and
follows next is in the examples gallery:
maplibre/features-viewport.html.
Endpoints:
GET /api/collections/{dataset_id}/items: feature items for a single dataset (bbox and datetime filterable). A CQL2filteris supported only on the catalogcollections/datasets/itemscollection; passingfilterhere returns HTTP 400.
Curl:
curl https://geolens.example.com/api/collections/{dataset_id}/itemsPaging. Every response carries numberMatched (what the query found) and
numberReturned (what this page holds). When they differ you are holding a
partial result. The loop condition is the rel="next" link, not the counts:
follow it until it stops appearing. Paging is keyset-based (after_gid=), so
rows do not shift under a reader mid-scan. limit is clamped silently to the
instance’s ogc_items_max_page_size (default 1000; see
Settings -> Network), and the self link
echoes the value that was applied.
QGIS Add Layer > OGC API Features:
1. Layer > Add Layer > Add WFS / OGC API Features Layer...2. New connection: Name: GeoLens URL: https://geolens.example.com/api/ Version: OGC API - Features3. Private instance: under Authentication > Configurations, click +, choose method "API Header", add header X-Api-Key = <your-api-key>, save, and select that configuration on the connection.4. Connect -> pick collection -> Add.The authentication configuration lives in QGIS’s encrypted auth database, not
in the .qgz, and the same configuration can be reused on the XYZ and vector
tile connections below. The catalog itself appears in the collection list as
datasets (the Records collection); add it like any other layer to browse
records in the attribute table. QGIS pushes a CQL2 filter to the server only
when the conformance page advertises the OGC API Features Part 3 filter
classes, which GeoLens 1.14.0 does not, so a Build query filter on the
datasets layer is evaluated client-side. A longer walkthrough with
screenshots and a ready-made project is at
qgis/README.md
in the examples repo.
ArcGIS Pro (New OGC API Server connection):
1. Insert ribbon > Connections > Server > New OGC API Server2. Server URL: https://geolens.example.com/api/?api_key=<your-api-key>3. OK — the connection appears in the Catalog pane under Servers.4. Expand the connection and drag a collection onto the map.ArcGIS Pro speaks OGC API Features natively (Pro 2.8 or newer). As with the
ogr2ogr example, the ?api_key= query parameter rides along on every
request the connection makes; omit it entirely for anonymous access to public
datasets. In the ArcGIS Maps SDK for JavaScript, OGCFeatureLayer takes the
same landing page URL plus a collectionId; see
arcgis-js/features.html
for a runnable page that shows the request interceptor for sending X-Api-Key.
GDAL export to GeoPackage:
ogr2ogr -f GPKG out.gpkg \ "OAPIF:https://geolens.example.com/api/?api_key=<your-api-key>" \ {dataset_id}The ?api_key= query parameter is the recommended way to authenticate
ogr2ogr, since the OAPIF driver does not currently let you set HTTP headers.
That query lane is deprecated for every client that can set a header
(geolens#821): a key in a
URL lands in access and proxy logs. Prefer X-Api-Key wherever the tool
allows it.
STAC 1.0
Section titled “STAC 1.0”GeoLens exposes raster collections (and their items) under a STAC 1.0 catalog
rooted at /api/stac/. Use any STAC client to search and ingest assets. A
browser-side search that draws the matching footprints and tiles is in the
examples gallery:
stac/browse.html.
Endpoints:
GET /api/stac/: STAC root catalog.GET /api/stac/collections: list of STAC collections.GET /api/stac/searchandPOST /api/stac/search: full STAC search (bbox, datetime, collections, intersects, ids). GET takes the parameters as a query string; POST takes the same fields as a JSON body.datetimeis an RFC 3339 instant (2026-08-12T15:53:30Z) or an intervalstart/end, with..for an open end (2026-01-01T00:00:00Z/..); bare dates are rejected with 400 (pystac-client accepts bare dates and normalizes them before sending).
Curl:
curl https://geolens.example.com/api/stac/curl 'https://geolens.example.com/api/stac/search?bbox=-122.5,37.5,-122.0,38.0&limit=10'pystac-client:
from pystac_client import Client
client = Client.open("https://geolens.example.com/api/stac/")search = client.search( collections=["my-raster-collection"], bbox=[-122.5, 37.5, -122.0, 38.0], datetime="2024-01-01T00:00:00Z/2024-12-31T23:59:59Z",)for item in search.items(): print(item.id, item.assets["raster_tiles"].href)Every raster item carries a raster_tiles asset whose href is an absolute
XYZ tile template ending in
/raster-tiles/{dataset_id}/tiles/{z}/{x}/{y}.png?v=<n>; pass it through to a
map client as is, including the ?v= cache version. That works unchanged for
a public item. For a private item (one an authenticated search returned) the
template carries no credential, so either send X-Api-Key with each tile
request or mint a signed tile_url from GET /api/tiles/token/{dataset_id}/
(see Tile endpoints). On local storage raster_tiles is
the only asset. On S3-backed instances a published dataset also advertises
data (the COG, as a presigned URL valid for an hour), thumbnail, and
overview.
Tile endpoints
Section titled “Tile endpoints”GeoLens serves vector and raster tiles. Public, published datasets serve tiles to anyone with no token. Private datasets serve them via signed access tokens, which are not generic API keys: they are HMAC-signed, scoped to a single dataset, and time-limited. They exist so that a map client whose tile URL template cannot carry a header can still read a private layer without exposing a permanent credential to the browser. The examples gallery has runnable pages for both.
Vector tile (MVT) URL shape:
https://geolens.example.com/api/tiles/{table_path}/{z}/{x}/{y}.pbf?sig={sig}&exp={exp}&scope={scope}{table_path} is the schema-qualified table name (data. plus the
table_name that GET /api/datasets/{id} reports, e.g. data.my_table), and
sig, exp, and scope are the HMAC-signed parameters returned by
GET /api/tiles/token/{dataset_id}/. Omit all three for a public dataset.
Raster tile URL shape:
https://geolens.example.com/raster-tiles/{dataset_id}/tiles/{z}/{x}/{y}.png?v=<n>Raster tiles live at the site root, not under /api/. Read the template from
the collection’s rel="tiles" link on GET /api/collections/{dataset_id}
(or from the STAC item’s raster_tiles asset) rather than building it by hand:
the ?v= cache-version parameter matters, because a raster replace bumps it
and a hand-built URL keeps serving the old cache entry. For a private raster
the token response’s tile_url is the same template with sig, exp, and
scope already appended. A tile outside the dataset’s footprint answers 204
(draw nothing); a dataset that does not exist answers 404 from v1.14.0 (older
releases answered 204 for both). The /api/tiles/raster-proxy/... route in
the auto-generated reference is what nginx forwards /raster-tiles/ to, and
the fallback for a deployment without nginx; prefer the /raster-tiles/
template.
Obtaining a tile token.
GET /api/tiles/token/{dataset_id}/: mint a token for one dataset. Vector datasets returnsig,exp,scope, andexpires_in; raster datasets return those plus a ready-to-usetile_urland the layer’sbounds,minzoom, andmaxzoom.POST /api/tiles/tokens/: the batch form, up to 50 dataset IDs in one request. Per-dataset failures come back as{"error": ...}entries without failing the batch.
Minting is authorized by dataset visibility. A public, published dataset mints
anonymously; a private one answers an anonymous mint with 401, so a static
page holding no credential cannot mint its own token for private data.
Something server-side has to hold the key and hand tokens down. The endpoints
accept the same authentication as the rest of the API (X-Api-Key, JWT,
OAuth-issued JWT). Tile tokens themselves are not substitutes for those
credentials. They are derived, scoped, and expire.
exp is always a 15-minute boundary, usually the next one. When that boundary
is under a minute away the mint skips to the following one, so a fresh token
carries anywhere from 60 seconds to just under 16 minutes. Read expires_in
off the response rather than assuming a fixed TTL, and re-mint before it
passes: map clients keep requesting whatever template you handed them.
Embed tokens are not tile tokens. X-Embed-Token is minted per map by an
authenticated owner, and the tile routes read it from the request header
only, so it cannot ride along in a URL template in place of a tile token.
QGIS Add XYZ Tiles (raster):
QGIS’s XYZ Tiles connection is raster-only. Point it at the .png template:
1. Browser panel > XYZ Tiles > Right-click -> New Connection...2. Name: GeoLens - <dataset> URL: https://geolens.example.com/raster-tiles/{dataset_id}/tiles/{z}/{x}/{y}.png?v=<n>3. Private dataset: select the API Header authentication configuration (X-Api-Key) described under OGC API Features above, or paste the token response's tile_url (origin prefixed) as the URL.4. Click OK, then drag the connection onto the canvas.QGIS Add Vector Tile Layer (MVT):
1. Layer > Add Layer > Add Vector Tile Layer...2. New > New Generic Connection... Name: GeoLens - <dataset> URL: https://geolens.example.com/api/tiles/{table_path}/{z}/{x}/{y}.pbf3. Private dataset: select the same API Header authentication configuration, or append ?sig=<sig>&exp=<exp>&scope=<scope> from GET /api/tiles/token/{dataset_id}/ to the URL.4. Click OK, then add the connection.A pasted token is a session credential: it expires within 16 minutes, which suits a quick share and not a project you open next week. For a working session use the authentication configuration.
MapLibre GL JS (vector tile source):
The MVT layer name inside each tile is the same schema-qualified {table_path}
as in the URL — use it as the source-layer:
map.addSource('geolens-roads', { type: 'vector', tiles: [ 'https://geolens.example.com/api/tiles/data.roads/{z}/{x}/{y}.pbf?sig=<sig>&exp=<exp>&scope=<scope>', ],});
map.addLayer({ id: 'roads-line', type: 'line', source: 'geolens-roads', 'source-layer': 'data.roads', paint: { 'line-color': '#3b6fd4', 'line-width': 1.5 },});Because tile tokens expire, a long-lived custom MapLibre app should mint a
fresh token via GET /api/tiles/token/{dataset_id}/ (or the batch POST)
and rebuild the source URL when one lapses. For a zero-code alternative,
GeoLens’s built-in share embeds handle tokens for you; see
Map Builder.
A runnable version of this snippet with error handling is
maplibre/vector-tiles.html
in the examples gallery; the raster-tile pages there cover MapLibre, Leaflet,
OpenLayers, and the ArcGIS Maps SDK for JavaScript. The ArcGIS WebTileLayer
takes the same raster template with {level}/{col}/{row} in place of
{z}/{x}/{y}; see
arcgis-js/imagery.html.