Skip to content

dhis2/api-types

@dhis2/api-types

TypeScript types for the DHIS2 REST API, generated from the official OpenAPI specification.

Covers the last four supported DHIS2 API versions: v40, v41, v42, v43.

Installation

npm install --save-dev @dhis2/api-types

Usage

Import types directly by name, or use the components["schemas"] namespace:

// Named imports — every schema in the spec is exported directly
import type { DataElement, OrganisationUnit, ValueType } from "@dhis2/api-types"

// Namespace imports — useful when you need paths/operations types too
import type { components, paths } from "@dhis2/api-types"
type DataElement = components["schemas"]["DataElement"]  // identical to the named import

// Pin to a specific DHIS2 version (default resolves to latest, currently v43)
import type { DataElement } from "@dhis2/api-types/v42"

// Endpoint request/response types (only available via namespace)
type GetDataElementsParams = paths["/dataElements"]["get"]["parameters"]
type DataElementResponse =
    paths["/dataElements"]["get"]["responses"][200]["content"]["application/json"]

Pair with openapi-fetch for fully type-safe API calls:

import createClient from "openapi-fetch"
import type { paths } from "@dhis2/api-types"  // paths is only in the namespace import

const client = createClient<paths>({ baseUrl: "https://play.dhis2.org/api" })

const { data } = await client.GET("/dataElements", {
    params: { query: { fields: "id,name,valueType" } },
})

Utility types

Import from @dhis2/api-types/utils for version-agnostic helpers that work with any version's schemas.

GistModel<T>

Types a response from DHIS2's /api/*.json?type=gist endpoint, which reduces payload size by collapsing the response:

  • Array fields (collections) → number (the total count)
  • Object fields (references and embedded objects) → string (the href or serialised value)
  • Scalar fields (string, number, boolean, enums) → unchanged
import type { components } from "@dhis2/api-types/v43"
import type { GistModel } from "@dhis2/api-types/utils"

type DataElement = components["schemas"]["DataElement"]
type DataElementGist = GistModel<DataElement>

// dataElementGroups: BaseIdentifiableObject[]  →  number  (count)
// categoryCombo:     IdentifiableObject        →  string  (href)
// name:              string                    →  string  (unchanged)
// aggregationType:   AggregationType           →  AggregationType  (enum preserved)

PickWithFieldFilters<T, Filters>

Narrows a model type to exactly the fields requested in a ?fields= query, including nested fields using bracket notation. Each entry in the array is one top-level field specifier.

import type { components } from "@dhis2/api-types/v43"
import type { PickWithFieldFilters } from "@dhis2/api-types/utils"

type DataElement = components["schemas"]["DataElement"]

// Flat pick — mirrors ?fields=id,name,valueType
type DEFlat = PickWithFieldFilters<DataElement, ["id", "name", "valueType"]>
// → { id?: string; name?: string; valueType?: ValueType }

// Nested pick — mirrors ?fields=id,categoryCombo[id,name]
type DEWithCombo = PickWithFieldFilters<DataElement, ["id", "categoryCombo[id,name]"]>
// → { id?: string; categoryCombo?: { id?: string; name?: string } }

// Array field nested pick — mirrors ?fields=status,dataValues[dataElement,value]
type EventPick = PickWithFieldFilters<
    components["schemas"]["Event"],
    ["status", "dataValues[dataElement,value]"]
>
// → { status: EventStatus; dataValues?: Array<{ dataElement?: string; value?: string }> }

Note: Nested picks only resolve fields that exist on the declared type. Reference fields like categoryCombo are typed as IdentifiableObject (with id, name, code, etc.), not the full concrete type. Deeper fields unavailable on IdentifiableObject (e.g. categories within a CategoryCombo) are silently dropped. See ADR 0001 for background.

Available versions

Import path DHIS2 version
@dhis2/api-types DHIS2 2.43 (latest)
@dhis2/api-types/v43 DHIS2 2.43
@dhis2/api-types/v42 DHIS2 2.42
@dhis2/api-types/v41 DHIS2 2.41
@dhis2/api-types/v40 DHIS2 2.40

Versioning

The package major version tracks the latest included DHIS2 API version. When DHIS2 v44 ships:

  • v44 is added, v40 is dropped
  • Package version bumps to 44.x.y

Pin to a major version to avoid unexpected API version drops:

"@dhis2/api-types": "^43.0.0"

Maintaining this package

Prerequisites

Secrets required in GitHub Actions:

  • NPM_TOKEN — npm publish token with access to the @dhis2 org
  • DHIS2_USERNAME / DHIS2_PASSWORD — credentials for the DHIS2 Play servers (defaults: admin / district)

Updating types

Types are generated from OpenAPI spec snapshots stored in specs/. The specs are fetched from DHIS2 Play servers. Never hand-edit the files in src/.

# Fetch fresh specs for all versions and regenerate types
npm run update

# Or step by step
npm run fetch-specs             # updates specs/vN.json
npm run generate                # regenerates src/vN.d.ts

# Target a single version
npm run fetch-specs -- --version v42 --force
npm run generate -- --version v42

Publishing

The publish workflow runs on two triggers, intentionally different:

Stable releases — tag-based, manual. Pushing a v* tag from any branch publishes to the latest dist-tag on npm. The version in package.json is used as-is. This requires a deliberate action, which is the point — stable releases affect everyone who runs npm install @dhis2/api-types and should never happen by accident.

# Bump the version, commit, then tag and push
npm version patch          # or minor / major
git push && git push --tags

Prerelease channels — branch-based, automatic. Any push to the beta or alpha branches immediately publishes to the matching dist-tag on npm. The version is auto-generated as {base}-{channel}.{short-sha} (e.g. 43.0.0-beta.abc1f3a) so every commit produces a unique, traceable package version without any manual version management.

# Make changes on the beta branch — publishing is automatic on push
git checkout beta
git merge my-feature-branch
git push
# → publishes 43.0.0-beta.abc1f3a to npm@beta

Consumers opt into a channel explicitly:

npm install @dhis2/api-types          # stable, unaffected by prerelease activity
npm install @dhis2/api-types@beta     # latest beta build
npm install @dhis2/api-types@alpha    # latest alpha build

Why this split is a good compromise. Stable releases carry real weight — a bad publish to latest breaks every downstream project that runs npm install. Tag-based publishing forces a deliberate decision: someone has to run git tag, review what they're shipping, and push the tag intentionally. That friction is a feature, not a bug.

Prerelease channels are the opposite: speed and low ceremony matter more than caution. A branch-based trigger means merging a PR to beta is all it takes to make types available for integration testing — no context-switching to create a tag, no deciding on a prerelease version number. The SHA-stamped version also means you can always trace a @beta install back to the exact commit it came from.

The result: latest stays stable and trustworthy, while beta and alpha move fast and stay current with in-progress work.

Releasing a new stable version

  1. Run npm run update and review the diff in specs/ and src/
  2. Bump the version in package.json (npm version patch|minor|major)
  3. Commit, push, then tag:
git push && git push --tags

The regenerate workflow also runs monthly on a schedule and opens a PR automatically if any specs have changed.

Adding a new DHIS2 API version

  1. Add an entry to scripts/versions.ts
  2. Add the new version to package.json exports and typesVersions; remove the oldest
  3. Update src/latest.d.ts to re-export the new version
  4. Update the publish workflow's type check list
  5. Run npm run update

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors