🍪 PRÉFÉRENCES & CONFIDENTIALITÉ
ROOMCA utilise des traceurs strictement nécessaires au fonctionnement du service (authentification, session, sécurité, préférences essentielles), ainsi qu’un outil de mesure d’audience respectueux de la vie privée, configuré sans dépôt de cookies. Aucun traceur marketing n’est activé sans votre accord. Vos choix sont enregistrés côté serveur pour traçabilité RGPD (art. 7.1). En savoir plus
Documentation développeur

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.

Header d'authentification
Authorization: Bearer rca_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

La 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éthodePathScopeDescription
GET/api/v1/(aucun)Métadonnées de version
GET/api/v1/eventsread:eventsFlux d'événements (ingestion SIEM)
GET/api/v1/usersread:usersListe des utilisateurs de votre entreprise
GET/api/v1/scenariosread:scenariosScénarios + score moyen + taux de réussite
GET/api/v1/campaignsread:phishingCampagnes 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éussi
payload: { "mfa_used": true, "new_ip": false }
user.login_failedÉchec de login
payload: { "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 soumis
payload: { "score": 8, "max_score": 10, "score_pct": 80, "passed": true, "month_key": "2026-04" }
phishing.clickedClic sur un lien de campagne phishing
payload: { "campaign_name": "Q2 facture fournisseur", "email": "alice@exemple.com", "variant_id": null }
phishing.submittedIdentifiants saisis sur un faux login
payload: { "campaign_name": "Q2 facture fournisseur", "email": "alice@exemple.com" }
campaign.launchedCampagne lancée manuellement par un admin
payload: { "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).

Node.js
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 }
}
Python
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.
Besoin d'aide ?

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 →