Skip to content
worldgovdata
Documentation / Reference

Reference

OpenAPI

The API publishes a machine-readable schema, generated from the running code, and serves an interactive reference built from it.

Two addresses: one to read in a browser, one to feed to a generator.

The two addresses

Interactive reference

https://api.worldgovdata.com/docs

Swagger UI. Browse every route and its schema, and issue requests from the page.

Schema

https://api.worldgovdata.com/data/api/openapi.json

OpenAPI JSON, generated from the running application. Feed this to a generator.

https://api.worldgovdata.com/docs is a redirect; the reference itself is served at https://api.worldgovdata.com/data/api/docs. Either works — the short form is the one worth remembering.

Download the schema

curl -sS https://api.worldgovdata.com/data/api/openapi.json -o worldgovdata-openapi.json

Fix the path prefix first

So before you generate anything, do one of these two things:

  • Rewrite the paths. Strip the leading /data/api from every key under paths, then point the generated client at https://api.worldgovdata.com/v1.
  • Or add a server. Insert a servers entry so the generator has an absolute base to work from, and rewrite the paths to match it.

One command

# Strip the internal prefix and pin the public base. Requires jq.
curl -sS https://api.worldgovdata.com/data/api/openapi.json \
  | jq '.servers = [{"url": "https://api.worldgovdata.com/v1"}]
        | .paths |= with_entries(.key |= sub("^/data/api/v1"; ""))' \
  > worldgovdata-openapi.json

The result has absolute-based paths of the form /countries, /indicators, /data — which is what every generator expects.

Add the Authorization header yourself

Authentication is applied as middleware rather than as a per-route dependency, so it does not appear in the generated schema as a security scheme. A client generated from the file as published will therefore not send the Authorization header, and every metered call it makes will come back 401 unauthorized.

This is a two-line fix in any generator: set a default header on the client, or declare the scheme in the schema before generating.

What to merge in

{
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer" }
    }
  },
  "security": [ { "bearerAuth": [] } ]
}

Which routes need it is on the endpoint index: the free catalogue routes answer without a key, and everything that returns observation rows requires one.

What the schema does not tell you

An OpenAPI document describes shapes. Everything that makes this a metered API lives outside it, and none of it can be inferred from the file:

  • Credit cost. Not in the schema. Credits has the per-route table.
  • Rate limits and the response headers. Not in the schema. Rate limits.
  • The error codes. The schema knows a route can fail; it does not enumerate display_only or insufficient_credits. Errors.
  • Licence obligations. Licensing.
  • Response bodies are loosely typed. The routers return dictionaries assembled from SQL, so the schema describes most responses as open objects rather than field by field. The field-level documentation is on these pages, written against the source.

Generating a client

After the two fixes above, the file works with the usual tools. Pick whichever your ecosystem already uses.

Common generators

Pick one

# TypeScript types only — no runtime, no client
npx openapi-typescript worldgovdata-openapi.json -o wgd-api.d.ts

# Full client, most languages
openapi-generator-cli generate \
  -i worldgovdata-openapi.json \
  -g python \
  -o ./wgd-client

# Go
oapi-codegen -package wgd worldgovdata-openapi.json > wgd/client.go

Versioning

The schema tracks the deployed code, so it changes when the API does. Within /v1 those changes are additive: new routes, new optional parameters, new fields in a response. Nothing is removed or renamed, so a client generated today keeps working. A breaking change would arrive as /v2, alongside its own schema.

Two consequences for a generated client: pin the schema file you generated from rather than fetching it at build time, and ignore unknown response fields rather than failing on them — a strict decoder turns an additive change into an outage.

Next