This guide covers how to receive LASSO webhooks directly at your own endpoint (any HTTPS service, such as n8n, a serverless function, or your own backend) with no Zapier required, and how those webhooks are kept authentic. It covers Invoice, Quote, and Purchase Order events.
💡 About the samples: The payloads below are representative examples showing structure and field names. Exact values vary by account and record. You'll see your account's real payload when we run a test to your endpoint (see Setup & cutover).
⚠️ Prerequisite — V2 payloads (Invoice & PO): This guide describes the V2 invoice and PO payloads, which all new integrations use. If an account hasn't yet been moved to V2 for those events, that migration happens first (a one-time switch on LASSO's side) — the older V1 payloads have a different shape and are being retired.
Available events
Event | Area | When it fires |
| Invoice | A user clicks Send To Accounting on an invoice (manual) |
| Invoice | Automatically when a payment is recorded |
| Quote | A quote is created |
| Quote | A quote is sent to the customer |
| Quote | A quote is accepted |
| Purchase Order | A PO is created |
| Purchase Order | A PO is updated |
💡 In LASSO, purchase orders are represented as subrentals, hence the subrental.* event names.
Security
Webhooks are delivered over HTTPS to the endpoint you provide, so traffic is encrypted in transit. A couple of practices keep your integration secure:
Keep your endpoint URL private. Treat it like a credential — don't share or publish it.
Verify the signature before you go live. LASSO signs every webhook with an HMAC-SHA256 signature (sent in the
x-lasso-webhook-signatureheader) so you can confirm each request genuinely came from LASSO. You can set up and test your endpoint without signature verification, but it's required before going to production.
🔐 We're finalizing the exact signature-verification steps and will provide them — along with your signing secret — as part of go-live, so you can implement the check with confidence. Just reach out and we'll walk through it with you.
Invoice payload (invoice.create, V2)
{
"webhookVersion": 2,
"invoiceNumber": "INV-2026-0512",
"invoiceType": "Reconcile",
"invoiceDate": "2026-07-01T00:00:00.000Z",
"dueDate": "2026-07-31T00:00:00.000Z",
"terms": 30,
"customer": "Acme Corp",
"email": "[email protected]",
"billingAddress": "123 Main St, Nashville, TN 37203",
"shippingAddress": "Music City Center, 201 Rep. John Lewis Way S, Nashville, TN 37203",
"eventCode": "EVT-10432",
"eventName": "Acme Corp Annual Gala",
"poNumber": "PO-7781",
"invoiceTotal": 6480.00,
"totalTax": 480.00,
"calculatedTax": 480.00,
"overriddenTax": 0,
"taxOverride": false,
"discountValueNum": 0,
"discountPercent": "0",
"percentageOfTotalToInvoice": 100,
"clientExternalCode": "ACME-001",
"eventExternalCode": "EVT-10432",
"venueExternalCode": "MCC",
"venueName": "Music City Center",
"sendLater": false,
"taxCode": "",
"messageDisplayedOnInvoice": "",
"messageDisplayedOnStatement": "",
"discountValue": "0",
"lineItems": [
{
"glCode": "4000",
"glCodeName": "Equipment Rental Revenue",
"glCodeDescription": "Gear rental",
"glCodeSum": 5000.00,
"preDiscountAmount": 5000.00,
"taxable": true,
"isDeposit": false
},
{
"glCode": "2100",
"glCodeName": "Customer Deposits (Liability)",
"glCodeDescription": "Prior deposit applied",
"glCodeSum": -2000.00,
"preDiscountAmount": -2000.00,
"taxable": false,
"isDeposit": true,
"depositInvoiceId": 88123,
"depositInvoiceNumber": "INV-2026-0480"
}
]
}
Notes:
lineItemsare GL-code sums (not raw line items) — each is a GL account with its summed amount, which is what makes the payload accounting-ready.Deposit / reconciliation fields (
isDeposit,depositInvoiceId,depositInvoiceNumber) are the V2 additions: a reconciliation invoice can reference the prior deposit it draws down, so deposits can post to a liability account instead of revenue.invoiceTypeis one of Deposit, Reconcile, or Additional.The fields
sendLater,taxCode,messageDisplayedOnInvoice,messageDisplayedOnStatement, anddiscountValueare retained for back-compat and come through empty/zero in V2 (shown above) — usediscountValueNumfor the numeric discount.
💡 invoice.payment_recorded is a separate, minimal event — its body is just { "id": <invoicePaymentId> }. Use that id to fetch full payment detail via the API.
Quote payload (quote.create / quote.sent / quote.accepted)
{
"event_type": "quote.accepted",
"quote_id": 48213,
"quote_uuid": "3f2c9a10-7b44-4e2e-9c1a-2b6d5e8f0a11",
"quote_number": "Q-2026-0347",
"quote_status": "accepted",
"quote_total": 12500.00,
"quote_tax": 925.00,
"quote_discount": 500.00,
"event_code": "EVT-10432",
"event_name": "Acme Corp Annual Gala",
"venue_name": "Music City Center",
"customer_name": "Acme Corp",
"customer_email": "[email protected]",
"accepted_at": "2026-07-01T15:22:00.000Z",
"db_date_created": "2026-06-20T18:05:00.000Z",
"webhookVersion": 1
}
Notes:
All three quote events share this shape;
event_typeandquote_statustell you the stage.accepted_atis populated only onquote.accepted(otherwisenull).quote_idis the internal id;quote_uuidis the stable external identifier.Monetary values are numbers; dates are ISO-8601 strings.
Quote keys are
snake_case— note this differs from the invoice payload'scamelCase.
Purchase Order payload (subrental.create / subrental.update, V2)
{
"action": "create",
"timestamp": "2026-07-01T16:40:00.000Z",
"version": "2.0",
"webhookData": {
"subrentalId": 90741,
"poNumber": "PO-2026-0231",
"poName": "LED Wall — Acme Gala",
"status": "approved",
"gearStatus": "pending",
"vendorName": "Bright AV Rentals",
"vendorCode": "VEND-0087",
"vendorExternalCode": "BAR-991",
"eventName": "Acme Corp Annual Gala",
"eventCode": "EVT-10432",
"eventExternalCode": "ACME-EVT-1",
"totalCost": 8200.00,
"deliveryDate": "2026-07-18T00:00:00.000Z",
"returnDate": "2026-07-22T00:00:00.000Z",
"warehouse": "Nashville Main",
"shipOption": "Vendor Delivery",
"shippingAddress": "Music City Center, 201 Rep. John Lewis Way S, Nashville, TN 37203"
},
"webhookGlCodeSums": [
{
"glCode": "5000",
"glCodeName": "Subrental / COGS",
"glCodeDescription": "Outside equipment rental",
"glCodeSum": 8200.00
}
]
}
Notes:
The V2 PO payload wraps everything in
action/timestamp/version("2.0") /webhookData/webhookGlCodeSums.subrentalIdis the only internal numeric id.For vendor and event, both the LASSO-stable code (
vendorCode/eventCode) and the customer-supplied external reference (vendorExternalCode/eventExternalCode) are included.status= PO status;gearStatus= fulfillment / gear state.The
timestampinside the payload is informational (when the PO event occurred).Any field may be
nullwhere not applicable.
Setup & cutover
What you provide:
Your production endpoint URL- any HTTPS endpoint that should receive these events (e.g. an n8n webhook URL, a serverless function, or your own backend).
Which events you want (from the table above).
What LASSO Support does:
Registers those webhooks against your URL. For invoice/PO, LASSO Support confirms the account is on V2- migrating it first if needed. When you're ready to go live, LASSO Support provides your signing secret and the signature-verification steps.
What you do:
Stand up your receiver- any HTTPS endpoint that accepts a POST.
Test together: performing the triggering action (e.g. Send To Accounting on an invoice, or creating a test quote/PO) delivers a live event to your endpoint- this is where you'll see your account's real payload.
Before go-live, add signature verification using the steps LASSO Support provides.
Cutover:
Once your endpoint is confirmed, LASSO Support deactivates the Zapier hook for that event, leaving a single active destination- at which point you're fully off Zapier for it.
