Overview
When a user submits a response to a notification, the ATP server delivers it to the originating service via a webhook callback to the URL specified during service registration. This page explains how to properly receive and handle these webhook callbacks.Webhook Format
HTTP Method: POSTURL: Service’s registered callback URL
Headers:
Content-Type: application/json
X-ATP-Signature: t=1622145123,v1=5257a869e7ecebb...
(HMAC signature for verification)X-ATP-Request-ID: req_abc123def456
(Unique request identifier)
Webhook Payload
Field | Type | Description |
---|---|---|
notification_id | string | UUID of the notification being answered |
action_id | string | Selected action identifier from the notification |
response_data | any | User input data, type determined by action’s response_type |
responded_at | datetime | ISO 8601 timestamp of response submission |
responder | object | Object containing responder identification |
responder
object contains:
Field | Type | Description |
---|---|---|
id | string | Unique identifier of responding entity |
type | string | Either “human” or “agent” to indicate responder type |
Signature Verification
The ATP server signs each webhook payload using thewebhook_secret
provided during service registration. You must verify this signature before processing the webhook to ensure it came from the ATP server.
The signature is included in the X-ATP-Signature
header with this format:
t
is the timestamp when the signature was generatedv1
indicates the signature algorithm version- The value after
v1=
is the hexadecimal representation of the HMAC-SHA256 signature
Signature Verification Example (Node.js)
Signature Verification Example (Python)
Webhook Response
Services must respond to webhook callbacks with an appropriate HTTP status code:- 200 OK: The webhook was processed successfully
- 400 Bad Request: The webhook payload was invalid
- 401 Unauthorized: Signature verification failed
- 500 Internal Server Error: Service encountered an error processing the webhook
- Initial retry after 30 seconds
- Second retry after 2 minutes
- Third retry after 10 minutes
- Fourth retry after 30 minutes
- Fifth retry after 1 hour
Custom Error Responses
If your service encounters an error processing the webhook, you can return a structured error response to provide more information:Field | Type | Description |
---|---|---|
code | string | Service-specific error identifier |
message | string | Technical error description for logging |
user_message | string | Human-readable message for potential user display |
retriable | boolean | Indicates whether retry attempts may succeed |
Webhook Handler Implementation
Express.js Example
Flask Example
Best Practices
- Always verify signatures: Never process webhooks without verifying the signature
- Respond quickly: Process webhooks asynchronously and respond within 5 seconds
- Implement idempotency: Handle duplicate webhook deliveries gracefully
- Log everything: Keep detailed logs of webhook requests and responses
- Implement error handling: Return appropriate status codes and error messages
- Use HTTPS: Ensure your webhook endpoint uses HTTPS for secure communication
- Monitor webhook failures: Set up alerting for repeated webhook failures