An official developer portal of the Government of the Republic of Zambia · Test environmentVerify a certificate
Pamodzi Developer HubBuild, integrate and learn the e-Services framework

GSB e-Services partner API

Version 1.0.0 25 operations Download the OpenAPI file

Authenticate with OAuth 2.0 client credentials: POST /oauth/token with your client ID and secret (HTTP Basic or form fields) to get a 15-minute bearer token, then call the API with Authorization: Bearer <token>. Each client has its own scopes, MDA and register scope, address allow-list, per-minute rate limit and daily quota; 429 answers carry Retry-After. Errors are RFC 7807 problem documents with a stable code and a requestId. Webhooks are signed: X-GSB-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. Reject a message whose t is more than 5 minutes old; during a secret rotation two v1 values are sent and either may match. Deliveries are at least once: drop duplicates by the event id.

Base address: /api/v1

Authentication

POST /oauth/token

Get an access token (client credentials)

No authentication.

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json TokenResponse
400

Unsupported grant type.

application/json OAuthError
401

Unknown client, wrong secret, or the client is not active.

application/json OAuthError
403

The address is not on the client's allow-list.

application/json OAuthError
429

Too many failed attempts from this address.

application/json OAuthError
500

Server error.

application/json OAuthError

GET /me

The calling client, its scopes and limits

Authentication: clientCredentials

Responses

StatusDescriptionBody
200

OK

application/json Me
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Catalogue

GET /services

Published services

Authentication: clientCredentials: services:read

Parameters

NameInTypeDescription
mdaIdquerystring (uuid)

Only this MDA's services

limitqueryinteger

1-500 (100)

offsetqueryinteger

Skip this many

Responses

StatusDescriptionBody
200

OK

application/json ServiceList
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /services/{serviceId}

One published service: passport, fees, required documents, steps

Authentication: clientCredentials: services:read

Parameters

NameInTypeDescription
serviceId requiredpathstring (uuid)

Service id

Responses

StatusDescriptionBody
200

OK

application/json ServiceDetail
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Permits

GET /permits/verify/{code}

Verify a permit, licence or certificate by its verification code or number

Authentication: clientCredentials: permits:verify

Parameters

NameInTypeDescription
code requiredpathstring

Verification code (QR) or permit number

Responses

StatusDescriptionBody
200

OK

application/json PermitVerification
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /verify/{documentNumber}

Verify any document: this platform, a peer node, or a legacy ministry (issuer=<code>) - one answer

Answers 404 with reason not_found only when no source knows the document, 503 when a source could not be asked (never a false not_found), 409 with reason ambiguous when two nodes hold the number (give issuer), 429 (Retry-After) over the federated-check ceilings. On the national hub a document of a node is asked of that node (lib/federation/verifyLookup).

Authentication: clientCredentials: permits:verify

Parameters

NameInTypeDescription
documentNumber requiredpathstring

Issued number or verification code

issuerquerystring

The issuing ministry (short name) or node key: on the hub only that node is asked; a legacy ministry (VERIFY_HUB_ZAMPOINTS) is asked through its ZamPoint, e.g. ZEMA

Responses

StatusDescriptionBody
200

OK

application/json HubVerification
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

POST /verify/documents

Bulk verification: codes and PDFs, each answered like the "verify a document" page of the portal

Codes need the permits:verify scope, PDFs documents:validate; an item the client may not check gets its own 403. PDFs are validated (seal, time-stamp, changes, issued record, lifecycle) and not kept.

Authentication: clientCredentials: permits:verify; clientCredentials: documents:validate

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json BulkVerifyResponse
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /permits/{code}/uses

Whether a certificate can be used now, what is left of its quantity, and its uses

Only certificates of the ministries in the MDA scope of the client; anything else answers 404 like an unknown code.

Authentication: clientCredentials: permits:consume

Parameters

NameInTypeDescription
code requiredpathstring

Verification code or certificate number

Responses

StatusDescriptionBody
200

OK

application/json CertificateUses
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

POST /permits/{code}/uses

Record a use of a certificate (quantity drawn down, place, consignment)

Send Idempotency-Key. A certificate that is not in force, is used up, or has less left than asked is refused (409, nothing recorded). Every use is audited and shown to the holder.

Authentication: clientCredentials: permits:consume

Parameters

NameInTypeDescription
code requiredpathstring

Verification code or certificate number

