Deal Engine Webhook API Reference
This document describes the GraphQL API for managing webhook configurations in Deal Engine.
Deal Engine Webhook API Reference
This document describes the GraphQL API for managing webhook configurations in Deal Engine.
Overview
The Webhook API allows you to:
- ✅ Configure webhook authentication settings
- ✅ Choose between HMAC Signature or API Key authentication
- ✅ Subscribe to event types with custom endpoint URLs
- ✅ View webhook event delivery history
- ✅ Manage webhook secrets
Configuration Methods
You can configure webhooks through two methods:
1. Dashboard UI (Recommended for Quick Setup)
- Navigate to Settings → Webhooks in the Deal Engine Dashboard
- Configure authentication:
- Select authentication type: Choose HMAC Signature or API Key
- Set your secret/key: Enter your own or click "Generate" to create one
- Customize header name (optional): Use a custom header or keep defaults
- Add event subscriptions with your endpoint URLs
- View delivery history and debug failed webhooks
2. GraphQL API (For Programmatic Control)
Use the API operations described below for automated or programmatic webhook management.
Authentication Types
Deal Engine supports two authentication methods:
| Type | Best For | Security Level | Complexity |
|---|---|---|---|
| HMAC | Production environments | ⭐⭐⭐ High | Moderate |
| API Key | Simple integrations | ⭐⭐ Medium | Simple |
HMAC Signature Authentication
- Each request is uniquely signed using HMAC SHA-256
- Includes timestamp for replay attack protection
- Header format:
t={timestamp},s={signature} - Default header:
X-DE-WEBHOOK-SIGNATURE
API Key Authentication
- Static key sent with every request
- Simpler to implement
- Default header:
X-API-KEY
Authentication
All webhook API operations require authentication. Admin-level operations (marked with 🔐) require admin privileges.
GraphQL Schema
Types
WebhookAuthType
Authentication method for webhook requests.
enum WebhookAuthType {
HMAC # HMAC SHA-256 signature-based authentication
APIKEY # API key in header authentication
}| Value | Description |
|---|---|
HMAC | Requests are signed using HMAC SHA-256. The signature is computed from the timestamp and payload. |
APIKEY | A static API key is sent in the header for authentication. |
WebhookApiConfig
API configuration for webhook authentication.
type WebhookApiConfig {
headerName: String! # Name of the authentication header
secret: String # Secret key reference (ARN or local)
type: WebhookAuthType! # Authentication type (HMAC or APIKEY)
}WebhookEventItem
A configured webhook event subscription.
type WebhookEventItem {
type: String! # Event type identifier (e.g., "refund_request.status_updated")
name: String! # Human-readable display name
url: String! # Destination URL for webhook delivery
uuid: String! # Unique identifier for this subscription
}WebhookFullConfig
Complete webhook configuration including authentication and subscriptions.
type WebhookFullConfig {
apiConfig: WebhookApiConfig # Authentication configuration
events: [WebhookEventItem!]! # List of event subscriptions
}WebhookEvent
A webhook event delivery record.
type WebhookEvent {
pk: String! # Partition key
sk: String! # Sort key
clientId: Int! # Client identifier
timestamp: Float! # Unix timestamp of the event
payload: JSON # Event payload data
environment: String! # Environment (production/staging)
eventId: String! # Unique event identifier
webhookId: String! # Subscription UUID
eventType: String! # Event type
version: String # API version
status: String # Delivery status
responseCode: Int # HTTP response code from your endpoint
responseBody: String # Response body from your endpoint
error: String # Error message if delivery failed
}WebhookEventTypeDefinition
Available event type definition.
type WebhookEventTypeDefinition {
type: String! # Event type identifier
name: String! # Human-readable display name
}Queries
Get Webhook Configuration
Retrieve the full webhook configuration for your account.
query WebhookFullConfig {
webhookFullConfig {
apiConfig {
headerName
type
}
events {
type
name
url
uuid
}
}
}Response:
{
"data": {
"webhookFullConfig": {
"apiConfig": {
"headerName": "X-DE-WEBHOOK-SIGNATURE",
"type": "HMAC"
},
"events": [
{
"type": "refund_request.status_updated",
"name": "Quote updated",
"url": "https://api.yourcompany.com/webhooks/deal-engine",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}
]
}
}
}Get Available Event Types
List all available event types you can subscribe to.
query WebhookEventTypes {
webhookEventTypes {
type
name
}
}Response:
{
"data": {
"webhookEventTypes": [
{
"type": "refund_request.status_updated",
"name": "Quote updated"
},
{
"type": "refund_candidate.status_updated",
"name": "Request updated"
}
]
}
}Possible status values per type
refund_request.status_updated
| Status | Description |
|---|---|
NEW | A quote was requested and is processing |
TICKETS_FROM_PNR_INSERTED | A quote was created by PNR; each ticket from the PNR was inserted for its own quote |
REFUND_CANDIDATE_READY | The quote was successfully created (ticket already existed in our DB) |
ERROR_PROCESSING_REQUEST | There was an error creating the quote; no refund candidate was created |
INSERTED_AND_CREATED_REFUND_CANDIDATE_READY | The quote was successfully created after first inserting the ticket into our DB |
refund_candidate.status_updated
| Status | Description |
|---|---|
REVIEW | The refund quote is complete and needs revision before it can be processed |
REFUNDED | The refund was successfully executed |
ERROR | There was an error processing and fulfilling the refund |
READY | The refund quote is ready to be processed |
Status values are delivered uppercase, exactly as shown.
When each event fires:
refund_request.status_updated— during quoting:REFUND_CANDIDATE_READYwhen the quote completes,ERROR_PROCESSING_REQUESTwhen quoting fails.refund_candidate.status_updated—REFUNDEDandERRORfire automatically when fulfillment finishes (both terminal outcomes always notify);READYandREVIEWfire on candidate status transitions.
Event payload (data field)
data field)Default payload for both event types:
{
"ticket_num": "0651234567890",
"status": "REFUNDED",
"pnr": "ABC123"
}| Field | Meaning |
|---|---|
ticket_num | 13-digit ticket number the event refers to |
status | New status (see tables above) |
pnr | Passenger Name Record, when available |
A customized payload can be configured per account instead, selecting any of: ticketNum, status, pnr, requestId (unique event request id), salesforcesId. Contact Deal Engine to enable a custom response shape.
Delivery notes:
- Events triggered by Deal Engine internal operators are not delivered to client endpoints.
- Delivery failures are logged and visible in the webhook event history (
webhookEventsquery below); they do not affect the refund itself.
Get Webhook Event History
Retrieve webhook delivery history with optional filtering.
query WebhookEvents($limit: Int, $nextToken: String, $filters: WebhookEventFilters) {
webhookEvents(limit: $limit, nextToken: $nextToken, filters: $filters) {
items {
eventId
eventType
timestamp
status
responseCode
payload
error
}
nextToken
}
}Variables:
{
"limit": 20,
"filters": {
"eventType": "refund_request.status_updated",
"status": "delivered",
"timestampFrom": 1700000000,
"timestampTo": 1700100000
}
}Filter Options:
| Field | Type | Description |
|---|---|---|
eventType | String | Filter by event type |
status | String | Filter by delivery status |
timestampFrom | Float | Start of timestamp range (Unix) |
timestampTo | Float | End of timestamp range (Unix) |
Response:
{
"data": {
"webhookEvents": {
"items": [
{
"eventId": "evt_abc123",
"eventType": "refund_request.status_updated",
"timestamp": 1700050000,
"status": "delivered",
"responseCode": 200,
"payload": { "refundId": "ref_xyz" },
"error": null
}
],
"nextToken": "eyJwayI6IkNMSUVOVC..."
}
}
}Get Webhook Secret 🔐
Retrieve the plain-text webhook secret value (admin only).
query WebhookSecret($secretArn: String!) {
webhookSecret(secretArn: $secretArn)
}
Security Note: This query returns the actual secret value. Only use this when you need to configure your webhook verification. Never expose this in logs or client-side code.
Mutations
Update Webhook API Configuration 🔐
Configure authentication settings for your webhooks.
mutation UpdateWebhookApiConfig($apiConfig: WebhookApiConfigInput!) {
updateWebhookApiConfig(apiConfig: $apiConfig)
}Variables:
{
"apiConfig": {
"headerName": "X-DE-WEBHOOK-SIGNATURE",
"type": "HMAC",
"secret": "your-secret-key"
}
}Input Fields:
| Field | Type | Required | Description |
|---|---|---|---|
headerName | String | Yes | Name of the authentication header (customizable) |
type | WebhookAuthType | Yes | HMAC or APIKEY |
secret | String | No | Your secret/API key (auto-generated if not provided) |
Default Header Names:
| Auth Type | Default Header |
|---|---|
| HMAC | X-DE-WEBHOOK-SIGNATURE |
| APIKEY | X-API-KEY |
Secret Handling Behavior:
- Not provided + no existing secret: A secure random key is auto-generated (format:
whsec_...) - Not provided + existing secret: The existing secret is preserved
- Provided: Your secret is used (stored securely in AWS Secrets Manager)
Security: Plain-text secrets are automatically encrypted and stored in AWS Secrets Manager. You'll receive a reference (ARN) that can be used to retrieve the actual value.
Response:
{
"data": {
"updateWebhookApiConfig": true
}
}Roll Webhook Secret 🔐
Generate a new webhook secret. Use this to rotate your secret for security purposes.
mutation RollWebhookSecret {
rollWebhookSecret
}Response:
{
"data": {
"rollWebhookSecret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
}
Important: After rolling the secret, update your webhook verification code immediately. The previous secret will no longer work.
Add Webhook Event Subscription 🔐
Subscribe to a webhook event type.
mutation AddWebhookEvent($event: WebhookEventItemInput!) {
addWebhookEvent(event: $event)
}Variables:
{
"event": {
"type": "refund_request.status_updated",
"url": "https://api.yourcompany.com/webhooks/deal-engine"
}
}Input Fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | String | Yes | Event type to subscribe to |
url | String | Yes | HTTPS endpoint URL for delivery |
uuid | String | No | UUID for updating existing subscription |
URL Requirements:
- Must be a valid URL format
- Should be accessible from the internet
- HTTPS recommended for production
Response:
{
"data": {
"addWebhookEvent": true
}
}Delete Webhook Event Subscription 🔐
Remove a webhook event subscription.
mutation DeleteWebhookEvent($uuid: String!) {
deleteWebhookEvent(uuid: $uuid)
}Variables:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}Response:
{
"data": {
"deleteWebhookEvent": true
}
}Complete Setup Examples
Setup with HMAC Signature (Recommended)
Step 1: Configure HMAC Authentication
mutation UpdateWebhookApiConfig {
updateWebhookApiConfig(apiConfig: {
headerName: "X-DE-WEBHOOK-SIGNATURE" # Or use your custom header name
type: HMAC
# secret: "your-custom-secret" # Optional - omit to auto-generate
})
}Step 2: Get Your Secret
query WebhookFullConfig {
webhookFullConfig {
apiConfig {
headerName
type
secret
}
}
}Use the returned secret ARN to retrieve the actual secret value:
query WebhookSecret($secretArn: String!) {
webhookSecret(secretArn: $secretArn)
}Step 3: Subscribe to Events
mutation AddWebhookEvent {
addWebhookEvent(event: {
type: "refund_request.status_updated"
url: "https://api.yourcompany.com/webhooks/quotes"
})
}Setup with API Key
Step 1: Configure API Key Authentication
mutation UpdateWebhookApiConfig {
updateWebhookApiConfig(apiConfig: {
headerName: "X-API-KEY" # Or use your custom header name
type: APIKEY
secret: "your-api-key" # Provide your key or omit to auto-generate
})
}Step 2: Get Your API Key
query WebhookFullConfig {
webhookFullConfig {
apiConfig {
headerName
type
secret
}
}
}If the secret is stored in AWS Secrets Manager, retrieve the actual value:
query WebhookSecret($secretArn: String!) {
webhookSecret(secretArn: $secretArn)
}Step 3: Subscribe to Events
mutation AddWebhookEvent {
addWebhookEvent(event: {
type: "refund_request.status_updated"
url: "https://api.yourcompany.com/webhooks/deal-engine"
})
}Subscribe to All Event Types
mutation AddWebhookEvent {
addWebhookEvent(event: {
type: "refund_request.status_updated"
url: "https://api.yourcompany.com/webhooks/quotes"
})
}
mutation AddWebhookEvent {
addWebhookEvent(event: {
type: "refund_candidate.status_updated"
url: "https://api.yourcompany.com/webhooks/requests"
})
}Verify Your Configuration
query WebhookFullConfig {
webhookFullConfig {
apiConfig {
headerName
type
}
events {
type
name
url
uuid
}
}
}Error Handling
Common Errors
| Error | Cause | Solution |
|---|---|---|
Invalid URL format | URL doesn't match expected format | Use a valid URL starting with http:// or https:// |
Failed to update webhook API config | Server error during config update | Retry the operation |
Failed to fetch webhook secret | Invalid secret ARN | Verify the secret ARN exists |
GraphQL Error Response Format
{
"errors": [
{
"message": "Invalid URL format",
"extensions": {
"code": "BAD_REQUEST"
}
}
],
"data": null
}Rate Limits
The webhook API is subject to the same rate limits as other Deal Engine APIs. Contact support if you need higher limits.
Best Practices
- Use HMAC Authentication: HMAC provides better security than API keys as each request is uniquely signed
- Rotate Secrets Regularly: Use
rollWebhookSecretperiodically for security - Monitor Delivery Status: Regularly check
webhookEventsfor failed deliveries - Use Descriptive URLs: Include identifiers in your webhook URLs for easier debugging
- Test Before Production: Configure webhooks in staging environment first
Support
For webhook-related issues:
- Check the webhook events log using the
webhookEventsquery - Verify your endpoint is accessible and returns 2xx status codes
- Review error messages in the delivery history
- Contact Deal Engine support with relevant
eventIdvalues
Updated 1 day ago