Pyxaura Pyxaura

Guide — Webhooks sortants

1. Créer un endpoint

curl -X POST https://pyxaura.com/api/v1/webhooks \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://votre-app.com/webhooks/pyxia",
    "events": ["sync.completed", "report.ready", "quota.warning"]
  }'
{
  "webhook": { "id": "wh_3", "url": "https://...", "active": true },
  "secret": "whsec_abc123..."
}

⚠️ Stockez secret immédiatement — il ne sera plus affiché.

2. Vérifier la signature côté consommateur

Chaque livraison inclut l'en-tête X-Pyxaura-Signature: t=<ts>,v1=<hex>.

Ruby

require "openssl"

def verify_webhook!(payload, signature_header, secret, tolerance: 300)
  parts      = signature_header.split(",").map { |p| p.split("=", 2) }.to_h
  timestamp  = parts["t"].to_i
  received   = parts["v1"]
  raise "Timestamp invalide"     if (Time.now.to_i - timestamp).abs > tolerance
  raise "Signature manquante"    if received.blank?
  expected   = OpenSSL::HMAC.hexdigest("SHA256", secret, "#{timestamp}.#{payload}")
  raise "Signature invalide"     unless ActiveSupport::SecurityUtils.secure_compare(expected, received)
  true
end

# Dans votre contrôleur Rails :
def receive_pyxia_webhook
  verify_webhook!(
    request.raw_post,
    request.headers["X-Pyxaura-Signature"],
    ENV["PYXIA_WEBHOOK_SECRET"]
  )
  event = JSON.parse(request.raw_post)
  # traiter event["event_type"]...
  head :ok
rescue => e
  head :bad_request
end

Node.js

const crypto = require("crypto");

function verifyWebhook(payload, signatureHeader, secret, toleranceSec = 300) {
  const parts     = Object.fromEntries(signatureHeader.split(",").map(p => p.split("=")));
  const timestamp = parseInt(parts.t);
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSec)
    throw new Error("Timestamp trop ancien");
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${payload}`)
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1)))
    throw new Error("Signature invalide");
}

3. Relancer une livraison échouée

curl -X POST https://pyxaura.com/api/v1/webhooks/deliveries/42/retry \
  -H "Authorization: Bearer $KEY"

4. Envoyer un événement test

curl -X POST https://pyxaura.com/api/v1/webhooks/test \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": "sync.completed"}'

5. Événements disponibles

Événement Déclencheur
sync.started / sync.completed / sync.failed Synchronisation source
document.indexed / document.failed Indexation document
report.ready / report.failed Génération rapport
space.deleted / space.reindexed Opérations space
quota.warning / quota.exceeded Seuil 80% / dépassement
export.ready Export corpus terminé

6. Retries

5 tentatives maximum avec backoff exponentiel :
1 min → 5 min → 15 min → 30 min → 1 h.

Au-delà, le endpoint est désactivé automatiquement (active: false).
Réactivez-le via PATCH /webhooks/:id après correction.