Idempotency-Key requiredheaderstring

8 to 80 letters, digits or . _ : - (a UUID is ideal); keep it when you retry.

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json CertificateUseRecorded
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Registers

GET /registers

Registers this client may read

Authentication: clientCredentials: registers:read

Responses

StatusDescriptionBody
200

OK

application/json RegisterList
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /registers/{code}/lookup

Search a register by label or key prefix (at most 50)

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
code requiredpathstring

Register code; write / as __

q requiredquerystring

At least 2 characters

limitqueryinteger

1-50 (20)

Responses

StatusDescriptionBody
200

OK

application/json RegisterLookup
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /registers/{code}/entries/{key}

One register entry by key

A key containing / (an NRC) cannot travel in the path through the gateway: use /registers/{code}/entries?key= instead.

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
code requiredpathstring

Register code; write / as __

key requiredpathstring

Entry key

Responses

StatusDescriptionBody
200

OK

application/json RegisterEntry
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /registers/{code}/entries

One register entry by key, the key in the query string (keys with /, such as an NRC)

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
code requiredpathstring

Register code; write / as __

key requiredquerystring

Entry key, URL-encoded

Responses

StatusDescriptionBody
200

OK

application/json RegisterEntry
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /registers/{code}/changes

What changed in a register since a cursor, deletions included (replay from the beginning with no cursor)

Oldest first. Each change carries the entry as it stands now, projected for the client like /entries; deleted and tombstoned entries come as state "removed". Keep nextCursor and send it next time; while more is true, ask again. The answer is signed (X-GSB-JWS, ES256, detached, over the body bytes; keys in /.well-known/jwks.json). Every call is audited.

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
code requiredpathstring

Register code; write / as __

cursorquerystring

nextCursor of the previous answer; empty = from the beginning

limitqueryinteger

1-1000 (100)

Responses

StatusDescriptionBody
200

OK

application/json RegisterChanges
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

The register entries an identifier appears in (companies directed, vehicles owned, parcels held), in the register scope of the client

type: nrc, tpin, passport, entity-number, plate, property-no, title-no, permit-no, zampass-id or any. An identifier containing / (an NRC) cannot travel in the path through the gateway: use /parties/{type}/links?value= instead. Every lookup is audited.

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
type requiredpathstring

Identifier type

value requiredpathstring

The identifier

Responses

StatusDescriptionBody
200

OK

application/json PartyLinks
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /parties/{type}/links

The register entries an identifier appears in, the identifier in the query string (an NRC)

Authentication: clientCredentials: registers:read

Parameters

NameInTypeDescription
type requiredpathstring

Identifier type

value requiredquerystring

The identifier, URL-encoded

Responses

StatusDescriptionBody
200

OK

application/json PartyLinks
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Applications

GET /cases/{caseNumber}/status

