Managing Webhooks
Use webhooks to receive near real-time notifications when account events happen in ValueMapper.
Prerequisites
Before creating webhooks, make sure you have:
- Completed authentication
- A public HTTPS endpoint that can accept
POSTrequests
Webhook URLs must use https://. Non-HTTPS URLs are rejected.
Supported Events
When creating a webhook, subscribe to one or more WebhookEventType values:
CONTACT_CREATEDCONTACT_DELETEDREDEMPTION_CODE_CREATEDREDEMPTION_CODE_REDEEMEDWALLET_CREDIT_ADDEDWALLET_CREDIT_SPENTWALLET_CREDIT_REMOVEDWALLET_CREDIT_CONVERTED
Event Payloads
Every delivery shares the same top-level envelope:
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"type": "contact.created",
"timestamp": "2025-04-16T21:33:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID prefixed with evt_ |
type | string | Event type string (see below) |
timestamp | string | ISO 8601 UTC timestamp of the event |
account_uuid | string | UUID of the account that generated the event |
data | object | Event-specific payload (see examples below) |
contact.created
Fired when a new contact is created.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"type": "contact.created",
"timestamp": "2025-04-16T21:33:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"contact": {
"uuid": "c1d2e3f4-0000-0000-0000-000000000001",
"email": "jane@example.com",
"name": "Jane Smith",
"phone": "+15550001234"
}
}
}
contact.deleted
Fired when a contact is deleted.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3302",
"type": "contact.deleted",
"timestamp": "2025-04-16T21:34:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"contact": {
"uuid": "c1d2e3f4-0000-0000-0000-000000000001",
"email": "jane@example.com",
"name": "Jane Smith",
"phone": "+15550001234"
}
}
}
redemption_code.created
Fired when a redemption code is issued. recipientEmail and recipientPhone are null when no recipient was specified.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3303",
"type": "redemption_code.created",
"timestamp": "2025-04-16T21:35:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"redemptionCode": {
"uuid": "r1d2e3f4-0000-0000-0000-000000000001",
"code": "SUMMER20",
"redeemed": false,
"externalId": "shopify-price-rule-123",
"recipientEmail": "jane@example.com",
"recipientPhone": null
}
}
}
redemption_code.redeemed
Fired when a redemption code is marked as redeemed.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3304",
"type": "redemption_code.redeemed",
"timestamp": "2025-04-16T21:36:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"redemptionCode": {
"uuid": "r1d2e3f4-0000-0000-0000-000000000001",
"code": "SUMMER20",
"redeemed": true,
"redeemedAt": "2025-04-16T21:36:00.000Z",
"externalId": "shopify-price-rule-123",
"recipientEmail": "jane@example.com",
"recipientPhone": null
}
}
}
wallet.credit_added
Fired when credit is added to a wallet.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3305",
"type": "wallet.credit_added",
"timestamp": "2025-04-16T21:37:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"wallet": {
"uuid": "w1d2e3f4-0000-0000-0000-000000000001"
},
"creditEntry": {
"uuid": "ce1d2e3f-0000-0000-0000-000000000001",
"action": "ADD",
"creditType": "CREDIT",
"amount": 10.00
}
}
}
wallet.credit_spent
Fired when credit is redeemed/spent from a wallet.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3306",
"type": "wallet.credit_spent",
"timestamp": "2025-04-16T21:38:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"wallet": {
"uuid": "w1d2e3f4-0000-0000-0000-000000000001"
},
"creditEntry": {
"uuid": "ce1d2e3f-0000-0000-0000-000000000002",
"action": "SPEND",
"creditType": "CREDIT",
"amount": 5.00
}
}
}
wallet.credit_removed
Fired when credit is administratively removed from a wallet.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3307",
"type": "wallet.credit_removed",
"timestamp": "2025-04-16T21:39:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"wallet": {
"uuid": "w1d2e3f4-0000-0000-0000-000000000001"
},
"creditEntry": {
"uuid": "ce1d2e3f-0000-0000-0000-000000000003",
"action": "REMOVE",
"creditType": "CREDIT",
"amount": 2.50
}
}
}
wallet.credit_converted
Fired when points or another credit type are converted to a different credit type.
{
"id": "evt_3f2504e0-4f89-11d3-9a0c-0305e82c3308",
"type": "wallet.credit_converted",
"timestamp": "2025-04-16T21:40:00.000Z",
"account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"wallet": {
"uuid": "w1d2e3f4-0000-0000-0000-000000000001"
},
"conversion": {
"from": "POINTS",
"to": "CREDIT",
"amount": 100,
"conversionRate": 0.01
},
"creditEntry": {
"uuid": "ce1d2e3f-0000-0000-0000-000000000004",
"action": "ADD",
"creditType": "CREDIT",
"amount": 1.00
}
}
}
Create a Webhook
Use the createWebhook mutation:
mutation CreateWebhook($webhook: CreateWebhookInput!) {
createWebhook(webhook: $webhook) {
success
webhook {
uuid
url
events
enabled
description
createdAt
}
secret
errors
}
}
Variables:
{
"webhook": {
"url": "https://example.com/webhooks/valuemapper",
"events": ["CONTACT_CREATED", "WALLET_CREDIT_ADDED"],
"description": "CRM + wallet sync"
}
}
Save secret immediately. It is returned in plaintext when creating or rotating a webhook secret, and should be stored securely by your system.
List Webhooks
Fetch configured webhooks for your account:
query GetWebhooks {
account {
webhooks {
uuid
url
events
enabled
description
createdAt
updatedAt
}
}
}
Check Webhook Deliveries
Use account.webhookDeliveries to inspect recent delivery attempts for a webhook.
query GetWebhookDeliveries(
$webhookUuid: String!
$limit: Int
$eventType: WebhookEventType
$success: Boolean
) {
account {
webhookDeliveries(
webhookUuid: $webhookUuid
limit: $limit
eventType: $eventType
success: $success
) {
uuid
eventType
statusCode
errorMessage
durationMs
success
attempts
createdAt
}
}
}
Common filters:
limit(default30, max100)eventType(optional)success(truefor successful deliveries,falsefor failures)
Check Delivery Health
Use account.webhookErrorRate for aggregate delivery health over a rolling window:
query GetWebhookErrorRate($webhookUuid: String!, $windowHours: Int) {
account {
webhookErrorRate(webhookUuid: $webhookUuid, windowHours: $windowHours) {
totalDeliveries
successCount
failureCount
successRate
failureRate
statusCodeBreakdown {
statusCode
count
label
}
}
}
}
windowHours defaults to 24 (max 720).
Delivery Headers and Signature Verification
Each webhook delivery includes:
X-Webhook-Id: webhook UUIDX-Webhook-Event: event identifier (for examplecontact.created)X-Webhook-Timestamp: ISO timestampX-Webhook-Signature: HMAC-SHA256 signature
To verify authenticity, compute:
HMAC-SHA256(secret, timestamp + "." + rawBody)
Then compare it against X-Webhook-Signature.
Update, Disable, or Delete a Webhook
updateWebhookupdates URL, events, description, and enabled status.rotateWebhookSecretgenerates a new signing secret.deleteWebhookpermanently removes the webhook.
Example update mutation:
mutation UpdateWebhook($webhook: UpdateWebhookInput!) {
updateWebhook(webhook: $webhook) {
success
webhook {
uuid
url
events
enabled
description
updatedAt
}
errors
}
}
Variables:
{
"webhook": {
"webhookUuid": "YOUR_WEBHOOK_UUID",
"enabled": false
}
}
Troubleshooting
Webhook URL must be a valid HTTPS URL.: Update the endpoint to HTTPS.At least one webhook event must be selected.: Provide at least one event inevents.- No deliveries returned: Confirm the
webhookUuidbelongs to the authenticated account.