Receiving Notifications
When you send a request to RTGS.global, most operations complete asynchronously. The result — a payment status update, a credit/debit notification, an incoming transfer — is delivered to your systems as a webhook: an HTTPS POST to an endpoint you host.
This guide explains how to receive those notifications, verify they are genuine, and process them safely.
How delivery works
RTGS.global delivers each notification as a single HTTPS POST to your endpoint. The request body is a CloudEvents v1.0 JSON document, and the message payload itself is carried base64-encoded inside it.
Delivery has two important properties:
- At least once. The platform guarantees durable delivery and may deliver the same notification more than once. Your endpoint must be idempotent — see Your endpoint's responsibilities below.
- Retried on failure. If your endpoint does not return a
2xxstatus promptly, delivery is retried with backoff. Returning4xxor5xxtriggers a retry. To prevent retries for a message you have permanently rejected (e.g. signature failure), returnwebhook-delivery: abort-messagealongside your4xx— see Aborting retries on signature failure.
Delivery is powered by Svix, an open-source webhook service. This is relevant in two places: each request carries Svix signature headers you can verify (see Verifying webhooks), and you can use the official Svix SDKs to verify those headers in your language of choice.
What you receive
A delivered notification looks like this:
{
"specversion": "1.0",
"id": "8f6e1c2a-4b7d-4f1e-9c2a-1a2b3c4d5e6f",
"source": "/rtgs/gateway",
"type": "global.rtgs.pacs.002.001.10",
"subject": "E2E-REF-20260618-001",
"datacontenttype": "text/plain",
"time": "2026-06-18T10:30:00.000Z",
"messageid": "b1d9f0c4-2e3a-4d5b-8c7e-9f0a1b2c3d4e",
"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"verificationmaterialtype": "rtgs-global-sig",
"verificationmaterial": "<base64-context>.<pairwise-did>.<public-did>",
"data_base64": "eyJHcnBIZHIiOnsiTXNnSWQiOiJiMWQ5ZjBjNC0yZTNhLTRkNWItOGM3ZS05ZjBhMWIyYzNkNGUiLCJDcnRnRHRUbSI6IjIwMjYtMDYtMThUMTA6MzA6MDBaIn0sIlR4SW5mSW5mIjp7Ik9yaWdJbmZyTHZsQ2QiOiJBQ0NQIn19"
}
Decoded, data_base64 is the ISO 20022 / FIX-compatible JSON payload — for example, a pacs.002 status update:
{
"GrpHdr": {
"MsgId": "b1d9f0c4-2e3a-4d5b-8c7e-9f0a1b2c3d4e",
"CrtnDtTm": "2026-06-18T10:30:00Z"
},
"TxInfAndSts": {
"OrgnlInstrId": "...",
"TxSts": "ACCP"
}
}
| Field | Description |
|---|---|
id | Auto-generated unique identifier for this delivery. Reused on retries — use it for deduplication. |
type | global.rtgs.{MessageType} — use this to decide how to deserialize the payload (e.g. global.rtgs.pacs.002.001.10). |
subject | The end-to-end reference for the originating transaction. |
datacontenttype | Always text/plain. The decoded payload is JSON despite this label. |
time | When the event was produced (UTC). |
messageid | The RTGS.global message identifier (a UUID). |
traceparent | Distributed tracing header (W3C Trace Context). |
verificationmaterialtype | Always rtgs-global-sig. |
verificationmaterial | The RTGS.global digital signature over the decoded payload. Three dot-separated components: base64 context, pairwise DID, public DID. See Verifying webhooks. |
data_base64 | The message payload (ISO 20022 / FIX-compatible JSON), base64-encoded. Decode it before verifying or parsing — see Processing the payload. |
Endpoint requirements
Before registering your endpoint, make sure it meets the following requirements:
| Requirement | Detail |
|---|---|
| Protocol | HTTPS only. Plain HTTP is not accepted. |
| TLS version | TLS 1.2 or higher. Self-signed certificates are not accepted — use a certificate issued by a trusted CA. |
| Port | Standard HTTPS port 443. |
| Method | Accepts POST requests with a Content-Type: application/json body. |
| Response | Return 2xx promptly (within a few seconds). 4xx or 5xx triggers a retry. |
| Path | Any path you choose, e.g. /webhooks/rtgs. |
Your endpoint's responsibilities
- Verify both signatures. The RTGS.global message signature is mandatory; the Svix delivery signature is strongly recommended. Reject with
401if verification fails. See Verifying webhooks. - Acknowledge quickly. Return
2xxas soon as you have verified the request — before running business logic. Slow responses cause retries. - Process asynchronously. Hand the verified notification to a queue or background worker, then return
2xx. - Be idempotent. The same notification may arrive more than once. Deduplicate on the CloudEvent
id, or on the ISO 20022GroupHeadermessage identifier inside the payload.
The two-signature model
Every notification carries two independent signatures. They protect against different threats, and you check them at different layers.
| Signature | Where | Proves | Required? |
|---|---|---|---|
| RTGS.global message signature | verificationmaterial field | The message was genuinely created by RTGS.global and the payload has not been tampered with (end-to-end authenticity & integrity). | Always mandatory. |
| Svix delivery signature | svix-signature header | The HTTP request really came from RTGS.global's delivery infrastructure and is not a replay (transport-layer authenticity). | Situational — see Verifying webhooks. |
The detail of how to verify each — including when the Svix check can be relaxed — is in Verifying webhooks.
Configuring your endpoint
How you configure your webhook endpoint depends on which deployment path you used.
Helm deployment
Edit your values.yaml for the rtgs-signing Helm chart and populate the svix section:
svix:
endpoints:
- uid: "ep-your-participant-prod"
url: "https://your-app.example.com/webhooks/rtgs"
whitelistSubnets:
- "10.0.0.0/8"
-
endpoints— the list of HTTPS URLs that will receive notifications. Theuidis a stable identifier you choose; use something descriptive likeep-{participant}-{env}. You can register multiple endpoints — for example a primary and a DR instance — by adding more entries to the list:svix:endpoints:- uid: "ep-your-participant-prod-primary"url: "https://your-app.example.com/webhooks/rtgs"- uid: "ep-your-participant-prod-dr"url: "https://your-dr.example.com/webhooks/rtgs"Every endpoint in the list receives every notification.
-
whitelistSubnets— CIDR ranges that the Svix server will accept delivery connections from. Set this to your internal network ranges if your endpoint is not publicly reachable. Leave empty ([]) for a public endpoint.
After changing values.yaml, upgrade the Helm release to apply:
helm upgrade rtgs-signing rtgs-signing/ -f values.yaml
Retrieving your signing secret
Once your endpoint is registered, the signing service generates a whsec_… secret for it. Your application must fetch this at startup using the Svix management API credentials provided to you by RTGS.global:
curl -X GET "{svix-server-url}/api/v1/app/{appId}/endpoint/{endpointUid}/secret/" \
-H "Authorization: Bearer {management-token}"
Store the retrieved secret in a secrets manager and load it at runtime. Never commit it to source control. See Verifying webhooks — Get your signing secret for the full detail.
Where to go next
- Event types reference — every event type you can receive, with payload structures and lifecycle tables.
- Verifying webhooks — check both signatures, with SDK examples per language.
- Processing the payload — decode and deserialize the message in your language.
- Verifying a Request — recipe for verifying the RTGS.global signature.
- Verifying a Svix Delivery Signature — recipe for verifying the Svix delivery signature.
For deeper reference on webhook verification mechanics, see the Svix consumer documentation.