Verify signatures
Every delivery is signed. Verify it before trusting the payload.
Headers
| Header | Value |
|---|---|
X-Signature | Base64 Ed25519 signature of the raw request body. |
X-Key-Id | Identifier of the public key that signed the delivery. |
X-Algorithm | Ed25519. |
Steps
- Keep the raw request body exactly as received; verify the bytes, not a re-serialized JSON.
- Read
X-Key-Idand fetch the key withGET /webhooks/public-keys/{publicKeyId}. Check that it isactive. Cache keys by id;X-Key-Idchanges when Axiym rotates keys. - Verify the Ed25519 signature in
X-Signatureover the raw body with that key. - If the headers are missing or the signature does not verify, respond
401and do not process the event. - Deduplicate verified events by
idto prevent repeated processing. Retries retain the original payload and timestamp. If you enforce a timestamp age limit, agree on the supported delivery and retry window with Axiym first; an arbitrary short window can reject legitimate delayed deliveries.
Example delivery
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"timestamp": "2026-06-23T14:05:09Z",
"type": "credit-account.created",
"data": {
"creditAccountId": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"clientId": "b7e8c1a2-9f43-4d2e-8a6b-1c2d3e4f5a6b",
"code": "AXI000221",
"currency": "USD",
"creditLimit": "10000.00",
"principalOutstanding": "0.00",
"totalRepaymentAmount": "0.00",
"totalInterestAmount": "0.00",
"availableBalance": "10000.00",
"paymentRails": "ZENUS_BANK",
"status": "ACTIVE"
}
}