Webhooks
Register an endpoint to receive push notifications as each carrier finishes, when a job needs agent input, and when a run completes. Because runs take minutes, webhooks are the preferred integration path; polling remains available as a fallback.
Register a Webhook
POST /v1/webhooks
Authorization: Bearer qs_live_xxxxx
Content-Type: application/json{
"url": "https://partner.example.com/hooks/quotesweep",
"events": [
"job.completed",
"quote.action_required",
"quote.completed",
"quote.failed"
]
}Response 201 Created
{
"success": true,
"data": {
"id": "wh_01HV...",
"status": "active",
"secret": "whsec_xxxxxxxxxxxx"
}
}The signing secret is returned once, at registration. Store it securely.
Events
| Value | Description |
|---|
job.completed
{
"event": "job.completed",
"quoteRequestId": "qr_01HV...",
"externalReference": "0065f00000ABCDE",
"jobId": "job_01HV...",
"carrierId": "carrier-a",
"lineOfBusiness": "bop",
"status": "success",
"result": {
"annualPremium": 12450.22,
"quoteNumber": "CARR-884213"
},
"timestamp": "2026-08-25T14:07:31Z"
}quote.action_required
{
"event": "quote.action_required",
"quoteRequestId": "qr_01HV...",
"externalReference": "0065f00000ABCDE",
"jobId": "job_02HV...",
"carrierId": "carrier-b",
"actionRequired": {
"type": "mfa",
"message": "Carrier sent a verification code to the agent's phone",
"deepLink": "https://app.quotesweep.com/quotes/qr_01HV.../jobs/job_02HV..."
},
"timestamp": "2026-08-25T14:06:10Z"
}quote.completed
{
"event": "quote.completed",
"quoteRequestId": "qr_01HV...",
"externalReference": "0065f00000ABCDE",
"status": "partial",
"summary": {
"carriersRequested": 5,
"quotesReturned": 3,
"lowestAnnualPremium": 12450.22,
"failedCount": 1,
"actionRequiredCount": 1
},
"timestamp": "2026-08-25T14:09:52Z"
}Every payload carries quoteRequestId and externalReference, so events can be correlated back to the originating record without holding local state.
Verification
Each request includes an X-QuoteSweep-Signature header. Compute HMAC-SHA256(raw_body, webhook_secret) and compare against it using a constant-time comparison before trusting the payload.
import hmac, hashlib
def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)Retry Policy
Failed deliveries retry up to three times with exponential backoff (5s, 30s, 5min). Respond 2xx to acknowledge.
Acknowledge quickly
Return a 2xx within 5 seconds and process the payload asynchronously. Delivery is at-least-once, so handlers must be idempotent — key on jobId for job events and quoteRequestId for request events.