When building FastBound integrations, you might want your applications to receive events as they occur in FastBound accounts so that your backend systems can execute actions accordingly.
After you register them, FastBound will push real-time event data to your application’s webhook endpoint when events happen in a FastBound account.
Receiving webhook events is particularly useful for listening to asynchronous events such as when someone commits an acquisition, creates or edits a contact, or changes an item in your FastBound account.
Subscribing to events with webhooks
Having FastBound notify another application about events in your FastBound account is relatively straightforward.
-
Browse to Settings > Webhooks in FastBound.
-
Tap the + Webhook button.
-
Enter a Name and URL for your Webhook and choose the Events to which you’d like to subscribe. Description is optional.
-
Tap the Create button.
FastBound also has an API for maintaining webhooks programmatically.
Reliable Delivery
FastBound will queue an event for delivery to your specified webhook URL when a subscribed-to event occurs.
The first delivery attempt typically occurs within seconds. An HTTP response with a 2xx status code indicates successful delivery, removing the webhook from the delivery queue.
If an error occurs when contacting your webhook URL, the delivery is considered failed and queued for redelivery. Delivery requests will time out and fail after 100 seconds.
Retry Logic
FastBound retries failed webhook deliveries for up to three days after the webhook is first generated. Each retry occurs at a specific elapsed time (measured from the original delivery attempt), with intervals that grow longer over time:
-
First hour (elapsed): 1m, 5m, 14m, 30m, 55m (5 retries)
-
Hours 2–24 (elapsed): 1h 31m, 2h 20m, 3h 24m, 4h 45m, 6h 25m, 8h 26m, 10h 50m, 13h 39m, 16h 55m, 20h 40m (10 retries, 15 total)
-
24–48 hours (elapsed): 24h 56m, 29h 45m, 35h 9m, 41h 10m, 47h 50m (5 retries, 20 total)
-
48–72 hours (elapsed): 55h 11m, 63h 15m, 72h 4m (3 retries, 23 total)
After the final retry at approximately 72 hours elapsed, no further delivery attempts are made.
Disable Logic
If a webhook fails 45 times, the webhook will be disabled, and the account owner will receive an email informing them that it has been disabled. The webhook URL will no longer receive events from FastBound. Disabled webhooks can be deleted or re-enabled in Settings > Webhooks.
Webhooks should be configured to receive only the types of events required by your application or integration. Listening for extra events (or all events) will put undue strain on your server and is not recommended.
You can change the events a webhook URL will receive in the account webhook settings or with the API.
Outbound IP Addresses
FastBound delivers all webhooks exclusively over HTTPS and includes signature verification so you can securely validate each request at the application layer. These protections provide strong, reliable security and are the recommended way to authenticate webhook traffic.
Because of this, we do not recommend IP-restricting webhook endpoints. IP allowlisting can introduce unnecessary operational risk, may break without notice as infrastructure evolves, and should not be relied upon as a primary security control.
That said, if your organization requires IP-based firewall rules, you can retrieve the current outbound IP addresses used by FastBound’s webhook infrastructure at:
https://webhook-source-ips.fastbound.workers.dev/
This endpoint returns a plain-text list of active outbound IP addresses, one per line. You can also retrieve the list of IP addresses in other formats at your discretion. You can safely allow these IP addresses in your firewall to allow webhook traffic.
You may allowlist these addresses in your firewall to permit webhook traffic. However, please note:
-
The list may change as infrastructure is updated or scaled.
-
You are responsible for keeping firewall rules in sync.
-
IP allowlisting should be considered a supplemental control only.
For the most secure and resilient integration, rely on HTTPS and signature verification rather than network-level filtering alone.
Event Types
FastBound’s Open API documentation is generated directly from source code for each release and always reflects the most current webhook event models and payload definitions. For the latest and authoritative schema details, always refer to the Open API documentation.
|
Event / Model |
Description |
|
acquisition.committed AcquisitionCommittedEvent |
An acquisition is committed to the A&D book. Includes contact, items, shipment tracking, invoice/PO numbers, and manufacturing flag. |
|
acquisition.created AcquisitionCreatedEvent |
A pending acquisition record is created. Contains contact, acquisition items, and tracking/invoice metadata. |
|
acquisition.deleted AcquisitionDeletedEvent |
An acquisition record is deleted. Includes contact and associated acquisition items. |
|
acquisition.transfer AcquisitionTransferEvent |
An acquisition created via transfer between FFLs. Includes transferor contact, transferee contact, and transferred items. |
|
contact.created ContactCreatedEvent |
A new contact is created. Contains full licensing, business, and status details. |
|
contact.deleted ContactDeletedEvent |
A contact is deleted. Includes identifying and licensing information. |
|
contact.edited ContactEditedEvent |
A contact’s details are modified. Contains updated licensing and business information. |
|
disposition.committed DispositionCommittedEvent |
A disposition is committed to the A&D book. Includes contact, items, theft/loss/destroyed metadata, tracking numbers, and 4473/manufacturing flags. |
|
disposition.deleted DispositionDeletedEvent |
A pending disposition is deleted. Includes status, contact, and item details. |
|
disposition.edited DispositionEditedEvent |
A disposition record is edited. Contains updated contact, status, tracking, and compliance metadata. |
|
disposition.items.added DispositionItemsAddedEvent |
Items are added to an existing disposition. Includes acquisition and pricing details. |
|
disposition.items.edited DispositionItemsEditedEvent |
Items within a disposition are modified (price, pawn redemption flag, etc.). |
|
disposition.items.removed DispositionItemsRemovedEvent |
Items are removed from a disposition. Includes item identity and pricing data. |
|
form4473.completed Form4473CompletedEvent |
A Form 4473 reaches completion status. Includes buyer information, response codes, and status metadata. |
|
inventory.location.moved InventoryLocationMovedEvent |
An item’s physical inventory location changes. |
|
inventory.location.verified InventoryLocationVerifiedEvent |
An item’s location is verified during cycle count. |
|
inventory.notfound InventoryNotFoundEvent |
An item is marked not found during inventory verification. |
|
item.deleted ItemDeletedEvent |
An item record is deleted. Includes identifying and status data. |
|
item.edited ItemEditedEvent |
Item details are modified (manufacturer, serial, location, pricing, etc.). |
|
item.imported ItemImportedEvent |
Items are imported via bulk/CSV process. |
|
item.undeleted ItemUndeletedEvent |
A previously deleted item is restored. |
|
item.undisposed ItemUndisposedEvent |
A disposed item is reverted back to available status. |
|
multiplesalereport.transmitted MultipleSaleReportTransmittedEvent |
A Multiple Sale Report is transmitted. Includes item acquisition details and transmission metadata. |
Samples
If you want to inspect or test webhook payloads without writing code, you can use free tools like Pipedream, Webhook.site, or similar request-capture services. These tools generate a temporary public URL that you can paste into your FastBound webhook configuration. When an event fires, the service captures the full HTTP request — including headers, body, and retry attempts — so you can review the exact JSON payload defined in Swagger. This makes it easy to validate event types, confirm schema changes between releases, and debug integrations before pointing the webhook to your production endpoint.
acquisition.committed
{
"id": "132511c8-d32b-4864-9166-94ae2cfcaf53",
"eventName": "acquisition.committed",
"accountNumber": 75165,
"timestampUtc": "2021-01-11T01:06:18.0599182Z",
"data": {
"date": "2021-01-10T20:03:06",
"type": "Purchase",
"shipmentTrackingNumber": null,
"invoiceNumber": null,
"purchaseOrderNumber": null,
"contact": {
"id": "ed38ffa7-da02-467d-8c4c-acad00121ee3",
"externalId": null,
"fflNumber": "158067072A90327",
"fflExpires": "2022-01-01T00:00:00",
"licenseName": "GLOCK INC",
"tradeName": null,
"organizationName": null,
"firstName": null,
"middleName": null,
"lastName": null,
"premiseAddress1": "6000 HIGHLANDS PKWY",
"premiseAddress2": null,
"premiseCity": "SMYRNA",
"premiseState": "GA",
"premiseZipCode": "300820000",
"premiseCounty": null,
"premiseCountry": "US",
"phoneNumber": "7704321202",
"fax": null,
"emailAddress": null
},
"items": [
{
"id": "feea44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00036",
"status": 1,
"statusText": "Available",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "17",
"caliber": "9X19",
"serial": "FPR269",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 499.99,
"mpn": "PI1750203",
"upc": "76450350210",
"sku": "PI1750203"
},
{
"id": "ffea44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00037",
"status": 1,
"statusText": "Available",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "17 Gen 4",
"caliber": "9X19",
"serial": "HZN295",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 539.77,
"mpn": "PG1750203",
"upc": "76450365203",
"sku": "PG1750203"
},
{
"id": "00eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00038",
"status": 1,
"statusText": "Available",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "19",
"caliber": "9X19",
"serial": "CPY726",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 499.99,
"mpn": "PI1950203",
"upc": "764503502194",
"sku": "PI1950203"
},
{
"id": "01eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00039",
"status": 1,
"statusText": "Available",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "19 Gen 4",
"caliber": "9X19",
"serial": "JZP837",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 540,
"mpn": "PG1950203",
"upc": "764503692031",
"sku": "PG1950203"
},
{
"id": "02eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00040",
"status": 1,
"statusText": "Available",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "20 SF",
"caliber": "10mm",
"serial": "TGE329",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 545.04,
"mpn": "PF2050203",
"upc": "764503662034",
"sku": "PF2050203"
}
]
}
}
disposition.committed
{
"id": "211d1ded-9f37-4cab-b924-58057b7441d6",
"eventName": "disposition.committed",
"accountNumber": 75165,
"timestampUtc": "2021-01-11T01:13:21.9774615Z",
"data": {
"date": "2021-01-10T20:12:36",
"type": "Sale",
"ttsn": null,
"otsn": null,
"shipmentTrackingNumber": null,
"invoiceNumber": null,
"purchaseOrderNumber": null,
"theftLoss_DiscoveredDate": null,
"theftLoss_Type": null,
"theftLoss_ATFIssuedIncidentNumber": null,
"theftLoss_PoliceIncidentNumber": null,
"destroyed_Date": null,
"destroyed_Description": null,
"destroyed_Witness1": null,
"destroyed_Witness2": null,
"contact": {
"id": "ed38ffa7-da02-467d-8c4c-acad00121ee3",
"externalId": null,
"fflNumber": "158067072A90327",
"fflExpires": "2022-01-01T00:00:00",
"licenseName": "GLOCK INC",
"tradeName": null,
"organizationName": null,
"firstName": null,
"middleName": null,
"lastName": null,
"premiseAddress1": "6000 HIGHLANDS PKWY",
"premiseAddress2": null,
"premiseCity": "SMYRNA",
"premiseState": "GA",
"premiseZipCode": "300820000",
"premiseCounty": null,
"premiseCountry": "US",
"phoneNumber": "7704321202",
"fax": null,
"emailAddress": null
},
"items": [
{
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "feea44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00036",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "17",
"caliber": "9X19",
"serial": "FPR269",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 499.99,
"mpn": "PI1750203",
"upc": "76450350210",
"sku": "PI1750203"
},
{
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "ffea44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00037",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "17 Gen 4",
"caliber": "9X19",
"serial": "HZN295",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 539.77,
"mpn": "PG1750203",
"upc": "76450365203",
"sku": "PG1750203"
},
{
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "00eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00038",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "19",
"caliber": "9X19",
"serial": "CPY726",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 499.99,
"mpn": "PI1950203",
"upc": "764503502194",
"sku": "PI1950203"
},
{
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "01eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00039",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "19 Gen 4",
"caliber": "9X19",
"serial": "JZP837",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 540,
"mpn": "PG1950203",
"upc": "764503692031",
"sku": "PG1950203"
},
{
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "02eb44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00040",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "20 SF",
"caliber": "10mm",
"serial": "TGE329",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 545.04,
"mpn": "PF2050203",
"upc": "764503662034",
"sku": "PF2050203"
}
]
}
}
disposition.items.added
{
"id": "cb0b80e7-2061-4e22-8d32-8e1d6b9d0638",
"eventName": "disposition.items.added",
"accountNumber": 75001,
"timestampUtc": "2023-04-13T21:59:20.0848182Z",
"data": {
"contact": null,
"dispositionItemsAdded": [
{
"item": {
"acquisitionType": "Dealer Transfer",
"acquire_Date": "2018-05-03T22:47:55",
"acquire_License": "548055070L04391",
"acquire_LicenseName": "DRUSSEL, COLBY",
"acquire_LicenseExpires": "2020-11-01T00:00:00",
"acquire_TradeName": "DRUSSEL PRECISION RIFLES",
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "9585 HANDS ROAD",
"acquire_Address2": null,
"acquire_City": "GARDEN CITY",
"acquire_State": "KS",
"acquire_Postal": "67846",
"acquire_Country": "US",
"acquire_PhoneNumber": null,
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"undeleteNote": null,
"locationVerifiedUtc": null,
"id": "73302692-51bf-446d-9fca-a8d6003ef97f",
"externalId": null,
"itemNumber": "00312",
"status": 2,
"statusText": "Pending Disposal",
"manufacturer": "Glock",
"countryOfManufacture": null,
"importer": "Glock Inc",
"type": "Pistol",
"model": "14",
"caliber": "9MM",
"serial": "A1300",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": null,
"mpn": null,
"upc": null,
"sku": null
},
"id": "52532af0-da81-4e64-9c5f-afe3016a5d82",
"price": null,
"pawnRedemption": false
}
],
"status": 2,
"statusText": "Awaiting Form 4473 Completion",
"id": "17828393-0a82-49b4-a78a-afe3016a3a2a",
"date": null,
"type": null,
"ttsn": null,
"otsn": null,
"shipmentTrackingNumber": null,
"invoiceNumber": null,
"purchaseOrderNumber": null,
"theftLoss_DiscoveredDate": null,
"theftLoss_Type": null,
"theftLoss_ATFIssuedIncidentNumber": null,
"theftLoss_PoliceIncidentNumber": null,
"destroyed_Date": null,
"destroyed_Description": null,
"destroyed_Witness1": null,
"destroyed_Witness2": null,
"is4473": true,
"isManufacturingDisposition": false
}
}
item.edited
{
"id": "31e3d290-40fd-49b3-910d-9af168acac50",
"eventName": "item.edited",
"accountNumber": 75165,
"timestampUtc": "2021-01-11T06:25:19.9115049Z",
"data": {
"dispositionType": "Sale",
"dispose_Date": "2021-01-10T20:12:36",
"dispose_License": "158067072A90327",
"dispose_LicenseName": "GLOCK INC",
"dispose_LicenseExpires": "2022-01-01T00:00:00",
"dispose_TradeName": null,
"dispose_Organization": null,
"dispose_FirstName": null,
"dispose_MiddleName": null,
"dispose_LastName": null,
"dispose_Address1": "6000 HIGHLANDS PKWY",
"dispose_Address2": null,
"dispose_City": "SMYRNA",
"dispose_State": "GA",
"dispose_Postal": "300820000",
"dispose_Country": "US",
"dispose_PhoneNumber": "7704321202",
"dispose_Fax": null,
"dispose_EmailAddress": null,
"ttsn": null,
"otsn": null,
"dispose_PurchaseOrderNumber": null,
"dispose_InvoiceNumber": null,
"dispose_ShipmentTrackingNumber": null,
"submissionDate": null,
"theftLoss_DiscoveredDate": null,
"theftLoss_Type": null,
"theftLoss_ATFIssuedIncidentNumber": null,
"theftLoss_PoliceIncidentNumber": null,
"destroyed_Date": null,
"destroyed_Description": null,
"destroyed_Witness1": null,
"destroyed_Witness2": null,
"deleteType": null,
"deleteNote": null,
"acquisitionType": "Purchase",
"acquire_Date": "2021-01-10T20:03:06",
"acquire_License": "158067072A90327",
"acquire_LicenseName": "GLOCK INC",
"acquire_LicenseExpires": "2022-01-01T00:00:00",
"acquire_TradeName": null,
"acquire_Organization": null,
"acquire_FirstName": null,
"acquire_MiddleName": null,
"acquire_LastName": null,
"acquire_Address1": "6000 HIGHLANDS PKWY",
"acquire_Address2": null,
"acquire_City": "SMYRNA",
"acquire_State": "GA",
"acquire_Postal": "300820000",
"acquire_Country": "US",
"acquire_PhoneNumber": "7704321202",
"acquire_Fax": null,
"acquire_EmailAddress": null,
"acquire_PurchaseOrderNumber": null,
"acquire_InvoiceNumber": null,
"acquire_ShipmentTrackingNumber": null,
"id": "feea44a3-2f2d-4af3-9a68-acad001234f0",
"externalId": null,
"itemNumber": "00036",
"status": 3,
"statusText": "Disposed",
"manufacturer": "Glock",
"countryOfManufacture": "Austria",
"importer": "Glock INC",
"type": "Pistol",
"model": "17",
"caliber": "9X19",
"serial": "FPR266",
"barrelLength": null,
"overallLength": null,
"condition": null,
"location": null,
"cost": null,
"price": 499.99,
"mpn": "PI1750203",
"upc": "76450350210",
"sku": "PI1750203"
}
}
Verifying Authenticity
While optional, verifying the authenticity of webhooks is recommended.
FastBound digitally signs every event sent to your webhook URL with a hash-based message authentication code (HMAC), which is is a message authentication code (MAC) involving a cryptographic hash function and a secret key. The computed HMAC can be used to simultaneously verify both the integrity and the authenticity of the event.
When a new webhook is added to a FastBound account, FastBound returns a random, 256-bit secret key. If you want to verify the authenticity of a webhook coming from FastBound, you must save this secret as you will not be able to retrieve it later.
Webhooks will only be delivered to HTTPS URLs and the webhook URL must be unique per FastBound account. In other words, if you want to receive more than one event at the same Webhook URL, your webhook must subscribe to more than one event.
When a subscribed event occurs in FastBound, FastBound will send an HTTP POST request to your app, with a JSON-formatted message body. The request will contain an X-FastBound-Signature header.
To verify the signature sent by FastBound:
-
Prepend the JSON payload with the timestamp (t) and a period (ASCII 46, 0x2E)
-
Compute an HMAC-SHA256 hash using the secret key returned at the time the webhook was created
Note: JSON libraries vary greatly. You should compute the signature on the raw bytes received in the POST body. Computing a signature on a JSON object after it has passed through a serializer may result in a different hash and verification of the signature will fail.
Example
If you paste the following values into an HMAC-SHA256 tool like https://www.stupidtools.net , you will be able to compute the same signature
Example Key
4pUkLdAvI4CzJbKZcJoNM2VIE86ItLn4
Example Headers
POST /path/to/my/webhook HTTP/1.1
Content-Length: 2080
Content-Type: application/json
X-FastBound-Signature: t=1610834911,v1=fe21f400de69f00ef9c65e95eaa6e308766261d292ed981f1d1b5ad41dc8ac97
|
Key |
Value |
|
t |
UNIX timestamp in seconds when the Webhook event was created |
|
v1 |
HMAC-SHA256 signature of the JSON payload in the POST request. |
Note: The signature (v1) is 256-bits (32 bytes), encoded in hexadecimal (aka base 16 or hex), resulting in 64 bytes.
Example Plain Text / Message
Note: The timestamp and period has been prepended to the original JSON body. The timestamp and period will NOT be in the body of the webhook.
1610834911.{"id":"31cee3bf-2abe-466d-bb73-65129edd1ebd","eventName":"item.edited","accountNumber":75114,"timestampUtc":"2021-01-16T22:08:31.367926Z","data":{"dispositionType":null,"dispose_Date":null,"dispose_License":null,"dispose_LicenseName":null,"dispose_LicenseExpires":null,"dispose_TradeName":null,"dispose_Organization":null,"dispose_FirstName":null,"dispose_MiddleName":null,"dispose_LastName":null,"dispose_Address1":null,"dispose_Address2":null,"dispose_City":null,"dispose_State":null,"dispose_Postal":null,"dispose_Country":null,"dispose_PhoneNumber":null,"dispose_Fax":null,"dispose_EmailAddress":null,"ttsn":null,"otsn":null,"dispose_PurchaseOrderNumber":null,"dispose_InvoiceNumber":null,"dispose_ShipmentTrackingNumber":null,"submissionDate":null,"theftLoss_DiscoveredDate":null,"theftLoss_Type":null,"theftLoss_ATFIssuedIncidentNumber":null,"theftLoss_PoliceIncidentNumber":null,"destroyed_Date":null,"destroyed_Description":null,"destroyed_Witness1":null,"destroyed_Witness2":null,"deleteType":null,"deleteNote":null,"acquisitionType":"Purchase","acquire_Date":"2018-06-11T21:11:00","acquire_License":null,"acquire_LicenseName":null,"acquire_LicenseExpires":null,"acquire_TradeName":null,"acquire_Organization":null,"acquire_FirstName":"Ben","acquire_MiddleName":null,"acquire_LastName":"Bacon","acquire_Address1":"2333 Black Oak Hollow Road","acquire_Address2":null,"acquire_City":"Sunnyvale","acquire_State":"CA","acquire_Postal":"94089","acquire_Country":null,"acquire_PhoneNumber":null,"acquire_Fax":null,"acquire_EmailAddress":null,"acquire_PurchaseOrderNumber":"PO","acquire_InvoiceNumber":"INVOICE","acquire_ShipmentTrackingNumber":"SHIPMENT","undeleteNote":null,"id":"440234a7-8bc1-45b5-bea2-a8fd00440b55","externalId":null,"itemNumber":"00001","status":2,"statusText":"Pending Disposal","manufacturer":"GLOCK","countryOfManufacture":"AUSTRIA","importer":"GLOCK INC","type":"Pistol","model":"17","caliber":"9MM","serial":"AAB1142","barrelLength":null,"overallLength":null,"condition":null,"location":null,"cost":null,"price":null,"mpn":null,"upc":null,"sku":null}}