Skip to content

Webhooks

Webhooks let QSign push events to your server the moment something happens — instead of you polling status.

Save your HTTPS endpoint in the Developer portal or with POST https://app.qsig.in/backend/othercompanyapi/webhook/save/. This account-management call uses the api_admin login JWT in Authorization: Bearer <token>, rather than the X-Api-Key used for envelope calls:

Terminal window
curl -X POST 'https://app.qsig.in/backend/othercompanyapi/webhook/save/' \
-H 'Authorization: Bearer <api-admin-login-jwt>' \
-H 'Content-Type: application/json' \
-d '{"webhook_url":"https://example.com/qsign/webhook"}'

The URL must be public HTTPS. Store the returned webhook_secret securely.

Every envelope delivery carries X-QSign-Timestamp and X-QSign-Signature. The signature is sha256= followed by the HMAC-SHA256 hex digest of timestamp + "." + raw_body. Verify it before trusting the payload:

import hmac, hashlib
signed = timestamp.encode() + b"." + raw_body
expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
assert any(hmac.compare_digest(expected, candidate.strip())
for candidate in received_signature.split(","))

Reject stale timestamps and duplicate X-QSign-Event-Id values in your receiver. During secret rotation the signature header may contain more than one candidate. Reveal or rotate the secret in the Developer portal. Respond 2xx quickly; QSign records every delivery attempt (event, target URL, attempts, status code, success) so you can inspect failures.

Use Send test event in the Developer portal to fire a synthetic webhook.test payload at your endpoint — it shows up in the delivery log like any real event.