Web Feature Service (WFS) Endpoints
Programmatic access to vector feature data using OGC WFS 2.0.0 standard. Retrieve, query, and update geospatial features via HTTP.
This documentation covers WFS 2.0.0 (XML & JSON profiles). WFS-T (Transactions) requires elevated privileges. Ensure your API key has `wfs:read` or `wfs:write` scopes.
Base URL & Versioning
All WFS requests must be made to the following base endpoint:
https://api.geoserver.io/wfs
Specify the service version using the VERSION parameter. We strongly recommend 2.0.0 for improved JSON support, filtering, and performance.
| Parameter | Type | Required | Description |
|---|---|---|---|
SERVICE | string | Yes | Must be WFS |
VERSION | string | Yes | 2.0.0 (recommended) or 1.1.0 |
REQUEST | string | Yes | Operation name (e.g., GetFeature) |
Authentication
All endpoints require authentication. Pass your API key via HTTP headers or query parameters:
Authorization: Bearer YOUR_API_KEY
// OR via query string (less secure)
https://api.geoserver.io/wfs?api_key=YOUR_API_KEY&...
For WFS-T (POST requests), authentication must be passed via the Authorization header or session cookie. Basic Auth is deprecated as of v2.4.
Core Operations
| Operation | Method | Description |
|---|---|---|
GetCapabilities | GET | Returns service metadata, available workspaces, layers, and limits. |
DescribeFeatureType | GET | Returns XSD schema for specified feature types. |
GetFeature | GET/POST | Retrieves feature geometries and attributes. |
Transaction | POST | Insert, update, or delete features (WFS-T). Requires write scope. |
Request Examples
1. Retrieve Features (JSON)
Fetch the first 50 features from the hydro:lakes layer as GeoJSON:
GET https://api.geoserver.io/wfs?
SERVICE=WFS&
VERSION=2.0.0&
REQUEST=GetFeature&
TYPE=hydro:lakes&
OUTPUTFORMAT=application/json&
COUNT=50&
SRSNAME=EPSG:4326
# Headers: Authorization: Bearer <key>
2. Spatial Filter (BBOX)
Query features within a bounding box:
GET https://api.geoserver.io/wfs?
SERVICE=WFS&
VERSION=2.0.0&
REQUEST=GetFeature&
TYPE=boundaries:us_states&
BBOX=-124.85,24.46,-66.95,49.38,EPSG:4326&
OUTPUTFORMAT=application/json
3. Advanced Filter (CQL)
Use Common Query Language to filter by attributes:
GET https://api.geoserver.io/wfs?
SERVICE=WFS&
VERSION=2.0.0&
REQUEST=GetFeature&
TYPE=transport:roads&
CQL_FILTER=CLASS='highway' AND LENGTH > 100&
OUTPUTFORMAT=application/json
4. Transaction (Insert)
POST XML payload to insert a new feature:
<wfs:Transaction service="WFS" version="2.0.0">
<wfs:Insert>
<feature:parcel xmlns:feature="http://geo.geoserver.io/parcel">
<feature:id>PAR-8842</feature:id>
<feature:geom><gml:Polygon srsName="EPSG:4326">
<gml:outer><gml:LinearRing>
<gml:coordinates>-73.9,40.7;-73.8,40.7;-73.8,40.8;-73.9,40.7</gml:coordinates>
</gml:LinearRing></gml:outer>
</gml:Polygon></feature:geom>
</feature:parcel>
</wfs:Insert>
</wfs:Transaction>
Supported Output Formats
Specify via the OUTPUTFORMAT parameter:
| MIME Type | Format | Notes |
|---|---|---|
application/json | GeoJSON | Recommended for web clients & APIs |
application/vnd.ogc.gml+xml | GML 3.2 | OGC standard, full type fidelity |
text/xml | GML 2.1 | Legacy support (WFS 1.1.0) |
application/vnd.google-earth.kml+xml | KML | Google Earth / Earth Pro compatible |
text/csv | CSV | Attribute-only export (no geometry) |
Rate Limits & Best Practices
- Read Requests: 100 req/min per API key (Starter), 1,000 req/min (Professional), Unlimited (Enterprise)
- Transaction Requests: 10 req/min (Professional), 100 req/min (Enterprise)
- Pagination: Use
STARTINDEXandCOUNTinstead of fetching entire datasets - Caching: Responses are cacheable by default. Override with
Cache-Control: no-cacheif data changes frequently - Geometry Simplification: Add
SIMPLIFY=true&TOLERANCE=0.0001to reduce payload size for large datasets
Always request only the attributes you need using the PROPERTYNAME parameter. Fetching geometry alone reduces response size by up to 70% for attribute-heavy layers.