Webhooks

TenderLock can call your HTTPS endpoint when something happens. Add endpoints in Settings → API & MCP (Professional and Enterprise).

Events

EventWhen
tender.publishedA tender is published to suppliers
tender.closedA tender reaches its closing date
submission.receivedA supplier submits or resubmits a bid
clarification.raisedA supplier asks a clarification question
award.approvedAn award is approved
tender.no_awardA tender is closed with no award
tender.cancelledA 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.

Before you renew. Before you appoint. Before you buy.
TenderLock it.

Run your first live tender free. No card required.