Webhooks 🚀
AXS provides event-driven integration through webhooks.
This enables your system to receive notifications whenever events occur — for example, when a patient is created or an order is updated.
1. Subscribing for Notifications 🔔
Integrators must register their webhook endpoints using the Webhook Subscription API.
Request Example 💬
POST /v1/webhooks/subscribe HTTP/1.1
Authorization: Bearer <your-access-token>
Content-Type: application/json
{
"events": ["patient.created", "order.updated"],
"callback": "https://your.api/callback",
"hmac": "shared-secret"
}
Note: 📌 The
hmacfield will be moved to a more secure workflow in the future.
2. Subscription Parameters ⚙️
Callback URL 🌐
A publicly accessible HTTPS endpoint to receive webhook notifications.
Event List 📋
One or more event types you wish to subscribe to. Example values:
patient.createdorder.updatedpatient.all
HMAC Secret 🔒
A shared secret string used to verify the authenticity of incoming messages.
3. Receiving Events 📥
When an event occurs, AXS sends an HTTP POST request to your callback URL with the following payload:
{
"source": "axs",
"messageId": "c2f8aaf5-d6d1-4f8c-a4a8-c4e9b3cb3545",
"timestamp": "2025-06-25T12:34:56Z",
"eventType": "patient.created",
"operationId": "123",
"organizationId": "0040694997",
"data": {
"patient": {}
},
"patientId": "a5437cb7-fffd-4cb2-8fdd-4063b5e43dae",
"organizationId": "0040694997"
}
4. HMAC Signature 🔐
Each webhook request includes a Signature header for message integrity.
How It Is Generated 🧠
- Convert the payload to a minified JSON string.
- Apply HMAC-SHA512 hashing using your shared secret.
- Example result (with secret
abcd):
71cb563082c57e645c198027e058be704b3923988f6751566e078a76d73af6493d6cbc3aaf2b3b78fb8b4543bb1d946ddc4dd3bc8c88bca5862634e3921037fd
- AXS sends this in the request header:
Signature: <calculated-HMAC>
5. Security Expectations 🛡️
- 🔐 Callback URLs must use HTTPS.
- ✅ Always validate the HMAC signature before processing payloads.
- 🔁 Use
messageIdfor idempotency to avoid duplicate processing.
6. Failure & Retry Policy ♻️
If the callback fails or times out:
- AXS retries automatically using exponential backoff.
- Retries are automatic re-deliveries of a webhook event when the receiving system fails to acknowledge it.
- Messages will be resent up to three times if they are not acknowledged, with a 15-minute interval between each attempt.
- After 3 failed attempts, the message is moved to the Dead Letter Queue (DLQ).
- The Dead-Letter-Queue (DLQ) is the special queue used in the messaging system to hold the messages that could not be processed successfully.
- You should monitor the health of your callback endpoints.
7. Subscriber Implementation Guide 🧩
Below are sample implementations to help you validate webhook requests.
Java (Spring Boot)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public boolean validateSignature(String payload, String signature, String secret) throws Exception {
Mac sha512_HMAC = Mac.getInstance("HmacSHA512");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA512");
sha512_HMAC.init(keySpec);
byte[] hash = sha512_HMAC.doFinal(payload.getBytes());
String calculated = bytesToHex(hash);
return calculated.equalsIgnoreCase(signature);
}
private String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
Node.js
const crypto = require("crypto");
function validateSignature(payload, signature, secret) {
const hash = crypto
.createHmac("sha512", secret)
.update(payload)
.digest("hex");
return hash === signature;
}
Python
import hmac
import hashlib
def validate_signature(payload: str, signature: str, secret: str) -> bool:
hash_bytes = hmac.new(secret.encode(), payload.encode(), hashlib.sha512).hexdigest()
return hmac.compare_digest(hash_bytes, signature)