Verify signature
contiguity.webhook.verify(rawBody, signatureHeader, secret, toleranceSeconds?)
- rawBody: The exact raw request body (string or buffer). Never re-serialize JSON (e.g. do not use
JSON.stringify(req.body)). - signatureHeader: Value of the
Contiguity-Signatureheader. Format:t=<timestamp>,v1=<hex>. - secret: Your webhook signing secret.
- toleranceSeconds: Optional. If set (e.g.
300), rejects if|now - t| > toleranceSeconds.
true if the signature is valid, false otherwise. Verification uses HMAC-SHA256 of t + "." + raw_body with the secret and constant-time comparison to v1.
Parse payload
contiguity.webhook.parse(rawBody)
Parses the raw body as JSON and validates id, type, timestamp. Returns a typed event (v2 format). Throws if invalid.
Example
Webhook payload format (v2)
All events include:- id: string (e.g.
evt_...) - type: string (event type)
- timestamp: number (Unix)
- api_version: string
- data: object (event-specific)
text.incoming.sms, text.incoming.mms, text.delivery.confirmed, text.delivery.failed, imessage.incoming, numbers.substitution, otp.reverse.verified, email.incoming, identity.verification_session.started, identity.verification_session.processing, identity.verification_session.verified, identity.verification_session.failed, identity.verification_session.requires_input, identity.verification_session.manually_approved, identity.verification_session.manually_denied, identity.verification_report.generated.
Signing reference
- Signed payload:
t + "." + raw_body(timestampt+.+ raw body). - Algorithm: HMAC-SHA256.
- Signature: hex-encoded in header as
t=<t>,v1=<hex>. - Verification: Compute HMAC-SHA256 of signed payload with webhook secret; compare to
v1with constant-time comparison. Optionally enforce timestamp tolerance (e.g. 300 seconds).
