generated: '2026-07-27' method: derived source: >- live ArcGIS REST service and layer metadata (?f=json) captured 2026-07-27 into examples/, the OGC WFS 2.0.0 GetCapabilities documents in wfs/, and observed responses from the KISTERS hydrological JSON tree docs: null docs_note: >- Manitoba Hydro documents none of this. Every convention below was read off the live service metadata that the hosting platforms (Esri ArcGIS and KISTERS WISKI Web Public) generate. The conventions are therefore the platforms' conventions, not conventions Manitoba Hydro authored or committed to. surfaces: - id: arcgis-rest label: Esri ArcGIS REST Feature Service (hosted + on-premise) hosts: - services2.arcgis.com/QoeQkfdOG126FqSi - maps.hydro.mb.ca/arcgis - id: ogc-wfs label: OGC Web Feature Service 2.0.0 hosts: - dservices2.arcgis.com/QoeQkfdOG126FqSi - id: kisters-json label: KISTERS WISKI Web Public static JSON hosts: - www.hydro.mb.ca/hydrologicalData/static/data authentication: style: none detail: see authentication/manitoba-hydro-authentication.yml content_negotiation: mechanism: query parameter, not Accept header arcgis_rest: parameter: f values: [json, geojson, pbf, html] evidence: 'layer metadata supportedQueryFormats: "JSON, geoJSON, PBF"' default_without_parameter: html ogc_wfs: parameter: outputFormat default: GML 3.2 (application/gml+xml; version=3.2) kisters_json: parameter: none note: static .json files; the parallel .html and .o.html renderings are separate files service_level_export_formats: evidence: 'FeatureServer supportedExportFormats' values: [csv, shapefile, sqlite, geoPackage, filegdb, featureCollection, geojson, kml, excel] pagination: style: offset supported: true evidence: 'layer advancedQueryCapabilities.supportsPagination = true' parameters: - name: resultOffset description: Zero-based index of the first record to return. - name: resultRecordCount description: Number of records to return in this page. response_fields: - name: exceededTransferLimit description: >- Boolean present on every query response. True means the result set was truncated by maxRecordCount and the caller must page with resultOffset. page_size: max_record_count: 2000 standard_max_record_count: 2000 note: >- Both outage layers report maxRecordCount 2000 and standardMaxRecordCount 2000. The parent FeatureServer reports maxRecordCount 1000. Treat 1000 as the safe page size. Counting without paging is available via returnCountOnly=true. ogc_wfs: parameters: [count, startIndex] note: WFS 2.0.0 native paging; the ArcGIS WFS implementation honours both. kisters_json: supported: false note: >- Each parameter file (1.json .. 15.json) is a complete snapshot of every reporting station for that parameter. Water Level returned 158 stations in a single 117 KB document. There is no paging and no incremental fetch. filtering_and_projection: where: parameter: where description: SQL-92 predicate against layer attributes; use where=1=1 for all rows. evidence: 'advancedQueryCapabilities.supportsSqlExpression = true' field_selection: parameter: outFields description: Comma-separated attribute list, or * for all. geometry_suppression: parameter: returnGeometry description: returnGeometry=false returns attributes only — much smaller payloads. ordering: parameter: orderByFields evidence: 'advancedQueryCapabilities.supportsOrderBy = true' distinct: parameter: returnDistinctValues evidence: 'advancedQueryCapabilities.supportsDistinct = true' statistics: parameter: outStatistics evidence: 'advancedQueryCapabilities.supportsStatistics = true' spatial: parameters: [geometry, geometryType, spatialRel, inSR, outSR, distance, units] note: >- Native spatial reference is EPSG:26914 (NAD83 / UTM zone 14N) on the outage services. Pass outSR=4326 to get WGS84 lon/lat. idempotency: supported: false reason: >- Every catalogued operation is a read. The ArcGIS feature services advertise capabilities "Query" only — no create, update, delete, or applyEdits — and the KISTERS files are static. There is no unsafe operation to make idempotent, so no Idempotency-Key contract exists and none is needed. All reads are naturally idempotent. request_tracing: request_id_header: none note: >- No X-Request-Id, X-Correlation-Id, or equivalent was observed on any response. There is no support channel to quote a request id to. versioning: arcgis_rest: scheme: platform version reported in metadata, not in the URL path hosted_current_version: 12 on_premise_current_version: '10.91' note: >- currentVersion is Esri's platform release, not a Manitoba Hydro API version. There is no v1/v2 path segment, no version header, and no published version policy. Service and layer names are the only stable identifiers, and Manitoba Hydro has made no commitment to keep them stable. ogc_wfs: scheme: query parameter parameter: version current: 2.0.0 note: The only formally versioned contract Manitoba Hydro exposes. kisters_json: scheme: none note: >- File paths carry no version. An older parallel tree at /hydrologicalData/data/ is still served but frozen at February 2021 readings — a silent, undocumented fork of the same surface. Only the /static/ tree is current. error_envelope: format: vendor JSON (ArcGIS) and OGC XML (WFS) — RFC 9457 problem+json is not used detail: see errors/manitoba-hydro-problem-types.yml rate_limiting: published_limits: none headers: none detail: >- No X-RateLimit-*, RateLimit-*, or Retry-After headers were observed and no rate limit is published anywhere. The only hard ceiling in evidence is the per-request record cap (maxRecordCount 1000-2000), which is a result-size limit rather than a request-rate limit. www.hydro.mb.ca sits behind an F5 web application firewall that will reject requests that do not look like a browser — treat that as the practical throttle on the hydrological tree. courtesy_guidance: >- Source data refreshes every five minutes (Manitoba Hydro's own ArcGIS item description for the planned outages layer). Polling faster than that gains nothing. caching_and_freshness: refresh_interval: 5 minutes (outage layers, per the provider's item description) freshness_field: DATA_LAST_UPDATE (epoch milliseconds, on both outage layers) conditional_requests: not advertised note: >- Timestamps on the ArcGIS layers are epoch milliseconds in UTC, not ISO 8601 strings. The KISTERS files carry human-formatted local timestamps wrapped in a element inside the field value — parse the sort attribute, not the display text. payload_quirks: - surface: arcgis-rest quirk: >- Date fields are returned as epoch milliseconds integers (TIME_OF_OUTAGE, ETR, DATA_LAST_UPDATE, SCHEDULED_START_TIME, SCHEDULED_END_TIME). - surface: arcgis-rest quirk: >- Fixed-width string fields are space-padded to their declared length (DEVICE_ADDRESS observed as "183 KENNEDY ST" followed by trailing spaces). Trim before comparing. - surface: arcgis-rest quirk: >- Customer counts appear twice — NUM_CUST_NOPOWER (integer) and NUM_CUST_NOPOWERTXT (banded string such as "Less than 5"). The banded string is what the public outage map shows. - surface: kisters-json quirk: >- Observation records use positional attribute keys "0".."7" whose meaning is declared in the sibling fields[] array of the same document. Values are HTML fragments — station name arrives wrapped in an tag carrying an internal station id, numeric values arrive wrapped in . There is no clean machine field; every value needs unwrapping. - surface: kisters-json quirk: >- Parameters are addressed by integer pid (1 = Water Level, 3 = Air Temperature, ...) resolved through tsdata.json; station metadata lives in a separate 855 KB stationdata.json keyed by station number. cross_links: authentication: authentication/manitoba-hydro-authentication.yml errors: errors/manitoba-hydro-problem-types.yml lifecycle: lifecycle/manitoba-hydro-lifecycle.yml conformance: conformance/manitoba-hydro-conformance.yml data_model: data-model/manitoba-hydro-data-model.yml examples: examples/