Run your business
Notifications and integrations
Email your team about new quotes, export to CSV, and send quotes to Zapier, Make or your CRM.
Email notifications
Go to Notifications. Under Email recipients, add each address that should be emailed when a customer submits a quote, then click Save.
- Any address works. It doesn’t need a ConfigBid account, and a shared inbox like
sales@yourcompany.comcovers the whole team. - Leave the list empty to turn notifications off.
Customers get their own confirmation email automatically, as long as you collect their email on the quote info step.
CSV export
On the Quotes page, click Export CSV.
- Choose What to export:
- Quotes: one row per quote, with customer, project, status, order reference and totals. Good for a sales pipeline spreadsheet.
- Line items: one row per part or custom line on each quote. Good for accounting imports and “what are we selling most of” reports.
- Optionally set a From and To date.
- Click Download CSV.
The export uses whatever search and status filter you have set on the Quotes list, so you can export only Won quotes, for example. Draft quotes are never included. Amounts are plain numbers with no currency symbols, so they import cleanly into Excel, Google Sheets and QuickBooks.
Webhook
A webhook sends every newly submitted quote to another app as soon as it comes in. Use it to create a deal in your CRM, add a row to a Google Sheet, or post to Slack, through Zapier, Make or your own system.
Connect Zapier
Zapier’s webhook trigger needs a paid Zapier plan. Make’s works on its free plan.
- In Zapier, create a Zap with the trigger Webhooks by Zapier → Catch Hook. Copy the URL Zapier gives you.
- In ConfigBid, go to Notifications → Webhook. Paste the URL into Webhook URL.
- Turn on Send a webhook when a quote is submitted and click Save webhook.
- Click Send test. Zapier receives a test request; use it to finish setting up your Zap.
- Submit a real test quote from the configurator so Zapier can see a full quote, then map its fields to your next step.
Make works the same way with its Custom webhook module.
Rules for the URL
- It must start with
https://. - It must be reachable on the public internet. Addresses inside your office network are refused.
- ConfigBid doesn’t follow redirects. Use the final URL.
What gets sent
Each quote is sent as a JSON POST:
{
"event": "quote.submitted",
"id": "delivery-uuid",
"createdAt": "2026-10-19T14:03:11Z",
"data": {
"reference": "Q-4F2A9B7C",
"status": "submitted",
"submittedAt": "2026-10-19T14:03:10Z",
"expiresAt": "2026-11-18T14:03:10Z",
"customer": { "name": "Sam Lee", "email": "sam@example.com" },
"project": { "name": "Garage refit", "location": "Springfield" },
"totals": {
"subtotal": 2310.00,
"adjustments": [{ "label": "Out-of-area travel", "amount": 75.00 }],
"total": 2385.00,
"deposit": null,
"currency": "USD"
},
"lines": [
{ "sku": "DOOR_STEEL", "name": "Steel door panel", "category": "Door",
"qty": 1, "unitPrice": 499.00, "lineTotal": 499.00 }
],
"answers": [
{ "key": "door_type", "label": "Door type", "value": "auto", "display": "Automatic" }
],
"links": { "quote": "https://…", "pdf": "https://…", "admin": "https://…" }
}
}
The Send test button sends "event": "ping" with a short message instead of a quote.
Delivery and failures
- If your receiving app doesn’t respond within 5 seconds, or returns an error, ConfigBid tries twice more, a few seconds apart.
- Every delivery and every failure is logged in Activity, so you can see whether a quote reached your other system.
- A failed webhook never affects the customer. Their quote is still saved and emailed.
Verify the signature (for developers)
Each request includes an X-ConfigBid-Signature header so your server can confirm the request came from ConfigBid. Zapier and Make users can ignore it.
The header looks like t=1760882591,v1=5f2c…. v1 is an HMAC-SHA256 of "{t}.{raw request body}", keyed with your Signing secret. The secret is shown on the Notifications page (Show / Copy). Recompute it and compare:
import hashlib, hmac
def verify(secret: str, header: str, raw_body: bytes) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
expected = hmac.new(
secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(parts["v1"], expected)
const crypto = require("crypto");
function verify(secret, header, rawBody) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}
Use the raw body exactly as received, before any JSON parsing. To reject replayed requests, also check that t is within a few minutes of the current time. Each request also has X-ConfigBid-Event (quote.submitted or ping) and X-ConfigBid-Delivery (a unique ID, so you can ignore duplicates).
Rotate issues a new signing secret straight away. Update your receiving app at the same moment, because requests signed with the old secret will fail its check.