API-first · MSP & agences web

Documentation API SoleoDigital

Créez et suivez des audits de conformité (Loi 25 / CAI, PIPEDA, RGPD) par programmation — et intégrez les résultats structurés dans vos propres outils.

Pourquoi l'API SoleoDigital
Démarrer
Explorer

Concepts

Les objets que vous manipulez via l'API.

Clé API

Jeton sk_soleo_… généré depuis le dashboard. Agit avec les permissions et le périmètre multi-organisations de son propriétaire.

Mission (audit)

Une cible à auditer (un domaine + un client). Identifiée par un mission_id qui sert de fil conducteur à toutes les étapes.

SoleoDigital Capture

Logiciel de capture téléchargeable, lié à la mission par un token. Il s'exécute sur le poste depuis lequel vous auditez.

Capture L2 / L3

L2 = trafic réseau (requêtes, tiers, cookies). L3 = événements runtime (stockage, DOM, moment du consentement).

Résultats (results.json)

Sortie structurée déterministe : score, violations, cross_border, summary. Le cœur de l'intégration. Indicatif : validez avant de présenter les conclusions à un client ou un tiers.

Rapport PDF

Livrable client brandé SoleoDigital, généré à partir de la capture et récupérable via l'API.


Quickstart

Votre premier audit, du token au rapport, en 5 minutes.

1 · Clé API→ 2 · Créer l'audit→ 3 · Lancer le kit→ 4 · Suivre le statut→ 5 · Récupérer le rapport

Prérequis

Vérifiez que votre clé fonctionne
curl https://app.soleodigital.ca/api/v1/public/v1/whoami \
  -H "X-API-Key: sk_soleo_votre_cle_ici"
Réponse
{
  "authenticated": true,
  "user": "vous@agence.ca",
  "organization_id": "org-123",
  "key_name": "Agence Web X",
  "scopes": ["audits:read", "audits:write"],
  "api_base": "https://app.soleodigital.ca/api/v1/public/v1"
}
Si vous voyez "authenticated": true, votre clé est valide. Sinon, vérifiez l'en-tête X-API-Key.
1

Créez un audit

curl -X POST https://app.soleodigital.ca/api/v1/public/v1/audits \
  -H "X-API-Key: sk_soleo_votre_cle_ici" -H "Content-Type: application/json" \
  -d '{"domain":"bnc.ca","name":"Audit BNC"}'
Réponse
{
  "mission_id": "mission-ab12cd34ef56",
  "domain": "bnc.ca",
  "name": "Audit BNC",
  "status": "Prête",
  "capture_status": "token_issued",
  "score": null,
  "agent_token": "eyJhbGci...",
  "agent_token_expires_at": "2026-07-03T04:00:00+00:00",
  "kit_download_url": "https://app.soleodigital.ca/api/v1/audit-missions/agent-kit?platform=windows&mission_id=mission-ab12cd34ef56",
  "results_url": "https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/results.json",
  "report_pdf_url": "https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/report.pdf"
}
Ce que vous venez de faire : créé une mission d'audit, généré un token, et obtenu le lien de téléchargement SoleoDigital Capture. Notez le mission_id — il sert pour toutes les étapes suivantes.
2

