API des Webhooks
Les webhooks permettent à votre backend de recevoir des notifications HTTP POST en temps réel lorsque des événements se produisent dans le moteur de prédiction. Il s'agit de l'approche recommandée pour l'intégration backend-to-backend — plus fiable que le maintien d'une connexion WebSocket persistante depuis votre serveur.
Authentification : en-tête X-Api-Key requis.
Fonctionnement
Event Occurs → Prediction Engine → HTTP POST → Your Backend URL
(HMAC signed)
- Vous enregistrez une URL de webhook auprès du moteur de prédiction
- Lorsque des événements correspondants se produisent, le moteur envoie un HTTP POST vers votre URL
- La charge utile est signée avec HMAC-SHA256 afin que vous puissiez vérifier son authenticité
- La livraison est relancée jusqu'à 3 fois si votre endpoint est indisponible
Enregistrer un Webhook
POST /api/v1/webhooks
Corps de la requête :
| Champ | Type | Requis | Description |
|---|---|---|---|
url | string | Oui | L'URL HTTPS qui recevra les livraisons de webhook |
events | string[] | Non | Types d'événements auxquels s'abonner (vide = tous les événements) |
description | string | Non | Libellé lisible par l'humain |
Types d'événements disponibles :
| Type d'événement | Déclencheur |
|---|---|
MARKET_CREATED | Un nouveau marché est créé |
MARKET_STATUS_CHANGED | Le statut du marché change (ouvert, suspendu, fermé, etc.) |
MARKET_RESOLVED | Le marché est résolu avec une issue gagnante |
ORDER_BOOK_UPDATE | Le carnet d'ordres change après une transaction ou un placement d'ordre |
PRICE_UPDATED | Les prix du marché changent |
ORDER_PLACED | Un nouvel ordre est placé |
ORDER_MATCHED | Un ordre est apparié et une transaction s'exécute |
ORDER_CANCELLED | Un ordre est annulé |
POSITION_UPDATED | Une position change |
SETTLEMENT_COMPLETED | Un règlement est traité |
Exemple :
curl -X POST https://polymarket.sandbox.playbatman.com/api/v1/webhooks \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-backend.com/webhooks/prediction",
"events": ["ORDER_MATCHED", "MARKET_RESOLVED", "SETTLEMENT_COMPLETED"],
"description": "Production webhook"
}'
Réponse :
{
"success": true,
"data": {
"id": "webhook-uuid",
"operatorId": "operator-uuid",
"url": "https://your-backend.com/webhooks/prediction",
"secret": "a1b2c3d4e5f6...64-char-hex-secret",
"events": ["ORDER_MATCHED", "MARKET_RESOLVED", "SETTLEMENT_COMPLETED"],
"isActive": true,
"description": "Production webhook",
"createdAt": "2026-02-18T23:00:00.000Z",
"updatedAt": "2026-02-18T23:00:00.000Z"
}
}
Sauvegardez le secret de la réponse — il n'est affiché en entier que lors de la création du webhook. Vous en aurez besoin pour vérifier les signatures de webhook.
Lister les Webhooks
GET /api/v1/webhooks
Retourne tous les webhooks de votre opérateur. Les secrets sont tronqués dans la réponse de liste.
Réponse :
{
"success": true,
"data": [
{
"id": "webhook-uuid",
"operatorId": "operator-uuid",
"url": "https://your-backend.com/webhooks/prediction",
"secret": "a1b2c3d4...",
"events": ["ORDER_MATCHED", "MARKET_RESOLVED"],
"isActive": true,
"description": "Production webhook",
"createdAt": "2026-02-18T23:00:00.000Z",
"updatedAt": "2026-02-18T23:00:00.000Z"
}
]
}
Mettre à Jour un Webhook
PATCH /api/v1/webhooks/{id}
Corps de la requête (tous les champs sont optionnels) :
| Champ | Type | Description |
|---|---|---|
url | string | Nouvelle URL de livraison |
events | string[] | Filtre d'événements mis à jour (vide = tous) |
isActive | boolean | Activer ou désactiver le webhook |
description | string | Description mise à jour |
Exemple — désactiver un webhook :
curl -X PATCH https://polymarket.sandbox.playbatman.com/api/v1/webhooks/{webhookId} \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{ "isActive": false }'
Supprimer un Webhook
DELETE /api/v1/webhooks/{id}
Réponse :
{
"success": true,
"data": { "message": "Webhook deleted" }
}
Charge Utile du Webhook
Chaque livraison de webhook est un HTTP POST avec un corps JSON :
{
"id": "delivery-uuid",
"sequence": 42,
"eventType": "ORDER_MATCHED",
"marketId": "market-uuid",
"operatorId": "operator-uuid",
"payload": {
"orderId": "order-uuid",
"marketId": "market-uuid",
"outcomeId": "outcome-uuid",
"operatorId": "operator-uuid",
"tradeId": "trade-uuid",
"side": "BUY",
"price": 0.65,
"shares": 50,
"filledShares": 50,
"remainingShares": 0,
"status": "FILLED",
"timestamp": 1708293600000
},
"timestamp": "2026-02-18T23:00:00.000Z"
}
En-têtes
| En-tête | Description |
|---|---|
Content-Type | application/json |
X-Webhook-Signature | sha256=<hex-encoded HMAC> |
X-Webhook-Event | Le type d'événement (ex. ORDER_MATCHED) |
X-Webhook-Id | Identifiant unique de livraison |
Vérification des Signatures
Chaque charge utile de webhook est signée avec HMAC-SHA256 en utilisant votre secret de webhook. Vérifiez toujours la signature avant de traiter la charge utile.
Node.js
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === `sha256=${expected}`;
}
// In your Express/Fastify handler:
app.post('/webhooks/prediction', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const rawBody = JSON.stringify(req.body); // or use raw body middleware
if (!verifyWebhook(rawBody, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
console.log(`Received ${event.eventType}:`, event.payload);
res.status(200).send('OK');
});
Python
import hmac
import hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return signature == f"sha256={expected}"
Livraison et Relances
- Délai d'attente : 10 secondes par tentative de livraison
- Relances : Jusqu'à 3 tentatives — immédiate, puis après 5 s, puis après 30 s
- Succès : Toute réponse HTTP 2xx est considérée comme un succès
- Fire-and-forget : Les échecs de webhook ne bloquent jamais le traitement des ordres ni les autres opérations
Bonnes Pratiques
- Répondre rapidement — Retournez immédiatement un statut 200 et traitez l'événement de manière asynchrone
- Vérifier les signatures — Validez toujours l'en-tête
X-Webhook-Signature - Gérer les doublons — Utilisez le champ
sequencepour dédupliquer les événements - Utiliser le filtrage d'événements — Abonnez-vous uniquement aux événements dont vous avez besoin pour réduire le bruit
- Surveiller votre endpoint — Si votre endpoint échoue régulièrement, les livraisons seront perdues après les relances