Integrations · Pro Max
Connect BidSparq to Zapier, Make & anything else
Webhooks let BidSparq POST a signed JSON event to any HTTPS endpoint the moment something happens — a new high-scored RFP, an approaching deadline. Wire that into Zapier, Make.com, n8n, Pipedream, or your own server and automate the rest.
What gets sent
- High-scored new matches — when an RFP scoring 80+ against your profile is posted.
- Pursuit deadline alerts— when a tracked pursuit is due within 7 days and you haven't submitted yet.
More events (pursuit won/lost, stage changes) are rolling out. Pick which events each endpoint receives in Settings → Notifications.
Quick start with Zapier
- In Zapier, create a new Zap and choose Webhooks by Zapier → Catch Hook as the trigger.
- Zapier gives you a Custom Webhook URL like
https://hooks.zapier.com/hooks/catch/…. Copy it. - In BidSparq, go to Settings → Notifications → Add endpoint. Paste the URL, pick your events, and create.
- Copy the signing secret shown once (optional but recommended — use it to verify authenticity).
- Click Send test in BidSparq, then in Zapier click Test trigger — you'll see the sample event. Map its fields to whatever action you want (Slack message, Asana task, Google Sheet row, CRM update…).
The same flow works for Make.com (Custom Webhook module), n8n (Webhook node), and Pipedream (HTTP trigger). Anywhere that gives you a catch URL.
Event payload
Every event is a JSON POST with this envelope:
{
"id": "evt_01HX5G2K3M4N5P6Q7R8S9T0V1W",
"type": "high_score_match",
"event_version": "v1",
"occurred_at": "2026-05-27T14:32:18.471Z",
"contractor_id": "cmpm8b…",
"data": {
"rfp_id": "abc123",
"rfp_url": "https://bidsparq.com/rfp/abc123",
"title": "Cybersecurity Assessment Services",
"agency": "Department of Veterans Affairs",
"state": "VA",
"due_date": "2026-06-30T17:00:00.000Z",
"ai_score": 87,
"estimated_value_cents": 250000000,
"set_aside": "8(a)"
}
}These HTTP headers accompany every request:
webhook-id: evt_01HX5G2K3M4N5P6Q7R8S9T0V1W
webhook-timestamp: 1716816738
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=Verifying the signature
We follow the Standard Webhooks spec. To verify: HMAC-SHA256 the string id.timestamp.rawBody with your signing secret (base64-decoded after the whsec_ prefix), then compare to the webhook-signature header.
Node.js
import crypto from "node:crypto";
function verify(rawBody, headers, secret) {
const id = headers["webhook-id"];
const ts = headers["webhook-timestamp"];
const sigHeader = headers["webhook-signature"]; // "v1,<base64>"
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected =
"v1," +
crypto.createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest("base64");
// constant-time compare against any space-delimited candidate
return sigHeader.split(" ").some((c) =>
c.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(c), Buffer.from(expected)));
}Python
import base64, hmac, hashlib
def verify(raw_body: bytes, headers: dict, secret: str) -> bool:
msg_id = headers["webhook-id"]
ts = headers["webhook-timestamp"]
sig_header = headers["webhook-signature"] # "v1,<base64>"
key = base64.b64decode(secret.replace("whsec_", ""))
signed = f"{msg_id}.{ts}.{raw_body.decode()}".encode()
expected = "v1," + base64.b64encode(hmac.new(key, signed, hashlib.sha256).digest()).decode()
return any(hmac.compare_digest(c, expected) for c in sig_header.split(" "))Tip: verify against the raw request body bytes — re-serializing the parsed JSON changes whitespace and breaks the signature. Also reject events whose webhook-timestamp is more than ~5 minutes old to block replay attacks.
Delivery & retries
- We retry failed deliveries up to 6 times over ~7.5 hours with exponential backoff.
- Return any
2xxstatus to acknowledge. Return410 Goneto permanently unsubscribe an endpoint. - Each event carries a stable
webhook-idacross retries — use it as an idempotency key so you never process the same event twice. - After repeated failures an endpoint is auto-paused; resume it anytime from Settings → Notifications.
- See the last 20 deliveries (status, attempts, errors) per endpoint in the same settings page.
Webhooks are a Pro Max feature.
Add your first endpoint →