Téléchargez et lancez le kit

  1. Ouvrez le kit_download_url dans votre navigateur (ou curl -O).
  2. Installez le kit sur le poste depuis lequel vous auditez.
  3. Lancez le kit de la mission.
  4. Naviguez sur le domaine audité (bnc.ca dans l'exemple).
  5. Cliquez sur « Refuser » sur la bannière de cookies — c'est ce qui produit la preuve de tracking post-refus.
La capture est maintenant en cours. Chaque requête réseau et événement runtime est enregistré.
3

Suivez l'avancement

curl https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56 \
  -H "X-API-Key: sk_soleo_votre_cle_ici"

Surveillez le champ capture_status. Les principaux états :

capture_statusSignification
token_issuedMission créée, kit prêt — en attente de la capture.
capture_runningDes événements arrivent : la capture est en cours.
capture_completedCapture terminée, finalisation du dossier en cours.
report_readyRapport et résultats structurés prêts à récupérer.
4

Récupérez les résultats

Résultats structurés (intégration dans votre outil)
curl https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/results.json \
  -H "X-API-Key: sk_soleo_votre_cle_ici"
Réponse
{
  "mission_id": "mission-ab12cd34ef56",
  "domain": "bnc.ca",
  "ready": true,
  "score": 62,
  "summary": {
    "post_refusal_tracking_total": 3,
    "pre_consent_tracking_total": 5
  },
  "violations": [ ... ],
  "cross_border": [ ... ],
  "interpretation": {
    "evidence_run_id": "run-7f3a9c",
    "target_domains": ["bnc.ca"],
    "executive_summary_fr": "Capture de 214 requêtes — 3 trackers actifs après refus du consentement.",
    "narrative_fr": "…",
    "archived": true
  },
  "stats": {
    "total": 214,
    "l2_network": 187,
    "runtime_captures": 27,
    "tracking_discovery": 12,
    "storage_total": 41
  },
  "archived_at": "2026-07-02T20:15:00+00:00",
  "report_pdf_url": "https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/report.pdf"
}
Rapport PDF livrable client
curl -o rapport_bnc.pdf \
  https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/report.pdf \
  -H "X-API-Key: sk_soleo_votre_cle_ici"
Tant que la capture n'est pas finalisée, results.json renvoie "ready": false et le PDF n'est pas encore disponible.

Félicitations

Vous venez de lancer votre premier audit automatisé avec SoleoDigital. 🎉

Prochaines étapes :


Quick Scan & graphe de relations

Analyse web instantanée d'un domaine — sans SoleoDigital Capture, sans capture locale. Idéal prospection & enrichissement CRM.

Contrairement à un audit complet (capture L2/L3 sur le poste du client), le Quick Scan est server-side et synchrone : il renvoie en quelques secondes les technologies détectées, le DNS, le SSL, des signaux de risque et un score. Chaque scan est enregistré dans un graphe de relations : vous pouvez ensuite lister les domaines qui partagent une même IP, un même identifiant Google Tag Manager, un même émetteur SSL, etc.

POST /quick-scan→ technos + DNS + SSL + score→ graphe d'entités→ GET /domains/{domain}/connections
1

Analysez un domaine

curl -X POST https://app.soleodigital.ca/api/v1/public/v1/quick-scan \
  -H "X-API-Key: sk_soleo_votre_cle_ici" -H "Content-Type: application/json" \
  -d '{"domain":"exemple.com"}'
Réponse (extrait)
{
  "domain": "exemple.com",
  "reachable": true,
  "http_status": 200,
  "https": true,
  "risk_score": 30,
  "grade": "B",
  "categories": {
    "Framework": ["Next.js", "React"],
    "Analytics": ["Matomo"],
    "Server": ["Apache"]
  },
  "dns": { "a": ["51.161.122.78"], "asn": "AS16276", "ns": ["ns10.ovh.ca"] },
  "ssl": { "issuer": "Let's Encrypt", "days_remaining": 64 },
  "domain_age": { "registered_at": "2018-04-12T00:00:00+00:00", "age_days": 2973, "registrar": "OVH sas" },
  "risk_signals": [
    { "code": "missing_csp", "label": "Content-Security-Policy absente", "weight": 6 },
    { "code": "no_cmp", "label": "Trackers sans plateforme de consentement (CMP)", "weight": 10 }
  ],
  "cached": false,
  "entities": {
    "ip": ["51.161.122.78"], "asn": ["AS16276"],
    "gtm_ids": [], "ga_ids": [], "ssl_issuer": "Let's Encrypt",
    "third_party_hosts": ["calendly.com", "plausible.io"]
  }
}
Le grade va de A (faible risque) à F. Le scan est enregistré dans le graphe et, si un webhook domain.scanned est configuré, une notification est envoyée à votre CRM.
2

Découvrez les domaines liés

curl https://app.soleodigital.ca/api/v1/public/v1/domains/exemple.com/connections \
  -H "X-API-Key: sk_soleo_votre_cle_ici"
Réponse (extrait)
{
  "domain": "exemple.com",
  "scanned": true,
  "related_domains_count": 7,
  "by_signal": { "strong": 1, "medium": 2, "provider": 1 },
  "connections": [
    {
      "etype": "gtm_id", "value": "GTM-AAA111", "signal": "strong",
      "count": 1, "shared_with": [{ "domain": "autre-site.com", "grade": "C" }]
    },
    {
      "etype": "ip", "value": "51.161.122.78", "signal": "medium",
      "count": 2, "shared_with": [ ... ]
    }
  ]
}

Chaque connexion porte un signal qui indique la force du lien :

signalSignificationTypes d'entités
strongQuasi-preuve de même propriétaireGTM, Google Analytics, Google Ads, Meta Pixel, Matomo
mediumLien probableIP partagée, hôte tiers peu commun
providerPartage d'infrastructureName server, émetteur SSL, ASN

Comment ça marche

Le modèle d'exécution, de l'appel API au rapport.

POST /audits→ Token + SoleoDigital Capture→ Capture locale (L2 + L3)→ Analyse conformité→ results.json + PDF
  1. Création. Votre appel POST /audits crée une mission et émet un token à courte durée de vie + un lien de téléchargement SoleoDigital Capture.
  2. Capture souveraine. Le kit s'exécute sur le poste de votre client : il enregistre le trafic réseau (L2) et les événements runtime (L3) pendant la navigation. Les preuves brutes ne transitent pas par un tiers.
  3. Ingestion & analyse. Les événements remontent à SoleoDigital, qui détecte trackers pré-consentement, tracking post-refus, transferts hors Canada et écarts Loi 25.
  4. Résultats. Un results.json déterministe et un rapport PDF brandé sont produits, puis récupérables par l'API.
  5. Rejeu. Chaque session reste rejouable dans le dashboard (console replay L2/L3), comme un enregistrement du live.
Souveraineté : la capture est locale au client. SoleoDigital ne revend jamais vos données et ne les utilise que pour produire vos livrables.

Utiliser l'API

Conventions transverses : auth, pagination, polling, erreurs.

Authentification

Chaque requête porte votre clé dans l'en-tête X-API-Key. Portées disponibles : audits:read, audits:write, mia_fast:read, mia_fast:write.

curl https://app.soleodigital.ca/api/v1/public/v1/whoami \
  -H "X-API-Key: sk_soleo_votre_cle_ici"
Vous pouvez aussi tester chaque endpoint en direct dans le Playground Swagger (bouton « Authorize » → collez votre clé).

Mode sandbox (tests sans quota)

Créez une clé sandbox dans le dashboard (Intégrations / API → case « Clé sandbox »). Les audits créés avec cette clé sont simulés : results.json est disponible immédiatement, aucun SoleoDigital Capture réel ni consommation de quota.

curl -X POST https://app.soleodigital.ca/api/v1/public/v1/audits \
  -H "X-API-Key: sk_soleo_sandbox_..." -H "Content-Type: application/json" \
  -d '{"domain":"exemple.ca","name":"Test intégration"}'

La réponse inclut "sandbox": true et "ready": true. Le PDF n'est pas généré en sandbox — utilisez results.json.

Idempotence (Idempotency-Key)

Sur POST /audits, envoyez un en-tête Idempotency-Key unique (8–255 caractères). En cas de timeout ou retry, la même clé + le même corps renvoient la réponse originale (TTL 24 h). Un corps différent avec la même clé → 409 Conflict.

curl -X POST https://app.soleodigital.ca/api/v1/public/v1/audits \
  -H "X-API-Key: sk_soleo_..." \
  -H "Idempotency-Key: crm-deal-88421-v1" \
  -H "Content-Type: application/json" \
  -d '{"domain":"client.ca","name":"Audit CRM"}'

Pagination

GET /audits est paginé via ?limit= (1–500, défaut 50) et ?offset=. La réponse renvoie total, limit, offset et items.

curl "https://app.soleodigital.ca/api/v1/public/v1/audits?limit=50&offset=0" \
  -H "X-API-Key: sk_soleo_votre_cle_ici"

Limites & débit

Polling des résultats (limite molle). Après le lancement du kit, interrogez results.json jusqu'à "ready": true. Intervalle recommandé : 5 s ; évitez de dépasser 1 req/s par mission. C'est une consigne d'usage, pas un rejet automatique.

Quick Scan (limite dure). POST /quick-scan est plafonné à 15 scans/minute par clé. Au-delà, l'API renvoie 429 avec un en-tête Retry-After (en secondes) — respectez-le avant de réessayer.

Gestion des erreurs

Les erreurs suivent le format { "detail": "message" } avec un code HTTP standard (voir codes d'erreur). Traitez notamment 402 (quota atteint), 401 (clé invalide) et 429 (débit Quick Scan dépassé — attendez Retry-After).


Webhooks & intégration CRM

Deux façons de brancher SoleoDigital à votre CRM (HubSpot, Salesforce, Zapier, Make…).

Option 1 — Polling REST

Le plus simple : après avoir créé un audit, votre CRM interroge results.json jusqu'à "ready": true, puis récupère le score et le PDF. Aucune configuration côté SoleoDigital. Idéal pour un premier branchement ou un CRM sans endpoint public.

Option 2 — Webhooks (temps réel, recommandé)

Configurez un webhook dans le dashboard → Intégrations / API → Webhooks. Dès qu'un audit est finalisé, SoleoDigital envoie un POST signé vers votre URL — pas de polling. C'est ce qu'attendent Zapier, Make et les workflows CRM.

Exemple de charge utile (event audit.completed)
{
  "event": "audit.completed",
  "created_at": "2026-07-02T20:15:00+00:00",
  "data": {
    "mission_id": "mission-ab12cd34ef56",
    "domain": "bnc.ca",
    "organization": "Client Final",
    "capture_status": "report_ready",
    "score": 62,
    "violations_count": 4,
    "violations_high": 1,
    "post_refusal_tracking_total": 2,
    "results_url": "https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/results.json",
    "report_pdf_url": "https://app.soleodigital.ca/api/v1/public/v1/audits/mission-ab12cd34ef56/report.pdf",
    "report_html_url": "https://app.soleodigital.ca/api/v1/live-capture/demo-report?stem=m-mission-ab12cd34ef56",
    "report_html_download_url": "https://app.soleodigital.ca/api/v1/live-capture/demo-report/download?stem=m-mission-ab12cd34ef56",
    "dashboard_url": "https://app.soleodigital.ca/index.html#mission-mission-ab12cd34ef56"
  }
}
En-têtes envoyés
Content-Type: application/json
X-Soleo-Event: audit.completed
X-Soleo-Delivery: <identifiant unique de livraison>
X-Soleo-Signature: sha256=<HMAC-SHA256 du corps avec votre secret>
Vérifiez la signature pour vous assurer que l'appel vient bien de SoleoDigital. Recalculez le HMAC-SHA256 du corps brut avec le secret du webhook, et comparez à X-Soleo-Signature.
Vérification (Python)
import hmac, hashlib

def verifie(corps: bytes, entete_signature: str, secret: str) -> bool:
    attendu = "sha256=" + hmac.new(secret.encode(), corps, hashlib.sha256).hexdigest()
    return hmac.compare_digest(attendu, entete_signature)

Répondez avec un code 2xx pour accuser réception. En cas d'échec réseau ou 5xx, SoleoDigital retente automatiquement (jusqu'à 5 tentatives, backoff exponentiel ~2 s → 45 s). Une réponse 4xx est considérée définitive (pas de retry). La livraison est asynchrone : elle ne bloque jamais l'audit. Toutes les tentatives sont visibles côté Super Admin.

Événements disponibles

eventDéclencheurCharge utile principale
audit.completedUn audit est finalisé (rapport prêt)mission_id, domain, score, violations_count, violations_high, results_url, report_pdf_url, report_html_url
audit.score_droppedLe score de conformité baisse significativementprevious_score, current_score, delta, violations_count, report_pdf_url, report_html_url
domain.scannedUn domaine est analysé par le Quick Scandomain, risk_score, grade, technologies, related_domains_count, connections_url
mia_fast.completedScan MIA Fast prospection terminé (~17 s, signaux serveur)job_id, domain, reference_id, risk_score, tier, cmp_detected, sales_play_id, recommended_sales_action_fr, report_pdf_url
Exemple de charge utile (event domain.scanned)
{
  "event": "domain.scanned",
  "created_at": "2026-07-03T05:20:00+00:00",
  "data": {
    "domain": "exemple.com",
    "reachable": true,
    "risk_score": 30,
    "grade": "B",
    "technologies": ["Next.js", "React", "Apache", "Matomo"],
    "related_domains_count": 7,
    "ip": ["51.161.122.78"],
    "asn": "AS16276",
    "ssl_issuer": "Let's Encrypt",
    "connections_url": "https://app.soleodigital.ca/api/v1/public/v1/domains/exemple.com/connections"
  }
}
Cas d'usage CRM : à l'ouverture d'une fiche prospect, injectez risk_score et related_domains_count pour prioriser vos relances et recommander un audit complet. Les en-têtes et la vérification de signature sont identiques à audit.completed (seul X-Soleo-Event change).

Référence API

Endpoints Authentification & URL de base POST /audits — créer un audit GET /audits — lister / statut GET /audits/{id}/results.json GET /audits/{id}/report.pdf POST /quick-scan — analyse instantanée GET /domains/{domain}/connections Codes d'erreur

Authentification & URL de base

Chaque requête porte votre clé dans l'en-tête X-API-Key. Portées : audits:read, audits:write. La clé agit avec les permissions et le cloisonnement multi-organisations de son propriétaire.

Base : https://app.soleodigital.ca/api/v1/public/v1
En-tête : X-API-Key: sk_soleo_xxxxxxxxxxxxxxxx

POST /audits

ChampTypeDéfautDescription
domainstring—Domaine à auditer (obligatoire)
namestringAudit <domaine>Nom de la mission
organizationstringvotre orgNom du client final
expires_in_daysint30Validité de la mission (1–365)
authorizedbooltrueAutoriser la capture immédiatement
with_agentbooltrueGénérer token agent + lien kit
agent_token_hoursint8Validité du token agent (1–24)

GET /audits  ·  GET /audits/{mission_id}

Liste paginée des audits accessibles (?limit=50&offset=0) ou état d'un audit précis. Réponse : mission_id, domain, status, capture_status, score, results_url, report_pdf_url…

GET /audits/{mission_id}/results.json

Résultats structurés une fois la capture finalisée : ready, score, summary, violations, cross_border, interpretation, stats. Renvoie "ready": false tant que la capture n'est pas terminée.

GET /audits/{mission_id}/report.pdf

Rapport PDF brandé SoleoDigital, prêt à livrer à votre client.

POST /quick-scan

Analyse web instantanée d'un domaine (server-side, sans SoleoDigital Capture). Portée requise : audits:read.

ChampTypeDéfautDescription
domainstring—Domaine à analyser (obligatoire)
persistbooltrueEnregistrer le résultat dans le graphe de relations
forceboolfalseIgnorer le cache et forcer un nouveau scan live

Réponse : domain, reachable, http_status, https, risk_score, grade, categories, technologies, dns, ssl, domain_age, security_headers, risk_signals, entities, cached.

Cache. Un domaine scanné il y a moins de 6 h renvoie le dernier rapport ("cached": true) sans re-scanner le site cible ni renvoyer de webhook domain.scanned. Passez "force": true pour forcer un scan frais.

GET /domains/{domain}/connections

Domaines liés au domaine donné, groupés par entité partagée (IP, ASN, name server, émetteur SSL, GTM/GA/Ads/Pixel, Matomo, hôte tiers). Portée requise : audits:read. Cloisonné à votre périmètre d'organisation.

Réponse : domain, scanned, related_domains_count, by_signal, connections[] { etype, value, signal, count, shared_with[] }.

Codes d'erreur

CodeSignification
400Requête invalide (ex. domaine mal formé)
401Clé API manquante ou invalide
403Portée insuffisante ou permission manquante
402Quota de missions du plan atteint
404Audit introuvable (ou hors de votre périmètre)
429Trop de requêtes (limite Quick Scan). En-tête Retry-After renvoyé.
504Le Quick Scan a dépassé le délai (site cible trop lent)

Besoin d'aide ? contact@soleodigital.ca