Webhooks
About Webhooks
Webhooks let you subscribe to events that occur on the WEX platform. Once subscribed, WEX will send a notification to your server whenever the relevant event happens. This allows you to get updated in near real time with data pushed to your API, as opposed to having to poll a WEX API looking for changes.
The WEX Fleet Services API uses webhooks to enable pushing updates when a card, a driver, or a vehicle object is changed or added. Webhooks are also used to push authorizations/declines as they occur. More hook event types will be added over time.
Using Webhooks
Subscribing to a Webhook
Webhook subscriptions are created and managed using the Fleet Services REST API. Once your hook consumer API endpoint is published and listening for incoming events, POST a new subscription to the /webhooks/subscriptions API endpoint to create your new webhook and begin receiving updates.
- Use the domain parameter to select which type of event to be notified about. Available event types are listed in the documentation for the subscription endpoint.
- Include the URL of the endpoint on your API server that WEX will POST hook messages to.
- Each webhook subscription is scoped to an account or set of accounts. When creating a webhook subscription, configure a set of accounts. Only events originating from those accounts or their descendant accounts will be included in the hook messages.
- Include the start date and optionally an end date for the subscription to operate. If no end date is specified the subscription will run indefinitely. Webhook subscriptions will only send events that occur after the subscription is created. Setting a start date in the past will not send messages about updates or events that were made in the past.
A successful hook subscription create request will return an HTTP 201 message that includes:
- A unique id for the subscription. This will be included in each message generated by the subscription.
- A secret token that will be used to generate an HMAC signature of every webhook message sent from this subscription. Be sure to save this token and associate with the subscription ID if you’re going to verify message signatures. Other details of the subscription including its status, the start and end date you selected, and the event domain configured.
See full details in the API documentation here.
Handling Hook Delivery
When an event occurs that you’re subscribed to, say, a card status is changed, or an authorization happens, WEX will make an HTTP POST request to the API endpoint specified when you created the webhook subscription.
The structure of the payload is:
{
"subscriptionId": 10,
"data": { JSON domain object - see details below}
}
An HTTP header will be included with the HMAC signature of the contents of the data field.
"x-webhook-signature": HMAC signature of data payload
Your endpoint must return an HTTP 200 response.
Retries
If your endpoint does not return HTTP 200, WEX retries the webhook delivery with exponential backoff. The system is currently configured to make three attempts.
Deliveries are also rate-limited per callback URL. If the rate limit is hit, WEX retries later. Rate limiting alone does not disable the subscription.
Subscription suspension A subscription is automatically set to DISABLED only when the callback returns a non-retryable HTTP status:
401, 403, 404, or 410
For transient failures (for example 5xx, timeouts, or rate limiting), WEX retries up to the retry limit. If those retries are exhausted, that delivery is dropped, but the subscription remains enabled for future events.
Validating a Hook Delivery
You may optionally confirm the message integrity of a hook delivery by validating its signature.
When creating a webhook subscription the response will include a unique secret_token. Be sure to save this token value. It will only be transmitted in the response to the initial subscription creation request. This secret token will be used to generate an HMAC signature of the payload of each hook sent to your API.
To validate the signature use the saved secret token for the webhook subscription to compute a signature of the payload object, and compare the signature to the value in the x-webhook-signature HTTP header of the hook message. If they match you have confirmed that the payload has not been changed.
Example: Generating an HMAC signature to compare with header value
function generateSignature(payloadBody, secretKey) {
return crypto
.createHmac('sha256', secretKey)
.update(payloadBody, 'utf8')
.digest('hex');
}
Algorithm: HmacSHA256
Unsubscribing a Webhook
When your application no longer needs to subscribe to a specific event, use the API to remove the webhook subscription. Simply send an HTTP DELETE request to the /webhook/subscription/{subscription id} endpoint.
See full details in the API documentation here.
Webhook Events & Payloads
Card
Card events are sent whenever a card is created or changed. When creating a webhook subscription you can optionally specify which accounts should be included. Note that the hook subscription will include events for cards in any child accounts of the accounts specified.
Filtering Card Events
You can include a filter in your webhook subscription to only be notified when specific events occur, rather than any change to the card. You can include an array of multiple event types, and the subscription will trigger if any of the filter conditions are met. At the time of this writing available event types for card webhook subscriptions include:
- CARD_SUSPENDED: card.status changed from any other status to suspended
- CARD_TERMINATED: card.status changed from any other status to terminated
- CARD_REACTIVATED: card.status changed from suspended to active
- CARD_STATUS_CHANGED: any change to card.status
Check out the /webhooks/event-types endpoint for the most up to date list of available event filters for each webhook domain.
Payload Example:
{
"data": {
"card_id": "1-SAMPLE",
"account_id": "1-SAMPLE2",
"account_name": "Sample Inc",
"purchase_control_id": "1-SAMPLE3",
"purchase_control_name": "Fuel only",
"bank_identification_number": null,
"batch_order_number": null,
"card_locked": false,
"card_number": "1234",
"card_profile_id": "1-SAMPLE4",
"card_profile_name": "Sample Profile",
"card_suffix": null,
"card_type": "Unrestricted",
"department": null,
"design_code": "ABC1",
"display_card_type": null,
"card_address": null,
"driver_id": null,
"driver_prompt_id": null,
"embossed_number": "*************12345",
"embossing": [
{
"source": "Company Asset Number",
"value": "UNIT XYZ",
"position": 1,
"read_only": false
},
{
"source": "Account Short Name",
"value": "Blah Blah",
"position": 2,
"read_only": false
},
{
"source": "Customer Defined",
"value": "123",
"position": 3,
"read_only": false
}
],
"ev_requested": false,
"ev_requested_date": null,
"expiration_date": "2029-06-03T00:00:00Z",
"last_issue_date": "2026-09-08T00:00:00Z",
"last_updated": "2026-09-08T20:39:30.643271599Z",
"mag_strip_number": "*******************11223",
"order_id": "1-SAMPLE5",
"original_card_id": "1-SAMPLE6",
"pos_display_prompt": "Odometer & Driver ID",
"pos_override_prompt": "Odometer & Driver ID",
"product_id": null,
"reference_id": null,
"renewal_flag": true,
"renewal_period": "60",
"rfids": [],
"status": "Terminated",
"status_reason": "Online Termination",
"use_address_on_card": null,
"usage_type": "Asset",
"user_defined_fields": [],
"vehicle_id": "1-SAMPLE7",
"vehicle_customer_id": "123456",
"vehicle_description": "Unit Number",
"vehicle_prompt_id": null,
"vin": null,
"license_plate_number": null,
"_links": null
},
"subscriptionId": 1
}
Schema
The contents of the data field in the webhook payload are described in the documentation for the REST API for cards, found here.
Driver
Driver events are sent whenever a driver object is created or changed. When creating a webhook subscription you can optionally specify which accounts should be included. Note that the hook subscription will include events for drivers in any child accounts of the accounts specified.
Webhook payloads for driver updates generally follow the same schema as the REST API endpoint for drivers, but omit sensitive fields with personally identifiable information (PII). The following fields are not included in the driver webhook payload: firstname, lastname, middlename, email, and phonenumber.
Payload Example:
{
"subscriptionId": 12345,
"data": {
"driver_id": "1-ABC123",
"driver_number": "D-1001",
"account_id": "1-AF33",
"prompt_id": "1234",
"purchase_device_id": "1-CARD99",
"requested_by": "",
"contact": {
"job_title": "Captain",
"preferred_communication": "EMAIL",
"title": "Mr",
"employee_number": "NC-107",
"badge_number": "1",
"cell_phone_number": "1234567890",
"zip_code": "04101",
"department": {
"department_id": "1-DEPT01",
"department_name": "Fleet Ops"
}
},
"driver_license": {
"license_number": "ABCD",
"license_state": "ME",
"license_country": "US",
"license_expiration_date": "2028-06-01T00:00:00Z"
},
"ev": {
"ev_provider": "Blink",
"home": {
"device": {
"home_device_id": "",
"home_device_status": ""
},
"home_reimbursement_requested_status": ""
}
},
"share_mode": "NONE",
"status": {
"status": "ACTIVE",
"status_reason": null,
"status_changed_date": "2024-01-15T14:30:00Z"
},
"user_defined_fields": [
{
"field_name": "UDF1",
"position": 1,
"value": "Region-East"
}
],
"last_updated": "2024-03-10T18:22:11Z",
"_links": {
"self": {
"href": "",
"method": ""
}
}
}
}
Schema
The contents of the data field in the webhook payload are described in the documentation for the REST API for drivers, found here.
Vehicle
Vehicle events are sent whenever a vehicle object is created or changed. When creating a webhook subscription you can optionally specify which accounts should be included. Note that the hook subscription will include events for vehicle in any child accounts of the accounts specified.
Payload Example:
{
"subscriptionId": 12345,
"data": {
"vehicle_id": "1-SAMPLE",
"account_id": "1-SAMPLE2",
"asset_type": "ASSET",
"company_vehicle_id": "UNIT-1001",
"vehicle_number": "V-1001",
"vehicle_prompt_id": "5678",
"description": "Van",
"date_entered": "2024-01-10T12:00:00Z",
"setup_date": "2024-01-10T12:00:00Z",
"purchase_device_id": "1-SAMPLE3",
"requested_by": null,
"share_mode": "NONE",
"detail": {
"make": "Toyota",
"model": "Prius",
"year": "2020",
"vin": "1HGCM82633A123456",
"start_odometer": 0,
"in_service_date": "2024-01-15T00:00:00Z"
},
"fuel": {
"fuel_usage_type": null,
"mpg": 60,
"tank_capacity": 20,
"unit_of_measure": "GALLONS"
},
"lease": {
"lease_indicator": false,
"lease_expiration_date": null
},
"license_plate": {
"license_plate_number": "ABC123",
"license_plate_state": "ME",
"license_plate_country": "US",
"license_plate_expiration_date": null
},
"status": {
"status": "ACTIVE",
"status_reason": null,
"status_changed_date": "2024-01-15T14:30:00Z",
"status_date": "2024-01-15T14:30:00Z"
},
"user_defined_fields": [
{
"field_name": "UDF1",
"position": 1,
"value": "Region-East"
}
],
"_links": null
}
}
Schema
The contents of the data field in the webhook payload are described in the documentation for the REST API for vehicles, found here.
Authorization
When a purchase is authorized or declined, Authorization webhook subscriptions are triggered. When creating a webhook subscription you can optionally specify which accounts should be included. Note that the hook subscription will include events for vehicle in any child accounts of the accounts specified.
Payload Example:
{
"subscriptionId": 76,
"data": {
"account_id": "1-DENNXR",
"action_code": "000",
"action_code_description": "Approved",
"auth_approval_code": "732761",
"auth_header_id": "107790515",
"brand_owner_name": "Example B2B, LLC",
"card_number": "*******************05682",
"card_id": "1-EBKNA65",
"currency_code": "USD",
"driver_id": null,
"driver_first_name": null,
"driver_last_name": null,
"items": [
{
"amount_account_basis": 0.01,
"amount_merchant_basis": 0.01,
"nacs_product_code": "456",
"nacs_product_description": "Undefined Candy-Reserved for NACS Future",
"quantity": 1.0,
"unit_price": 0.01,
"uom": "U"
}
],
"message_type_code": "1200",
"private_site_usage": null,
"prompts": [
{
"name": "ODOMETER",
"value": "12324"
},
{
"name": "VEHICLE_ID",
"value": "1M4PJVCB0LD123456"
}
],
"terminal_id": "INDEPENDENT",
"terminal_prefix": "ZB",
"txn_timestamp_site": "2026-09-17T18:22:45.000",
"txn_timestamp_wex": "2026-09-15T18:22:54.536Z",
"total_amount_merchant_basis": 0.01,
"total_amount_account_basis": 0.01,
"vehicle_id": "1-EBKNA5X",
"site_details": {
"latitude": 47.394192,
"longitude": -122.249245,
"wex_site_id": "0001S720",
"site_name": "Auto Integrate",
"site_address1": "11 Princess Cir",
"site_address2": null,
"site_city": "Ormond Beach",
"site_state": "FL",
"site_zip_code": "32174-1605",
"site_country_code": "US"
}
}
}
Schema
The contents of the data field in the webhook payload are described in the documentation for the REST API for authorizations, found here.
On this page
- Webhooks