Agent payloads
Each agent type receives a requestMetadata.payload object in the webhook request body containing the full context of the current view. The payload structure depends on the agent type. All payloads reflect the state of the object at the moment the agent dialog is opened.
Webhook body structure
The top-level body sent to the webhook has the following fields:
| Field | Description |
|---|---|
type | The agent type that triggered the request (for example SALES_HUB_ORDER_EDITOR) |
adminUserId | The backoffice user who triggered the agent |
requestMessage | The user's message. Present for chat agents, absent for button agents |
conversationId | Present for follow-up messages in multi-turn conversations |
requestMetadata.payload | The full page context. Structure varies by agent type (see below) |
Tender payload
Used by SALES_HUB_QUOTE_EDITOR, SALES_HUB_ORDER_EDITOR and SALES_HUB_QUOTE_REQUEST_EDITOR. Contains the full Tender object for the currently open quote, order or request.
Top-level fields
| Field | Type | Description |
|---|---|---|
tenderId | String | Primary identifier for the tender |
orderId | Int | Order ID |
status | String | Current order status (for example QUOTATION, NEW, VALIDATED) |
channelId | Int | Sales channel ID |
source | String | Order origin (for example Sales Portal, Webshop) |
email | String | Contact email |
debtorId | String | Debtor identifier |
invoiceUserId | Int | Invoice user ID |
userId | Int | User ID |
shopId | Int | Shop ID |
createdAt | DateTime | Creation timestamp |
reference | String? | Customer reference |
remarks | String? | Customer remarks |
externalId | String? | External system ID |
validUntil | DateTime? | Quote expiry date |
actionCode | String? | Action code |
creditPoints | Int? | Credit points |
valuePoints | Int? | Value points |
incentivesApplied | Boolean? | Whether incentives have been applied |
Contact
| Field | Type | Description |
|---|---|---|
contactId | Int | Contact ID |
firstName | String | First name |
middleName | String | Middle name |
lastName | String | Last name |
email | String | Email address |
phone | String | Phone number |
primaryLanguage | String | Language code (for example NL) |
company | Object | Nested company with taxNumber and cocNumber |
pricesheets | Array | Assigned pricesheets |
purchaseAuthorizationConfigs | Object | Purchase authorization configuration |
Company
| Field | Type | Description |
|---|---|---|
companyId | Int | Company ID |
name | String | Company name |
pricesheets | Array | Assigned pricesheets with localized names |
addresses | Array | Company addresses (delivery and invoice) |
Addresses
The deliveryAddress and invoiceAddress objects share the same structure:
| Field | Type | Description |
|---|---|---|
firstName | String | First name |
middleName | String | Middle name |
lastName | String | Last name |
company | String | Company name |
street | String | Street name |
number | String | House number |
numberExtension | String | House number extension |
postalCode | String | Postal code |
city | String | City |
region | String? | Region or province |
country | String | Country code (for example NL, CN) |
email | String | |
phone | String | Phone |
mobile | String? | Mobile phone |
gender | String | Gender code |
icp | String | Intra-community delivery flag (Y or N) |
Items
The items array contains TenderMainItem objects representing order line items. Each main item can have childItems (accessories, options, surcharges) as TenderBaseItem objects.
TenderMainItem fields:
| Field | Type | Description |
|---|---|---|
orderItemId | Int | Order item ID |
uuid | String | Unique item identifier |
productId | Int | Product ID |
name | String | Product name |
sku | String | SKU |
quantity | Int | Quantity |
price | String | Unit price |
priceNet | Number | Unit price including tax |
originalPrice | Number | Original list price |
costPrice | Number | Cost price |
customerPrice | Number | Customer-specific price |
customerDiscountPercentage | Number | Customer discount percentage |
discountPercentage | String | Line item discount percentage |
marginAmount | Number | Margin amount (price minus cost price) |
marginPercentage | Number | Margin percentage |
saleMarginAmount | Number | Sale margin amount |
saleMarginAmountSum | Number | Sale margin amount including child items |
saleMarginPercentage | Number | Sale margin percentage |
saleMarginPercentageSum | Number | Sale margin percentage including child items |
attributedSaleDiscount | Number | Attributed sale discount |
attributedSaleDiscountSum | Number | Attributed sale discount including child items |
attributedSaleMargin | String | Attributed sale margin |
attributedSaleMarginSum | Number | Attributed sale margin including child items |
totalPrice | Number | Total price (quantity × price) |
totalPriceNet | Number | Total price including tax |
sum | Number | Sum including child items |
sumNet | Number | Sum including child items and tax |
totalSum | Number | Total sum |
totalSumNet | Number | Total sum including tax |
totalDiscountPercentage | Number | Total discount percentage |
totalDiscountPercentageSum | Number | Total discount percentage including child items |
taxCode | String | Tax code (for example H for high, N for none) |
taxPercentage | Number | Tax percentage |
supplier | String | Supplier name |
supplierCode | String | Supplier product code |
notes | String | Item notes |
priority | Int | Sort priority |
expectedDeliveryDate | DateTime? | Expected delivery date |
incentive | Object? | Applied incentive |
surcharges | Array | Surcharges on the item |
valuePoints | Int? | Value points |
childItems | Array | Child items (accessories, options, surcharges) |
Product details (nested under each item):
| Field | Type | Description |
|---|---|---|
product.productId | Int | Product ID |
product.unit | Int | Unit |
product.minimumQuantity | Int | Minimum order quantity |
product.inventory.totalQuantity | Int | Total available stock |
product.hasBundle | String | Whether the product has a bundle (Y or N) |
product.isBundleLeader | String | Whether the product is a bundle leader (Y or N) |
product.bundles | Array | Available bundles with items |
product.crossupsellsFrom.itemsFound | Int | Number of cross/upsell products |
product.cluster | Object? | Cluster (configurable product) with names, SKU, options |
product.media.images | Object | Product images with URLs |
TenderBaseItem (child items) has the same pricing and margin fields as TenderMainItem but without childItems, priority, product details and surcharges.
Bonus items
The bonusItems array contains bonus products added by incentive rules. Empty when no incentives are applied.
Carriers
| Field | Type | Description |
|---|---|---|
name | String | Carrier name |
id | Int | Carrier ID |
amount | Number | Shipping cost amount |
description | String? | Carrier description |
logo | String? | Carrier logo URL |
Payment methods
| Field | Type | Description |
|---|---|---|
code | String | Payment method code (for example IDEAL, INVOICE) |
externalCode | String | External payment method code |
type | String | Type (for example payment) |
description | String | Display name |
amount | Number | Transaction cost |
allowed | Boolean | Whether the method is allowed for this order |
Payment data
| Field | Type | Description |
|---|---|---|
method | String | Selected payment method |
overruled | String | Whether the transaction cost is overruled (Y or N) |
price | Number | Transaction cost (gross) |
priceNet | Number | Transaction cost (net) |
tax | Number | Tax amount |
taxPercentage | Number | Tax percentage |
status | String | Payment status (for example UNKNOWN) |
statusDate | DateTime? | Payment status date |
accountingId | String? | Accounting reference |
Postage data
| Field | Type | Description |
|---|---|---|
carrier | String? | Selected carrier name |
method | String | Delivery method |
overruled | String | Whether shipping cost is overruled (Y or N) |
price | Number | Shipping cost (gross) |
priceNet | Number | Shipping cost (net) |
taxPercentage | Number | Tax percentage |
partialDeliveryAllowed | String | Whether partial delivery is allowed (Y or N) |
pickUpLocationId | Int? | Pick-up location ID |
requestDate | DateTime? | Requested delivery date |
warehouse | String? | Warehouse |
Totals
| Field | Type | Description |
|---|---|---|
subTotalGross | Number | Subtotal (gross) |
subTotalNet | Number | Subtotal (net, including tax) |
totalGross | Number | Total (gross, including shipping and payment) |
totalNet | Number | Total (net, including tax, shipping and payment) |
totalTax | Number | Total tax amount |
discountGross | Number | Total discount (gross) |
discountNet | Number | Total discount (net) |
discountPercentage | Number | Discount percentage |
discountOverruled | String? | Whether discount is overruled |
Revisions
| Field | Type | Description |
|---|---|---|
itemsFound | Int | Total number of revisions |
items[].revisionNumber | Int | Revision number |
items[].createdAt | DateTime | Revision creation timestamp |
items[].createdByAdminUser | Object? | Admin user who created the revision (firstName, middleName, lastName) |
items[].createdByContact | Object? | Contact who created the revision |
items[].createdByCustomer | Object? | Customer who created the revision |
items[].snapshot.status | String | Order status at time of revision |
items[].snapshot.type | String | Order type at time of revision |
items[].snapshot.public | Boolean | Whether the revision was public |
Example tender payload
A trimmed example showing the key structure. Actual payloads contain all fields listed above.
{
"type": "SALES_HUB_ORDER_EDITOR",
"adminUserId": 205,
"requestMessage": "can you give me advice how to increase the order value?",
"requestMetadata": {
"payload": {
"tenderId": "019d026b-99ce-7b94-b5cd-f5d436d23f78",
"orderId": 3043,
"status": "VALIDATED",
"channelId": 1,
"source": "Sales Portal",
"email": "wouter@example.nl",
"contact": {
"contactId": 14780,
"firstName": "Wouter",
"lastName": "Smrkovsky",
"email": "wouter@example.nl",
"phone": "0592343043",
"primaryLanguage": "NL",
"company": {
"taxNumber": "NL001607480B01",
"cocNumber": "02009131"
},
"pricesheets": []
},
"company": {
"companyId": 308,
"name": "M&G Group",
"pricesheets": [
{
"names": [{ "language": "NL", "value": "Contract M&G Group" }]
}
],
"addresses": [
{
"street": "Burgemeester Grollemanweg",
"number": "14",
"postalCode": "9405TN",
"city": "Assen",
"country": "NL",
"type": "delivery"
}
]
},
"deliveryAddress": {
"street": "Burgemeester Grollemanweg",
"number": "14",
"postalCode": "9405TN",
"city": "Assen",
"country": "NL"
},
"items": [
{
"orderItemId": 29054,
"name": "La Marzocco Linea Mini – Yellow",
"sku": "2400015",
"quantity": 1,
"price": "4796.55",
"costPrice": 3650,
"customerPrice": 4796.55,
"marginAmount": 1146.55,
"marginPercentage": 31.41,
"saleMarginPercentage": 23.90,
"saleMarginPercentageSum": 35.36,
"supplier": "Intern",
"taxCode": "H",
"taxPercentage": 21,
"product": {
"productId": 1020,
"inventory": { "totalQuantity": 282 },
"hasBundle": "N",
"crossupsellsFrom": { "itemsFound": 0 },
"cluster": {
"clusterId": 74,
"names": [{ "value": "La Marzocco Linea Mini", "language": "NL" }],
"sku": "LAMALIMI"
}
},
"childItems": [
{
"orderItemId": 29055,
"name": "Walnut set for the Linea Mini",
"sku": "1000121",
"quantity": 1,
"price": 585.37,
"costPrice": 423.56,
"marginAmount": 161.81,
"marginPercentage": 38.20,
"taxCode": "H",
"taxPercentage": 21
}
]
}
],
"bonusItems": [],
"carriers": [
{ "name": "DHL", "id": 8, "amount": 2.36 },
{ "name": "PostNL", "id": 2, "amount": 4.50 }
],
"payMethods": [
{ "code": "IDEAL", "description": "Ideal | Wero", "amount": 0, "allowed": true },
{ "code": "INVOICE", "description": "Betalen via factuur", "amount": 0, "allowed": true }
],
"paymentData": {
"method": "",
"overruled": "N",
"price": 35,
"priceNet": 42.35,
"status": "UNKNOWN",
"taxPercentage": 21
},
"postageData": {
"carrier": null,
"method": "",
"overruled": "N",
"price": 10,
"priceNet": 12.10,
"taxPercentage": 21,
"partialDeliveryAllowed": "Y"
},
"total": {
"subTotalGross": 6246.94,
"subTotalNet": 7558.80,
"totalGross": 6291.94,
"totalNet": 7613.25,
"totalTax": 1321.31,
"discountGross": 0,
"discountNet": 0,
"discountPercentage": 0
},
"revisions": {
"itemsFound": 4,
"items": [
{
"revisionNumber": 4,
"createdAt": "2026-03-18T19:11:03.197Z",
"createdByAdminUser": {
"firstName": "Jasper",
"lastName": "Pardijs"
},
"snapshot": {
"status": "VALIDATED",
"type": "dropshipment",
"public": true
}
}
]
}
}
}
}
Company payload
Used by SALES_HUB_COMPANY. Contains the company object for the currently open company detail page.
| Field | Type | Description |
|---|---|---|
companyId | Int | Company ID |
name | String | Company name |
debtorId | String? | External billing ID |
cocNumber | String? | Chamber of Commerce number |
taxNumber | String? | VAT/tax number |
email | String? | |
phone | String? | Phone |
tag | String? | Classification tag |
addresses | Array | Company addresses |
Example company payload
{
"type": "SALES_HUB_COMPANY",
"adminUserId": 205,
"requestMessage": "summarize this company",
"requestMetadata": {
"payload": {
"companyId": 11888,
"name": "Acme Corp B.V.",
"debtorId": null,
"cocNumber": null,
"taxNumber": null,
"email": null,
"phone": null,
"tag": null,
"addresses": [
{
"street": "Industrieweg",
"number": "42",
"postalCode": "3846 BD",
"city": "Harderwijk",
"country": "NL",
"isDefault": "N"
}
]
}
}
}
Products payload
Used by BACKOFFICE_PRODUCTS. Contains a summary of the current product list view.
| Field | Type | Description |
|---|---|---|
totalItems | Int | Total number of products and clusters matching the current filter |
Example products payload
{
"type": "BACKOFFICE_PRODUCTS",
"adminUserId": 205,
"requestMessage": "how many products do we have?",
"requestMetadata": {
"payload": {
"totalItems": 12185
}
}
}
Custom frontend payloads
Custom agent types (for example WEBSHOP_PRODUCT_DETAIL or CUSTOMER_PORTAL_ORDERS) have no fixed payload structure. You build the requestMetadata.payload yourself with whatever data your webhook needs. See Embedding agents in your frontend for details.
Response format
The webhook must return a JSON object with the following fields:
| Field | Description |
|---|---|
conversationId | Echoed back to link the response to the conversation |
responseMessage | Text displayed to the user in the UI. Supports newlines for formatting |
responseMetadata | Optional structured data for the UI or downstream systems |
Example response
{
"conversationId": "4308",
"responseMessage": "Quote #3043 is approved.\n\nMargin: 28.34% (€1770.13)",
"responseMetadata": {
"processed": true,
"marginPercentage": "28.34",
"marginAmount": "1770.13",
"totalRevenue": "6246.94",
"totalCost": "4476.81",
"threshold": 20,
"timestamp": "2026-03-18T19:29:15.105Z"
}
}
See also
- Conversations for the conversation lifecycle
- Webhook integration for building the webhook backend
- Agent configuration for setting up agents and webhook credentials