Webhooks
TenderLock can call your HTTPS endpoint when something happens. Add endpoints in Settings → API & MCP (Professional and Enterprise).
Events
| Event | When |
|---|---|
tender.published | A tender is published to suppliers |
tender.closed | A tender reaches its closing date |
submission.received | A supplier submits or resubmits a bid |
clarification.raised | A supplier asks a clarification question |
award.approved | An award is approved |
tender.no_award | A tender is closed with no award |
tender.cancelled | A tender is cancelled |
Payload
POST /your/endpoint
TenderLock-Event: submission.received
TenderLock-Signature: t=1791133355,v1=5f2b…
{
"id": "evt_9KfQ2…",
"type": "submission.received",
"created": "2026-10-04T17:02:35+00:00",
"data": { "tender_id": "…", "tender_title": "…", "supplier": "…", "version": 1 }
}
Bid contents are never included. Fetch details through the API after the closing date.
Verify the signature
Compute an HMAC-SHA256 of t + "." + raw body with your signing secret and compare it to v1. Reject requests older than 5 minutes.
import hmac, hashlib, time
def verify(secret, header, body):
parts = dict(p.split("=", 1) for p in header.split(","))
signed = f"{parts['t']}.{body}".encode()
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"]) and abs(time.time() - int(parts["t"])) < 300
Retries
Respond with any 2xx within 10 seconds. Failed deliveries are retried twice (after 5 and 10 minutes). Every attempt is shown in Settings → API & MCP.
