Webhooks
Subscribe your own server to real-time 6X events (calls, SMS, verification, staff) via signed HTTP POST requests - setup, event list, signature verification, retries.
Webhooks
Instead of polling the API, webhooks push data to your server the moment something happens in your 6X account. When an event fires, 6X sends an HTTP POST request to your registered endpoint with a signed JSON payload. See the Webhooks product page for the full feature overview and FAQ.
Setting up a webhook
- Log into the Wholesale Portal.
- Go to Webhooks in the sidebar.
- Fill in your server URL, tick the events you want to receive, and click Create Webhook.
- Copy your Signing Secret — you'll need this to verify incoming requests. It's also always visible (partially masked, click to reveal) next to the endpoint afterward.
Available events
| Event | Fired when |
|---|---|
sms.inbound | An SMS arrives on one of your numbers |
sms.sent | An outbound SMS you sent is accepted by the carrier |
flash_verification.completed | A flash-call reachability check (via voice/flash-verify) finishes |
staff.clocked_in | A staff member clocks in |
staff.clocked_out | A staff member clocks out |
leave.requested | A leave request is submitted |
leave.approved | A leave request is approved |
leave.rejected | A leave request is rejected |
call.answered/call.missed/call.ended events aren't wired up yet for the current self-service Extensions/Ring Groups/Call Queues — a real, known gap, not an oversight. Chat, event-ticket, and gift-card webhook events also aren't available — if your integration needs any of these, contact support to let us know it's wanted.
Payload structure
Every webhook delivers the same envelope regardless of event type. wholesale_customer_id identifies your account (it's null on the rare legacy endpoint still keyed by business_id instead):
{
"event": "sms.inbound",
"timestamp": "2026-06-21T08:30:00+00:00",
"wholesale_customer_id": 42,
"business_id": null,
"data": {
"from": "+447911123456",
"to": "+447936508801",
"message": "Hello",
"message_id": "abc123"
}
}
Verifying the signature
Every request includes an X-6X-Signature header — an HMAC-SHA256 of the raw request body signed with your endpoint secret. Always verify this before processing the payload.
// PHP example
$payload = file_get_contents('php://input');
$signature = hash_hmac('sha256', $payload, $yourSigningSecret);
if (!hash_equals($signature, $_SERVER['HTTP_X_6X_SIGNATURE'] ?? '')) {
http_response_code(401);
exit('Invalid signature');
}
$event = json_decode($payload, true);
// Node.js example
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', signingSecret)
.update(rawBody)
.digest('hex');
if (sig !== req.headers['x-6x-signature']) {
return res.status(401).send('Invalid signature');
}
Responding to a webhook
Your endpoint must return a 2xx HTTP status within 10 seconds. If it does not, 6X marks the delivery as failed and retries up to 3 times with a 60-second backoff between attempts.
Delivery logs
Every delivery attempt is logged. Go to Webhooks in your portal, then click the delivery count next to any endpoint to see the full history including response codes, response body, and retry attempts.
Testing your endpoint
Click Test next to any registered endpoint to send a webhook.test event immediately. Use this to confirm your server is receiving and verifying requests correctly before going live.
Limits
| Limit | Value |
|---|---|
| Max endpoints per account | 5 |
| Delivery timeout | 10 seconds |
| Retry attempts | 3 |
| Retry backoff | 60 seconds |
Request headers sent by 6X
| Header | Value |
|---|---|
Content-Type | application/json |
X-6X-Signature | HMAC-SHA256 of the raw request body |
X-6X-Event | The event name e.g. sms.inbound |
User-Agent | 6X-Webhooks/1.0 |