Receive real-time HTTP notifications when events occur on your Techspert account.
To start receiving webhooks, contact your Techspert representative to configure your endpoint URL and obtain your signing key for verifying signatures.
Once a webhook is configured for your account, Techspert will send an HTTP POST request to your endpoint URL whenever a call recording finishes processing. You can use these notifications to automate workflows, trigger downstream processing, or keep your own systems in sync with activity on your Techspert account.
Techspert sends a POST request to your endpoint with the following headers:
POST <your-endpoint-url>
Content-Type: application/json
X-Webhook-Signature: t=<unix-timestamp>,v1=<hmac-hex>
The request body is a JSON object containing the event payload.
Your endpoint must return a 2xx HTTP status code within the request timeout to be considered a successful delivery. Any other status code or a connection error will be treated as a failure and the delivery will be retried.
Events are delivered asynchronously. If your endpoint does not return a 2xx response, Techspert will retry the delivery automatically with exponential backoff (capped at 4 hours between attempts) for a maximum of 15 attempts. After 15 consecutive failures, the delivery is marked as permanently failed and will not be retried.
To avoid unnecessary retries, ensure your endpoint:
2xx status code.Every webhook delivery includes an X-Webhook-Signature header. You should verify this header on receipt to confirm the request genuinely originated from Techspert and has not been tampered with in transit.
The signature is an HMAC-SHA256 digest, computed using a signing key shared with you at setup. The header has the form:
X-Webhook-Signature: t=<unix-timestamp>,v1=<hmac-hex>
t — Unix timestamp (seconds) at the time of delivery.v1 — HMAC-SHA256 hex digest of the signed string., to extract the t and v1 values.., and the raw request body: <t>.<raw-body>.HMAC-SHA256 of that string using your signing key.v1 value using a constant-time comparison to prevent timing attacks.now - t is within your tolerance window (we recommend 5 minutes) to guard against replay attacks.Important: always verify against the raw request body bytes, not a re-serialised version of the parsed JSON, as key ordering may differ.
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhookSignature(
rawBody: string,
header: string,
signingKey: string,
toleranceSeconds = 300,
): boolean {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const timestamp = Number(parts['t']);
const expected = parts['v1'];
if (!timestamp || !expected) return false;
const now = Math.floor(Date.now() / 1000);
if (now < timestamp || now - timestamp > toleranceSeconds) {
return false; // Outside tolerance window — possible replay attack
}
const computed = createHmac('sha256', signingKey)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const computedBuffer = Buffer.from(computed, 'hex');
const expectedBuffer = Buffer.from(expected, 'hex');
if (computedBuffer.length !== expectedBuffer.length) {
return false;
}
return timingSafeEqual(computedBuffer, expectedBuffer);
}
If you need to rotate your signing key (e.g. as part of a security policy), contact Techspert to initiate a rotation.
When a rotation is performed:
Update your stored signing key before or at the cutover time to avoid verification failures.
2xx status code to acknowledge receipt.X-Webhook-Signature header before acting on the payload.Fired when a call has finished processing and associated files are available.
Note: Presigned URLs expire. Download files promptly after receiving the notification, before the
presigned_url_expirytimestamp.
| X-Webhook-Signature required | string Example: t=1715680800,v1=a3f9c2... HMAC-SHA256 signature for verifying request authenticity. See Verifying Signatures. |
| type required | string Value: "call_processing_complete" The event type identifier. |
| case_code_id required | string Your provided project identifier, or the Techspert identifier if not provided, for the project/case code associated with the call. |
| expert_id required | string The Techspert identifier for the expert on the call, this is unique to each expert & project, so will differ for the same person on another project. |
| expert_name required | string The display name of the expert. |
| call_timestamp required | string <date-time> The date and time the call took place (ISO 8601, UTC). |
required | Array of objects (CallProcessingCompleteFile) List of files available for download. |
{- "type": "call_processing_complete",
- "case_code_id": "PROJ-001",
- "expert_id": "22222222-2222-2222-2222-222222222222",
- "expert_name": "Jane Smith",
- "call_timestamp": "2026-05-14T10:00:00.000Z",
- "files": [
- {
- "asset_type": "transcription",
- "presigned_url_expiry": "2026-05-21T10:00:00.000Z"
}
]
}