Subscribing to events

Written by Jarad on March 20, 2023

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.

  1. Browse to Settings > Webhooks in FastBound.

  2. Tap the + Webhook button.

  3. Enter a Name and URL for your Webhook and choose the Events to which you’d like to subscribe. Description is optional.

  4. 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:

  1. Prepend the JSON payload with the timestamp (t) and a period (ASCII 46, 0x2E)

  2. 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}}