Where an application stands (cases of the client's MDAs only)

No personal data is returned.

Authentication: clientCredentials: cases:read

Parameters

NameInTypeDescription
caseNumber requiredpathstring

The application number

Responses

StatusDescriptionBody
200

OK

application/json CaseStatus
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Events

GET /events

The event catalogue

Authentication: clientCredentials: events:subscribe

Responses

StatusDescriptionBody
200

OK

application/json EventCatalogue
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /webhooks

This client's webhook subscriptions (administrators create them)

Authentication: clientCredentials: events:subscribe

Responses

StatusDescriptionBody
200

OK

application/json SubscriptionList
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Audit

GET /audit/events

Audit events about applications of the client's MDAs, oldest first, from a sequence number on

Replay: pass the last sequence you stored as after. Events carry identifiers, roles at the time and the marking - never names, addresses or before / after values. Applications whose marking may not be exposed to partner systems are left out.

Authentication: clientCredentials: audit:read

Parameters

NameInTypeDescription
afterqueryinteger

Only events with a higher sequence (0: from the start)

limitqueryinteger

1-500 (100)

Responses

StatusDescriptionBody
200

OK

application/json AuditEventPage
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Geodata

GET /geo/feeds

The GeoJSON feeds this platform publishes

Authentication: clientCredentials: geo:read

Responses

StatusDescriptionBody
200

OK

application/json GeoFeedList
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

GET /geo/feeds/{key}

One feed as a GeoJSON FeatureCollection, paged

Answers application/geo+json with an ETag: poll with If-None-Match. Follow links[rel=next] for the next page.

Authentication: clientCredentials: geo:read

Parameters

NameInTypeDescription
key requiredpathstring

Feed key, e.g. forestry.licensed-areas

limitqueryinteger

1-2000 (1000)

offsetqueryinteger

Skip this many

bboxquerystring

minLon,minLat,maxLon,maxLat (WGS 84)

updatedSincequerystring (date-time)

Only features changed since (ISO 8601)

Responses

StatusDescriptionBody
200

OK

application/geo+json GeoFeatureCollection
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Legacy consumers

POST /parties/associated-entities

Organisations a person (by NRC) represents

Replaces ZIGS GET /Corporate/GetAssociatedEntities?nrc= (ZamPass portal). Active, approved mandates only.

Authentication: clientCredentials: parties:read

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json AssociatedEntities
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

POST /fines/search

Verify a fine, or list the fines of a person

Replaces ZIGS /Fines/VerifyById, /Fines/Search and /Fines/GetFinesHistoryByNRC (ZamMobile), read-only. Needs the fines register (FINES_REGISTER_CODE) in the register scope of the client; 404 when it is not.

Authentication: clientCredentials: fines:read

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json FineList
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

POST /ussd/cases/lookup

Status and invoice of an application, for the phone of its applicant

Replaces ZIGS /USSD/GetCase and the read half of /USSD/CasePayment (Zamtel USSD gateway). Cases of the MDAs of the client only; a phone number that is not on the application answers 404. The service directory is the public GET /api/ussd/departments.

Authentication: clientCredentials: ussd:gateway

Request body (required)

Responses

StatusDescriptionBody
200

OK

application/json UssdCase
400

The request is not valid (code VALIDATION_FAILED).

application/json Problem
401

No token, an invalid or expired token, or the client is suspended / revoked / expired (TOKEN_REQUIRED, INVALID_TOKEN, CLIENT_INACTIVE, CLIENT_EXPIRED).

application/json Problem
403

The token lacks the scope (INSUFFICIENT_SCOPE), the address is not on the client's allow-list (IP_NOT_ALLOWED), or the client has no MDA scope (MDA_SCOPE_REQUIRED).

application/json Problem
404

Not found, or outside the client's scope (the two are not distinguished).

application/json Problem
429

The client's per-minute limit or daily quota is used up (RATE_LIMITED, QUOTA_EXCEEDED). Wait Retry-After seconds.

application/json Problem
500

Something failed on our side; quote requestId.

application/json Problem

Webhooks

The platform sends these events to your subscribed address.

EVENT case.submitted

An application was submitted to the office.

Request body (required)

EVENT case.status_changed

An application moved to a new stage the applicant can see.

Request body (required)

EVENT case.returned

An application was returned to the applicant for action.

Request body (required)

EVENT case.decided

An application was approved or rejected.

Request body (required)

EVENT case.completed

An application was completed.

Request body (required)

EVENT payment.invoiced

A fee was requested for an application.

Request body (required)

EVENT payment.confirmed

A payment for an application was confirmed.

Request body (required)

EVENT permit.issued

A permit, licence or certificate was issued.

Request body (required)

EVENT permit.status_changed

A permit was suspended, reinstated, cancelled or revoked.

Request body (required)

EVENT service.published

A new version of a service was published to the catalogue.

Request body (required)

EVENT webhook.test

A test message sent from the back office.

Request body (required)

EVENT platform.module-changed

An optional module was switched on or off, or assigned to other ministries (MOD-02).

Request body (required)

EVENT forestry.licence.issued

An event of the forestry module.

Request body (required)

EVENT forestry.licence.expired

An event of the forestry module.

Request body (required)

EVENT forestry.licence.suspended

An event of the forestry module.

Request body (required)

EVENT forestry.licence.revoked

An event of the forestry module.

Request body (required)

EVENT forestry.licence.reinstated

An event of the forestry module.

Request body (required)

EVENT forestry.checkpoint.scanned

An event of the forestry module.

Request body (required)

Schemas

Problem

RFC 7807 problem details, plus the platform's message / code / requestId. Act on code, never on the text.

FieldTypeDescription
typestring (uri)
titlestring
status requiredinteger
code requiredstring
detailstring
message requiredstring
requestIdstring

Quote this to support.

instancestring

The path of the request this answers (never its query string).

OAuthError

FieldTypeDescription
error requiredstring: invalid_client, unsupported_grant_type, access_denied, slow_down, server_error
error_descriptionstring
requestIdstring

TokenRequest

FieldTypeDescription
grant_type requiredany
client_idstring
client_secretstring
scopestring

Space-separated subset of the client's scopes; omit for all of them.

TokenResponse

FieldTypeDescription
access_token requiredstring
token_type requiredany
expires_in requiredinteger
scopestring
warningstring

Me

FieldTypeDescription
clientIdstring
namestring
environmentstring: sandbox, production
scopesarray of string: services:read, permits:verify, documents:validate, registers:read, cases:read, events:subscribe, audit:read, geo:read, legacy:documents, legacy:data-exchange, legacy:payment-callback, legacy:notify, parties:read, fines:read, ussd:gateway, permits:consume
mdaScopearray of string (uuid)
registerScopearray of string
rateLimitPerMininteger
dailyQuotainteger | null

Mda

FieldTypeDescription
idstring (uuid)
namestring
shortNamestring | null

Service

FieldTypeDescription
id requiredstring (uuid)
name requiredstring
descriptionstring | null
typestring | null
mdaIdstring | null (uuid)
mdaMda
feestring | null
processingTimestring | null
validitystring | null
versioninteger | null

The published version number.

updatedAtstring (date-time)

ServiceList

FieldTypeDescription
totalinteger
limitinteger
offsetinteger
servicesarray of Service

ServiceDetail

Type: Service & object

PermitVerification

FieldTypeDescription
valid requiredboolean

true only when the permit exists, is active and within its validity.

permitNumberstring
titlestring | null
statusstring
caseTypestring | null
issuedAtstring | null (date-time)
validFromstring | null (date-time)
validUntilstring | null (date-time)
holderstring | null

Initials and surname only.

holderIdentifierstring | null

Masked.

issuerstring | null
servicestring | null
verifiedAtstring (date-time)
backCapturedboolean

A historical paper permit recorded by the office (LP-ZIGS-14). Until a second officer validates it, its status is pending-validation and valid is false.

CertificateUseRequest

Send an Idempotency-Key header: the same key with the same body is recorded once (a repeat answers 200 with replayed: true); the same key with another body is refused (422 IDEMPOTENCY_KEY_REUSED).

FieldTypeDescription
quantitynumber

Required when the certificate was granted for a quantity (authorised is not null); at most three decimals.

unitstring

Optional; when given it must be the unit of the certificate.

reference requiredstring

What it was used for: the consignment, declaration or entry number.

place requiredstring

The border post, port or checkpoint.

officerRefstring

The service number of your officer (never shown to the holder).

usedAtstring (date-time)

When it was used (default: now; never in the future).

notestring

CertificateUse

FieldTypeDescription
idstring (uuid)
quantitynumber | null
unitstring | null
referencestring
placestring
usedAtstring (date-time)
recordedBystring

The agency that recorded it.

channelstring: api, office
statusstring: recorded, reversed
officerRefstring | null

CertificateUses

Whether the certificate can be used now, how much of its authorised quantity is left, and its uses (newest first).

FieldTypeDescription
permitPermitVerification
usableboolean
reasonstring | null
authorisednumber | null

null: the certificate has no quantity; uses are recorded as a log.

unitstring | null
usednumber | null
remainingnumber | null
singleUseboolean
usedUpboolean
countinteger
usesarray of CertificateUse

CertificateUseRecorded

201 on a new use, 200 with replayed: true on a repeat with the same Idempotency-Key. 409 CERTIFICATE_NOT_VALID / CERTIFICATE_NOT_YET_VALID / CERTIFICATE_USED_UP / QUANTITY_EXCEEDED (remaining, requested, unit) when it cannot be used.

FieldTypeDescription
useCertificateUse
authorisednumber | null
usednumber | null
remainingnumber | null
unitstring | null
usedUpboolean
replayedboolean

HubVerification

The national verification hub (LP-INT-06): the same answer for a document of this platform, of a peer node or of a legacy ministry ZamPoint.

FieldTypeDescription
found requiredboolean
valid requiredboolean

true only when the document exists and is valid now.

statusstring | null
reason requiredstring,null: null, expired, revoked, suspended, cancelled, not_valid, not_found, ambiguous

ambiguous (409): two nodes hold a document with this number - give issuer.

documentNumberstring
titlestring | null
issuerobject | null
issuedAtstring | null
validUntilstring | null
holderMaskedstring | null

Initials and surname only; null for a legacy ministry.

sourcestring,null: null, local, federation, zampoint
checkedAtstring (date-time)
nodeobject

source federation: the node that answered (lane verifyhub).

BulkVerifyRequest

FieldTypeDescription
items requiredarray of object

At most VERIFY_BULK_MAX_ITEMS (20). A code needs permits:verify, a PDF documents:validate.

VerificationResult

One verification answer (lib/verification/result.js): seal validity and document status side by side.

FieldTypeDescription
outcomestring: valid, warning, invalid, unknown, not-signed
headlinestring
pointsarray of object
sealobject | null
changedboolean | null
recordobject | null

The issued record the file matches - never holder data.

signaturesarray of object
technicalobject

BulkVerifyResponse

FieldTypeDescription
resultsarray of object
checkedAtstring (date-time)
idstring

RegisterList

FieldTypeDescription
registersarray of object

RegisterEntry

FieldTypeDescription
registerstring
keystring
labelstring
contextstring | null
dataobject | null

On a typed register: the record as the register pack describes it, only the fields the scope of the client clears.

maskedarray of string

Typed registers: pack paths shown masked.

withheldarray of string

Typed registers: pack paths left out.

schemaobject
updatedAtstring (date-time)
FieldTypeDescription
typestring
linksarray of object

RegisterChanges

Sent as canonical JSON (keys sorted, no white space) and signed: the X-GSB-JWS header is a detached compact JWS (ES256) over those exact bytes; the key is in /.well-known/jwks.json (by kid).

FieldTypeDescription
registerstring
cursorstring

The cursor asked with.

nextCursorstring

Send it as ?cursor= next time; it never goes back.

moreboolean

true: ask again at once, there is more.

changesarray of object

RegisterLookup

FieldTypeDescription
registerstring
resultsarray of object

CaseStatus

FieldTypeDescription
caseNumber requiredstring
status requiredstring

The internal status code.

statusLabelstring

The words the applicant sees.

decisionstring,null: approved, rejected, null
serviceobject
submittedAtstring (date-time)
dueAtstring | null (date-time)
updatedAtstring (date-time)

GeoFeedList

FieldTypeDescription
feeds requiredarray of object

GeoFeatureCollection

GeoJSON (RFC 7946), WGS 84 longitude / latitude. Paged like OGC API - Features: follow the link with rel "next".

FieldTypeDescription
type requiredany
namestring
crsobject
numberMatchedinteger | null
numberReturned requiredinteger
features requiredarray of object
links requiredarray of object

AuditEventPage

FieldTypeDescription
events requiredarray of object
nextAfter requiredinteger

Pass as after for the next page (the same value when nothing new).

moreboolean

EventType

FieldTypeDescription
typestring
descriptionstring
fieldsarray of string

EventCatalogue

FieldTypeDescription
eventsarray of EventType

SubscriptionList

FieldTypeDescription
subscriptionsarray of object

CloudEvent

CloudEvents 1.0, structured JSON mode. Identifiers and statuses only - fetch details with your own token.

FieldTypeDescription
specversion requiredany
id requiredstring (uuid)

The same on every retry and replay: use it to drop duplicates.

source requiredstring
type requiredstring
subjectstring
time requiredstring (date-time)
datacontenttypeany
data requiredobject

NrcQuery

The NRC travels in the body, never the URL.

FieldTypeDescription
nrc requiredstring

AssociatedEntities

Organisations the person is an active, approved representative of. Field names follow the legacy ZIGS Corporate/GetAssociatedEntities answer.

FieldTypeDescription
entitiesarray of object
sourceany

FineQuery

Either fineId or nrc. Personal identifiers travel in the body, never the URL.

FieldTypeDescription
fineIdstring
nrcstring

FineList

Fines from the fines register (no names, NRCs or officer identities).

FieldTypeDescription
registerstring
finesarray of object

UssdCaseQuery

FieldTypeDescription
caseNumber requiredstring
msisdn requiredstring

The number the citizen dials from (260...); must be the one on the application.

UssdCase

FieldTypeDescription
caseNumberstring
statusstring
statusLabelstring
serviceobject
invoiceobject | null
updatedAtstring (date-time)