Webhook Configuration
Overview
Webhooks enable push messaging about events to a partner's web application via a push service. Apple Business defines a request body format and partners implement a webhook that can handle POST requests to that webhook. Since webhooks are internet-facing, partners should validate that requests received are actually originated by Apple Business.
Availability
- Only an administrator role may create a webhook.
- Webhook URL SHOULD be unique across environments.
Registering Webhooks
- Go to your organization's profile page, select the "API" tab, and select to create a webhook.
- Add distinct name.
- Add an organization member as the contact person for the webhook.
- Select environment and add webhook URL.
After successfully registering your webhook, you're provided with a client secret which is displayed one time.
Recommendations
- Immediately encrypt the client secret or store as hashed version, not as plain text.
- If the security of the client secret is compromised, immediately request a new one.
Message Ordering
Apple Business cannot guarantee that each message will be delivered in the order they were generated.
Message Uniqueness
Apple Business cannot guarantee that you will only receive a single message about an event. Messages about the same event should be rare.
Apple Business Signatures
Business-Signature header values are generated using HMAC SHA512.
Examples of Creating Hashes Using HMAC SHA512
Python (3.7)
import hashlib
import hmac
import base64
payload = bytes('{"type": "HEALTH_CHECK", "id": "498ed60c-883b-4b81-a9c1-1c262ddc69d2_HEALTH", "createdDate": "2026-04-10T12:00:00.000Z"}','utf-8')
client_secret = bytes('secret', 'utf-8')
timestamp = bytes('1649778478749', 'utf-8')
signature = base64.b64encode(hmac.digest(client_secret, payload + timestamp, hashlib.sha512)).decode('utf-8')
print(signature)
Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public static String generateSignature(String secret, String message) {
try {
byte[] secretBytes = secret.getBytes(StandardCharsets.UTF_8);
byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretBytes, "HmacSHA512");
mac.init(secretKeySpec);
byte[] hmacSha512 = mac.doFinal(messageBytes);
String signature = Base64.getEncoder().encodeToString(hmacSha512);
return signature;
} catch (Exception e) {
throw new RuntimeException("Failed to generate signature.", e);
}
}
Scala
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import java.nio.charset.StandardCharsets
import java.util.Base64
object HmacSignature {
def generateSignature(secret: String, message: String): String = {
try {
val secretBytes = secret.getBytes(StandardCharsets.UTF_8)
val messageBytes = message.getBytes(StandardCharsets.UTF_8)
val mac = Mac.getInstance("HmacSHA512")
val secretKeySpec = new SecretKeySpec(secretBytes, "HmacSHA512")
mac.init(secretKeySpec)
val hmacSha512 = mac.doFinal(messageBytes)
val signature = Base64.getEncoder.encodeToString(hmacSha512)
signature
} catch {
case e: Exception => throw new RuntimeException("Failed to generate signature.", e)
}
}
}
Delivery Failures
Apple Business will consider the following as failures:
- Unable to connect to the partner's webhook URL. Reasons include, but are not limited to DNS failure, network failure, or firewall issues.
- Webhook URL does not respond within an expected timeout duration.
- Webhook URL returns HTTP Status Code
5XX.
Retry Attempts
If a request fails, Apple Business will attempt to re-deliver the message.
| Retry Number | Interval (relative to last retry) | Interval (relative to original request) |
|---|---|---|
| 1 | 5 seconds after the failure | 5 seconds after failure |
| 2 | 5 seconds after previous retry | 10 seconds after failure |
| 3 | 5 seconds after previous retry | 15 seconds after failure |
| 4 | 5 seconds after previous retry | 20 seconds after failure |
| 5 | 5 seconds after previous retry | 25 seconds after failure |
| 6 | 5 seconds after previous retry | 30 seconds after failure |
| 7 | 5 seconds after previous retry | 35 seconds after failure |
| 8 | 5 seconds after previous retry | 40 seconds after failure |
| 9 | 5 seconds after previous retry | 45 seconds after failure |
| 10 | 5 seconds after previous retry | 50 seconds after failure |
Partner Requirements
- Webhook must use the HTTPS communication protocol.
- Transport Layer Security (TLS) version 1.2 (or higher).
- System should be idempotent and capable of handling the same request more than once.
- Partner response should be any
2XXHTTP Status Code, or error, with no response body. Any non-2XXresponse is considered a failure. - Partner should respond within ten (10) seconds to a
POSTrequest after which the sending application should time out and consider thePOSTrequest to be a failure. - Partner should allow retry attempts in response to an error being received by Apple Business.
- Partner should process
POSTrequests asynchronously if handling takes longer than the specified amount of time. - Partner should implement countermeasures to prevent replay attacks by using the
Business-Timestampheader value.
Validating POST Requests
A partner's web application should verify that Apple Business is the service that originated a POST request.
Recommendations
- Validate that only a
POSTmethod is received - Validate that
Business-Timestampis within two (2) minutes of the current time - Validate
Business-Signature:- Hash the payload information, the
Business-Timestampheader value, and the shared client secret. (Hash using the same algorithm Apple Business uses.) - If computed signature matches the
Business-Signatureheader value, then no content has changed and the message was originated by Apple Business.
- Hash the payload information, the
Webhook Health & Message Verification
Apple Business will check the "health" and security of your webhook. The following data will be collected to monitor the health and security of your webhook:
- Response HTTP status codes.
- Response times.
- Retry attempts.
Health Check
Apple Business periodically sends HEALTH_CHECK messages to test the readiness of your webhook. Health check requests are sent with an intentionally invalid Business-Signature to verify that your error handling is working correctly — your webhook must respond with 400 Bad Request when signature validation fails. Health checks are performed on a continual basis and at predetermined intervals.
See Webhook Health Check POST for the full request and response specification.