Webhooks
Créer un endpoint
POST /webhook-endpoints · permission webhooks:write · idempotent
curl -X POST https://api.click2call.app/v1/webhook-endpoints \
-H "Authorization: Bearer $CLICK2CALL_API_KEY" \
-H "Idempotency-Key: webhook-production" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemple.fr/webhooks/click2call","events":["call.connected","call.completed","callback.requested"]}'
Le secret n'est renvoyé qu'à la création. Les endpoints doivent être HTTPS et ne peuvent pas cibler un réseau privé.
Événements
call.requested, call.ringing, call.connected, call.completed, call.failed et callback.requested.
{"id":"01K...","event":"call.completed","created_at":"2026-07-31T10:04:42Z","data":{"id":"01K...","workspace_id":"01K...","status":"completed","duration_seconds":210}}
Vérifier la signature
L'en-tête Click2Call-Signature suit t=timestamp,v1=signature. La signature est le HMAC-SHA256 de timestamp + "." + corps_brut.
Vérification sans SDK
import crypto from 'node:crypto';
const parts = Object.fromEntries(signatureHeader.split(',').map((part) => part.split('=')));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) throw new Error('Signature expirée');
const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))) throw new Error('Signature invalide');
parse_str(str_replace(',', '&', $signatureHeader), $parts);
if (abs(time() - (int) $parts['t']) > 300) {
throw new RuntimeException('Signature expirée');
}
$expected = hash_hmac('sha256', $parts['t'].'.'.$rawBody, $secret);
if (!hash_equals($expected, $parts['v1'] ?? '')) {
throw new RuntimeException('Signature invalide');
}
Utilisez le corps brut, comparez en temps constant et rejetez un timestamp vieux de plus de 300 secondes. Dédupliquez avec l'identifiant id.
Administration
GET /webhook-endpointsPATCH /webhook-endpoints/{id}· idempotentDELETE /webhook-endpoints/{id}GET /webhook-deliveriesPOST /webhook-deliveries/{id}/retry· idempotent