API publique et webhooks
Intégrez ROOMCA à votre SIEM, votre outil de reporting ou vos scripts internes. Deux canaux complémentaires : une API REST versionnée pour la consommation à la demande, et des webhooks sortants signés HMAC pour recevoir les événements en temps réel.
1. Authentification
Toutes les requêtes vers l'API publique exigent une clé d'API au format Bearer. Les clés sont générées par un administrateur dans Paramètres → Webhooks & API (SIEM) → Clés API. Chaque clé porte des scopes qui restreignent les endpoints accessibles.
Authorization: Bearer rca_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxLa clé est scopée à l'entreprise qui l'a générée. Une clé émise pour votre tenant ne peut jamais accéder aux données d'une autre entreprise. Une clé peut être révoquée à tout moment depuis l'interface admin, l'accès est coupé immédiatement.
2. Endpoints REST
Base URL : https://roomca.fr/api/v1
| Méthode | Path | Scope | Description |
|---|---|---|---|
| GET | /api/v1/ | (aucun) | Métadonnées de version |
| GET | /api/v1/events | read:events | Flux d'événements (ingestion SIEM) |
| GET | /api/v1/users | read:users | Liste des utilisateurs de votre entreprise |
| GET | /api/v1/scenarios | read:scenarios | Scénarios + score moyen + taux de réussite |
| GET | /api/v1/campaigns | read:phishing | Campagnes phishing avec compteurs |
Pagination
Les endpoints paginés acceptent les paramètres since (id à partir duquel récupérer) et limit (1 à 500, défaut 100). La réponse contient next_since à réutiliser à la requête suivante et has_more qui indique s'il reste des pages.
Exemple : ingérer le flux d'événements
curl -H "Authorization: Bearer rca_xxxxxxxxxxxx" \
"https://roomca.fr/api/v1/events?since=0&limit=100"
# Réponse
{
"data": [
{
"id": 4821,
"type": "scenario.completed",
"company_id": 17,
"actor_user_id": 342,
"target_type": "scenario",
"target_id": 58,
"payload": { "score": 870, "max_score": 1000, "success": true, "duration_seconds": 412 },
"created_at": "2026-04-24T15:10:34.221Z"
}
],
"next_since": 4821,
"has_more": true
}3. Types d'événements
Chaque événement porte un type, un company_id, un payload typé par event, et un actor_user_id quand une action utilisateur est à l'origine. Les événements sont immuables une fois créés.
user.login_successLogin réussipayload: { "mfa_used": true, "new_ip": false }user.login_failedÉchec de loginpayload: { "attempt": 3, "locked": true }user.sso_loginLogin SSO (OIDC ou SAML)payload: { "provider": "azure_ad" }scenario.completedScénario réussi (score au dessus du seuil)payload: { "score": 870, "max_score": 1000, "success": true, "duration_seconds": 412 }scenario.failedScénario échouépayload: { "score": 120, "max_score": 1000, "success": false }quiz.completedQuiz mensuel soumispayload: { "score": 8, "max_score": 10, "score_pct": 80, "passed": true, "month_key": "2026-04" }phishing.clickedClic sur un lien de campagne phishingpayload: { "campaign_name": "Q2 facture fournisseur", "email": "alice@exemple.com", "variant_id": null }phishing.submittedIdentifiants saisis sur un faux loginpayload: { "campaign_name": "Q2 facture fournisseur", "email": "alice@exemple.com" }campaign.launchedCampagne lancée manuellement par un adminpayload: { "name": "Pilote direction", "type": "phishing", "target_count": 42 }4. Webhooks sortants
Un administrateur déclare un ou plusieurs endpoints HTTPS qui reçoivent les événements choisis. À chaque émission, ROOMCA signe la requête avec HMAC-SHA256 puis effectue jusqu'à 3 tentatives avec backoff (0s, 2s, 10s). Le timeout par tentative est de 5 secondes.
Format de la requête reçue
POST https://votre-endpoint HTTP/1.1
Content-Type: application/json
User-Agent: ROOMCA-Webhooks/1.0
X-Roomca-Event: scenario.completed
X-Roomca-Signature: t=1714048234,v1=abc123...hexhmac
X-Roomca-Delivery-Attempt: 1
{
"id": 4821,
"type": "scenario.completed",
"company_id": 17,
"actor_user_id": 342,
"target_type": "scenario",
"target_id": 58,
"payload": { "score": 870, "max_score": 1000, "success": true, "duration_seconds": 412 },
"created_at": "2026-04-24T15:10:34.221Z"
}La réussite d'une livraison est détectée via un code HTTP 2xx retourné par votre endpoint dans les 5 secondes. Toute autre réponse (ou un timeout) déclenche un retry selon le backoff. L'interface admin expose le journal des 50 dernières tentatives par webhook.
5. Vérifier la signature HMAC
Le header X-Roomca-Signature a le format t=TIMESTAMP_UNIX,v1=HEX. Pour authentifier la requête, recalculez le HMAC-SHA256 du payload signé concaténé (timestamp + "." + body brut) avec le secret partagé, puis comparez en temps constant. Rejetez une requête dont le timestamp s'écarte de plus de 5 minutes (protection anti-replay).
import crypto from 'crypto'
function verifyRoomcaSignature(rawBody, headerValue, secret, toleranceSec = 300) {
const parts = Object.fromEntries(headerValue.split(',').map(p => p.split('=')))
const timestamp = Number(parts.t)
const received = parts.v1
if (!timestamp || !received) return false
if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSec) return false
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')
try {
return crypto.timingSafeEqual(
Buffer.from(received, 'hex'),
Buffer.from(expected, 'hex')
)
} catch { return false }
}import hmac, hashlib, time
def verify_roomca_signature(raw_body: bytes, header_value: str,
secret: str, tolerance_sec: int = 300) -> bool:
parts = dict(p.split('=') for p in header_value.split(','))
try:
ts = int(parts['t']); received = parts['v1']
except (KeyError, ValueError):
return False
if abs(time.time() - ts) > tolerance_sec:
return False
signed = f"{ts}.{raw_body.decode()}"
expected = hmac.new(secret.encode(), signed.encode(),
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, received)6. Limites et quotas
- Rate limit API : 60 requêtes par minute et par clé. Au delà, réponse 429 avec header Retry-After.
- Pagination max : 500 enregistrements par requête (defaut 100).
- Isolation multi-tenant : chaque clé est scopée à une entreprise, aucune donnée cross-tenant ne circule.
- Transport : HTTPS exclusivement (TLS 1.3 avec hybride post-quantique X25519MLKEM768).
- Audit : chaque création, révocation ou utilisation de clé est journalisée côté admin.
Pour un cas d'usage particulier (Splunk, Elastic, Datadog, Power BI, script custom...), contactez-nous. Nous pouvons prioriser un champ manquant ou un endpoint supplémentaire selon vos besoins d'intégration.
Contacter l'équipe →