Creating Your First Webhook
Prerequisites
- Application API Key
- A publicly accessible HTTPS endpoint (see tips for local development)
Step 1 — Prepare the endpoint
Create an endpoint on your server that accepts POST and returns 200:
app.post('/webhooks/chatt2me', (req, res) => {
const payload = req.body;
console.log('Event received:', JSON.stringify(payload, null, 2));
// Process the event here...
res.status(200).send('OK');
});
from flask import Flask, request
app = Flask(__name__)
@app.post('/webhooks/chatt2me')
def webhook():
payload = request.get_json()
print('Event received:', payload)
# Process the event here...
return 'OK', 200
Always return 200 as quickly as possible. If processing takes time, queue the payload and process it in the background — the Hub may consider the webhook as failed if the response takes too long.
Step 2 — Register the webhook
curl -X POST https://api.chatt2.me/v1/organization/webhook \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"label": "ReceivedMessages",
"endpoint": "https://your-server.com/webhooks/chatt2me",
"eventType": "Message",
"authenticationProtocol": "NoAuthentication"
}'
Registration fields
| Field | Required | Description |
|---|---|---|
label | ✅ | Descriptive name to identify the webhook in the Hub Chatt2.me dashboard |
endpoint | ✅ | HTTPS URL of your endpoint |
eventType | ✅ | Message or MessageStatus |
authenticationProtocol | ✅ | Authentication scheme Hub uses when calling your endpoint. NoAuthentication means Hub sends no auth header — protect your endpoint via custom headers instead |
headers | ❌ | Array of custom headers to authenticate your endpoint |
requiresSignature | ❌ | When true, outbound deliveries include X-hub-Signature — verify with Verifying webhook signatures. Toggle later with PATCH |
Response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"applicationId": "00000000-0000-0000-0000-000000000001",
"active": true,
"label": "ReceivedMessages",
"eventType": "Message",
"endpoint": "https://your-server.com/webhooks/chatt2me",
"numberOfErrors": 0,
"authenticationProtocol": "NoAuthentication",
"requiresSignature": false,
"isVerified": false,
"createdDate": "2026-02-09T12:00:00.000Z"
}
isVerified becomes true after Hub successfully calls your endpoint and receives an HTTP 200 response whose body matches the X-Validation-Token header Hub sends on that verification POST. See Endpoint verification for the full handshake, code examples, and an optional walkthrough using Webhooks2.me.
Webhooks2.me can host a temporary HTTPS URL whose custom response echoes X-Validation-Token, which is enough to pass verification while you build your real endpoint.
Save the webhook id — you will need it to list logs and perform retries.
Step 3 — Add authentication (recommended)
To ensure that only Hub Chatt2.me can trigger your endpoint, add a secret header:
curl -X POST https://api.chatt2.me/v1/organization/webhook \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"label": "ReceivedMessages",
"endpoint": "https://your-server.com/webhooks/chatt2me",
"eventType": "Message",
"authenticationProtocol": "NoAuthentication",
"headers": [
{
"key": "X-Webhook-Secret",
"value": "my-ultra-secret-value"
}
]
}'
In your endpoint, validate the header:
app.post('/webhooks/chatt2me', (req, res) => {
const secret = req.headers['x-webhook-secret'];
if (secret !== process.env.WEBHOOK_SECRET) {
return res.status(401).send('Unauthorized');
}
// ...
res.status(200).send('OK');
});
Step 4 — List your webhooks
curl https://api.chatt2.me/v1/organization/webhook \
-H "x-api-key: your-api-key"
Step 5 — Update or delete
Update endpoint, event type, or signature requirement
You can set requiresSignature to enable or disable Hub signing on outbound deliveries. When enabling, a new signing secret is generated. Implement verification on your server using the steps in Verifying webhook signatures.
curl -X PATCH https://api.chatt2.me/v1/organization/webhook/{webhookId} \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "https://your-server.com/webhooks/chatt2me-v2",
"eventType": "MessageStatus",
"requiresSignature": true
}'
Delete
curl -X DELETE https://api.chatt2.me/v1/organization/webhook/{webhookId} \
-H "x-api-key: your-api-key"
Returns HTTP 204 on success.
Redefining the signing secret
When Require signature is enabled for a webhook, you can rotate the signing secret without disabling verification by calling:
curl -X POST https://api.chatt2.me/v1/organization/webhook/{webhookId}/redefine-signature \
-H "x-api-key: your-api-key"
The response body contains the new secret once (secret). Previous deliveries already signed with the old secret will fail verification if your endpoint validates the signature. See Verifying webhook signatures for the header format and a Node.js example.
Testing locally
To expose your local server during development:
# Install ngrok: https://ngrok.com/download
ngrok http 3000
# Copy the generated HTTPS URL (e.g. https://abc123.ngrok.io)
# Use this URL as the endpoint when registering the webhook
Next steps
- Endpoint verification —
isVerifiedand theX-Validation-Tokenhandshake - Verifying webhook signatures — validate
X-hub-Signaturewhen Require signature is on - Event types and payload — structure of the JSON your endpoint receives
- Inspecting logs — view incoming requests and identify failures