Download OpenAPI specification:Download
Group Assist (group checkout) API used by MCCY Culture Pass.
A caller submits a batch of up to 50 per-NRIC transactions in one call. The call is
asynchronous: the service persists a workflow, returns a workflowId immediately, and processes
the batch on background workers. The outcome is retrieved by polling POST /api/workflow/get.
Every request and response on these endpoints is wrapped in a JWE/JWS envelope.
| Direction | Content-Type | Body | Inner |
|---|---|---|---|
| Request | application/x-www-form-urlencoded |
payload=<JWE> |
business JSON, RSA-OAEP-512 to GovWallet's enc key |
| Success | application/json |
{"payload": "<JWE>"} |
JWE to the campaign's registered key, wrapping a GovWallet-signed JWS |
| Error | application/json |
{"payload": "<JWS>"} |
signed only, not encrypted — claims are {"error": "..."} |
The response JWS adds iss, iat and nbf claims alongside the business fields — that is why
enquiry samples show iss: non-prd.dist.wallet.gov.sg next to workflowId/state/result.
GET /.well-known/jwks.json publishes both keys: RSA use: "enc" for request encryption, EC
P-256 use: "sig" for response verification.
Every request and response below is documented in its decrypted form — the JSON that goes
inside the envelope described above, not the raw HTTP body. This is for readability. The
EncryptedEnvelope and SignedEnvelope schemas describe the real bodies.
To send a documented request: serialise the object to JSON, encrypt it with RSA-OAEP-512
to the use: "enc" key from GET /.well-known/jwks.json, and POST the compact JWE as
application/x-www-form-urlencoded in a single field — payload=<JWE>. Any other content type,
or a missing payload field, is rejected.
To read a documented response: the body is always the single-field wrapper
{"payload": "<compact token>"}. Decrypt the JWE with the private key registered for your
campaign, verify the resulting JWS against the use: "sig" key from the JWKS endpoint, then
read its claims. Error responses skip the decryption step — their payload is a bare JWS.
Because both directions are documented as plaintext, generated clients and Swagger UI's "Try it out" will not work against this spec without adding the envelope steps yourself.
Campaign names are environment-suffixed — mccy-culture-pass-stg, mccy-culture-pass-prd.
Examples throughout this file use the staging form. The name must match an existing campaign or
intake returns campaign not found.
Accepts up to 50 transactions, each keyed by hashNric, and queues them for asynchronous
processing. Returns a workflowId used for later enquiry.
Idempotency — nonce is unique per campaign. Replaying a request with a nonce already
seen for that campaign does not create a second workflow; the existing workflowId is
returned with status 200 instead of 202.
Partner cart transaction id — GovWallet namespaces the supplied partnerCartTxnId by
prefixing it with batch_payment- on intake. The prefix is applied idempotently: an id that
already carries it is left untouched. Downstream records carry the prefixed id.
Shown decrypted. The actual request body is application/x-www-form-urlencoded with a
single field, payload=<JWE>, whose plaintext is the JSON object below encrypted with
RSA-OAEP-512 to the use: "enc" key from the JWKS endpoint.
| nonce required | string Unique per campaign; the idempotency key for the batch. Replaying a nonce returns the workflow created the first time. |
| exp required | integer <int64> Expiry as a Unix timestamp in seconds. Must be present and strictly in the future at the time GovWallet processes the request. |
| iss required | string <uri> Issuer identifying the calling agency. Must be registered against |
| partnerIss required | string <uri> Issuer identifying the merchant/partner the payment is made to. Must be registered
against |
| tags | Array of strings Free-form labels attached to the batch. |
| partnerCartTxnId required | string Partner's own identifier for the cart/transaction group. GovWallet prefixes it with
|
required | Array of objects (BatchTransaction) [ 1 .. 50 ] items One entry per beneficiary. At least 1, at most 50. |
| campaign required | string GovWallet campaign name, environment-suffixed. Must exist or intake returns
|
{- "nonce": "sample-nonce",
- "exp": 1234567890,
- "tags": [
- "group-assist"
], - "partnerCartTxnId": "97183f96-b9e1-4c93-97ae-03d04ff08104",
- "transactions": [
- {
- "hashNric": "A0ED9F60F71AD2C34ED8B15C6AD4F696FE982DD15E44CD3A43415D3C46C43A39",
- "cart": {
- "itemId": "string",
- "itemName": "string",
- "providerName": "string",
- "itemStartDate": "2026-08-01T10:00:00Z",
- "itemEndDate": "2026-08-01T12:00:00Z",
- "description": "string",
- "quantity": 1,
- "amountCents": 100,
- "additionalFeesCents": 10,
- "discountCents": 10,
- "itemType": "Group Assist Ticket",
- "metadata": {
- "UserDefined1": "2514669",
- "UserDefined2": "97183f96-b9e1-4c93-97ae-03d04ff08104",
- "coordinator": {
- "id": "sample-cps-id"
}
}
}
}
], - "campaign": "mccy-culture-pass-stg"
}{- "workflowId": "968de5dd-558f-47ee-a032-a3217fc373a8"
}Returns the current state of a workflow and, once state is completed, the per-transaction
results.
The workflow must belong to the campaign supplied in the request; a mismatch is reported as
404 and is indistinguishable from a workflow that does not exist.
Shown decrypted. The actual request body is application/x-www-form-urlencoded with a
single field, payload=<JWE>, whose plaintext is the JSON object below encrypted with
RSA-OAEP-512 to the use: "enc" key from the JWKS endpoint.
| campaign required | string Must match the campaign the workflow was created under. |
| workflowId required | string <uuid> The |
{- "campaign": "mccy-culture-pass-stg",
- "workflowId": "eee88efd-e82a-476e-8864-52b1e95ebc80"
}Non-terminal. result is absent. createdAt and updatedAt are still
identical because nothing has advanced the workflow yet.
{- "workflowId": "b188cbfa-bc94-4bb2-8e30-98c8518c5ae7",
- "state": "queued",
- "createdAt": "2026-07-24T01:56:39Z",
- "updatedAt": "2026-07-24T01:56:39Z",
- "iss": "non-prd.dist.wallet.gov.sg",
- "iat": 1784879567,
- "nbf": 1784879567
}Ask Spoon