REST API v1

Documentation API CertiCV

Intégrez la vérification de CV directement dans votre ATS ou application RH. API REST sécurisée, webhooks signés HMAC-SHA256, disponible à partir du plan Pro.

Base URLhttps://api.certicv.com/api/v1
Obtenir une clé API Quickstart

Clé API sécurisée

Header X-API-Key par organisation. Scopes granulaires. Révocation instantanée.

Webhooks HMAC

Événements signés HMAC-SHA256. Retry avec backoff exponentiel.

RGPD natif

Base légale configurée par dossier. Journalisation complète des accès.

Chiffrement bout-à-bout

Documents chiffrés AES-256-GCM. Scan antivirus à l'upload.

Quickstart en 5 minutes

Créez un candidat, lancez un dossier, déposez les documents, envoyez l'invitation et récupérez le rapport.

  1. Créez une clé API depuis le dashboard (Développeur → Clés API).
  2. Créez un candidat (POST /candidates).
  3. Créez un dossier de vérification (POST /verification-cases).
  4. Envoyez l'invitation (PATCH /verification-cases/:id/send-invitation).
  5. Le candidat remplit son dossier → statut passe à CANDIDATE_SUBMITTED.
  6. CertiCV effectue les vérifications → statut passe à REPORT_READY.
  7. Recevez l'événement webhook report.ready et récupérez le rapport.
# 1. Créer un candidat
curl -X POST "https://api.certicv.com/api/v1/candidates" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Alice",
    "lastName": "Dubois",
    "email": "alice.dubois@example.com",
    "country": "FR",
    "language": "fr"
  }'

# 2. Créer un dossier de vérification
curl -X POST "https://api.certicv.com/api/v1/verification-cases" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "candidateId": "cand_01ABC",
    "jobTitle": "Product Manager",
    "sector": "tech",
    "sensitivityLevel": 3,
    "modules": [
      { "type": "IDENTITY" },
      { "type": "EDUCATION" },
      { "type": "EXPERIENCE" }
    ]
  }'

# 3. Envoyer l'invitation au candidat
curl -X PATCH "https://api.certicv.com/api/v1/verification-cases/case_01DEF/send-invitation" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# 4. Récupérer le rapport une fois REPORT_READY
curl -X GET "https://api.certicv.com/api/v1/reports/report_01GHI/full" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Authentification

Envoyez votre clé API dans le header X-API-Keysur chaque requête. La clé brute n'est affichée qu'une seule fois à la création — stockez-la immédiatement côté serveur. Ne l'exposez jamais dans le frontend ou dans du code versé dans Git.

curl -X GET "https://api.certicv.com/api/v1/integrations/test-auth" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Réponse attendue : { "authenticated": true, "organizationId": "org_...", "scopes": ["read:cases", "write:cases"] }

ScopeUsage
read:casesLecture des dossiers et documents.
write:casesCréation et modification des candidats, dossiers et validations.
read:reportsLecture, export JSON/PDF et partage des rapports.
read:candidatesLecture de la base candidats.

Cycle de vie d'un dossier

Un dossier de vérification passe par les statuts suivants. Utilisez le filtre ?status= pour interroger les dossiers à un stade précis.

DRAFT
  ↓ send-invitation
INVITATION_SENT
  ↓ le candidat accède au portail
CANDIDATE_STARTED
  ↓ le candidat soumet son dossier
CANDIDATE_SUBMITTED
  ↓ traitement IA
AI_ANALYSIS_DONE
  ↓ revue manuelle
VERIFICATION_IN_PROGRESS
  ↓ rapport généré
REPORT_READY
  ↓ archivage
ARCHIVED
StatutDescription
DRAFTDossier créé, invitation non encore envoyée.
INVITATION_SENTInvitation envoyée au candidat.
CANDIDATE_STARTEDLe candidat a ouvert son portail.
CANDIDATE_SUBMITTEDLe candidat a soumis ses documents.
AI_ANALYSIS_DONEAnalyse IA terminée.
MANUAL_REVIEW_PENDINGEn attente de validation manuelle.
ADDITIONAL_INFO_REQUESTEDDes informations complémentaires ont été demandées.
VERIFICATION_IN_PROGRESSVérifications en cours.
REPORT_READYRapport disponible.
DISPUTEDLe candidat conteste un résultat.
CLOSEDDossier clôturé.
ARCHIVEDDossier archivé.

Candidats

Un candidat représente la personne vérifiée. Créez d'abord le candidat, puis rattachez-le à un dossier de vérification.

POST/candidatesCréer un candidat.
GET/candidatesLister les candidats.
GET/candidates/{id}Détail d'un candidat.
PUT/candidates/{id}Mettre à jour un candidat.
# Créer un candidat
curl -X POST "https://api.certicv.com/api/v1/candidates" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Alice",
    "lastName": "Dubois",
    "email": "alice.dubois@example.com",
    "phone": "+33612345678",
    "country": "FR",
    "language": "fr",
    "linkedinUrl": "https://linkedin.com/in/alicedubois"
  }'

# Réponse
{
  "id": "cand_01ABC",
  "firstName": "Alice",
  "lastName": "Dubois",
  "email": "alice.dubois@example.com",
  "country": "FR",
  "language": "fr",
  "createdAt": "2026-05-18T18:30:00.000Z"
}

Dossiers de vérification

Un dossier regroupe les modules de vérification, les documents, les résultats et le rapport final. Filtrez les dossiers avec les paramètres search et status.

GET/verification-casesLister les dossiers (filtres: search, status, limit).
POST/verification-casesCréer un dossier de vérification.
GET/verification-cases/{id}Détail d'un dossier.
PATCH/verification-cases/{id}/send-invitationEnvoyer l'invitation au candidat.
PATCH/verification-cases/{id}/archiveArchiver un dossier.
# Créer un dossier
curl -X POST "https://api.certicv.com/api/v1/verification-cases" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "candidateId": "cand_01ABC",
    "jobTitle": "Product Manager",
    "sector": "tech",
    "sensitivityLevel": 3,
    "legalBasis": "LEGITIMATE_INTEREST",
    "modules": [
      { "type": "IDENTITY" },
      { "type": "EDUCATION" },
      { "type": "EXPERIENCE" },
      { "type": "DOCUMENT_ANALYSIS" }
    ]
  }'

# Réponse
{
  "id": "case_01DEF",
  "candidateId": "cand_01ABC",
  "jobTitle": "Product Manager",
  "status": "DRAFT",
  "modules": [...],
  "createdAt": "2026-05-18T18:35:00.000Z"
}

Documents

Les documents sont envoyés en multipart/form-data. Formats acceptés : PDF, PNG, JPG, JPEG, DOC, DOCX. Limite : 10 Mo. Les fichiers sont chiffrés (AES-256-GCM) et scannés par antivirus avant stockage.

POST/documentsTéléverser un document (multipart/form-data, max 10 Mo).
GET/documents/{id}/downloadTélécharger le fichier original.
# Téléverser un document
curl -X POST "https://api.certicv.com/api/v1/documents" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@/path/to/diplome.pdf" \
  -F "candidateId=cand_01ABC" \
  -F "caseId=case_01DEF" \
  -F "type=DIPLOMA"

# Réponse
{
  "id": "doc_01GHI",
  "candidateId": "cand_01ABC",
  "caseId": "case_01DEF",
  "type": "DIPLOMA",
  "fileName": "diplome.pdf",
  "mimeType": "application/pdf",
  "fileSize": 842120,
  "isEncrypted": true,
  "createdAt": "2026-05-18T18:45:00.000Z"
}

Rapports

Le rapport expose le score global, les résultats par module, les incohérences détectées et la décision humaine. L'URL PDF expire après 15 minutes.

POST/reports/cases/{caseId}/generateGénérer le rapport final.
GET/reports/{id}/fullLire le rapport complet avec sections.
GET/reports/{id}/jsonExporter le rapport au format JSON.
GET/reports/{id}/pdfObtenir une URL présignée vers le PDF (expire 15 min).
GET/reports/{id}/share-linkCréer un lien de partage sécurisé.
GET/reports/shared/{token}Accès public par token (sans clé API).
# Récupérer le rapport complet
curl -X GET "https://api.certicv.com/api/v1/reports/report_01GHI/full" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Réponse
{
  "id": "report_01GHI",
  "caseId": "case_01DEF",
  "globalIndex": 87,
  "identityScore": 100,
  "educationScore": 80,
  "experienceScore": 85,
  "referencesScore": null,
  "consistencyScore": 95,
  "executiveSummary": "3 éléments confirmés sur 4 vérifiés. Indice global : 87/100.",
  "publishedAt": "2026-05-18T19:00:00.000Z",
  "sections": [
    {
      "title": "Vérification : EDUCATION — Master Management",
      "status": "green",
      "content": { "source": "OFFICIAL_SOURCE", "confidence": "high" }
    }
  ]
}

# Obtenir l'URL du PDF (expire dans 15 min)
curl -X GET "https://api.certicv.com/api/v1/reports/report_01GHI/pdf" \
  -H "X-API-Key: ccv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Réponse
{
  "url": "https://s3.certicv.com/reports/report_01GHI.pdf?...",
  "expiresIn": 900
}

Webhooks & Signature HMAC

CertiCV envoie des événements asynchrones vers vos serveurs. Configurez vos endpoints depuis la page Webhooks du dashboard. Répondez avec un statut 2xxen moins de 5 secondes pour acquitter l'événement.

ÉvénementDéclenchement
pingTest manuel depuis le dashboard.
candidate.submittedLe candidat a soumis son dossier.
verification.completedLa vérification est terminée.
report.readyUn rapport est prêt à consulter.
dispute.openedUn candidat conteste un résultat.
quota.exceededLe quota mensuel est dépassé.
// Payload webhook
{
  "id": "evt_abc123",
  "event": "verification.completed",
  "created": 1715012345,
  "data": {
    "caseId": "case_01DEF",
    "status": "REPORT_READY",
    "reportId": "report_01GHI",
    "candidate": "Alice Dubois"
  }
}

Chaque webhook contient le header X-CertiCV-Signature au format t=timestamp,v1=signature. La signature est un HMAC-SHA256 de timestamp.bodyBrut, calculé avec votre secret webhook.

import crypto from "crypto";

export function verifyCertiCVWebhook(
  rawBody: string,
  header: string,
  secret: string,
  toleranceSeconds = 300   // rejeter les events vieux de +5 min
): boolean {
  if (!header) return false;

  const parts = Object.fromEntries(
    header.split(",").map((part) => {
      const [k, v] = part.split("=");
      return [k, v];
    })
  );

  const timestamp = Number(parts.t);
  const signature = parts.v1;
  if (!timestamp || !signature) return false;

  // Vérifier la fraîcheur du timestamp
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > toleranceSeconds) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  );
}

Erreurs & Rate limits

Toutes les erreurs retournent un statut HTTP explicite et un corps JSON. Limite par défaut : 60 requêtes par minute par organisation.

{
  "statusCode": 400,
  "message": ["email must be an email", "firstName must be a string"],
  "error": "Bad Request"
}
CodeSignificationRésolution
400Payload invalideVérifiez les champs requis et les formats.
401Clé API manquante ou invalideAjoutez le header X-API-Key.
403Scope ou plan insuffisantVérifiez les scopes de la clé et votre plan.
404Ressource introuvableVérifiez l'identifiant passé.
429Rate limit dépasséRéessayez après le délai Retry-After.
500Erreur interneRéessayez plus tard ou contactez le support.

Enums

Valeurs acceptées pour les champs typés.

VerificationModuleType

IDENTITY          — Vérification d'identité
EDUCATION         — Diplômes et formations
EXPERIENCE        — Expériences professionnelles
REFERENCES        — Vérification de références (plan Pro+)
DOCUMENT_ANALYSIS — Analyse des documents fournis
CRIMINAL_RECORD   — Casier judiciaire (plan Business+)
PROFESSIONAL_LICENSE — Licences et certifications professionnelles

DocumentType

CV · DIPLOMA · TRANSCRIPT · CERTIFICATE · ATTESTATION
ID_DOCUMENT · REFERENCE_LETTER · EMPLOYMENT_CERTIFICATE
PAY_SLIP · PORTFOLIO · OTHER

LegalBasis

PRE_CONTRACTUAL_MEASURES  — Mesures précontractuelles
LEGITIMATE_INTEREST       — Intérêt légitime
LEGAL_OBLIGATION          — Obligation légale
EXPLICIT_CONSENT          — Consentement explicite

Sécurité & RGPD

CertiCV est conçu pour traiter des données sensibles avec un haut niveau de sécurité. Les intégrateurs doivent s'assurer de disposer d'une base légale appropriée avant de transmettre des données candidat.

HTTPS obligatoire en production.
Clés API stockées uniquement côté serveur.
Scopes limités selon le principe du moindre privilège.
Documents chiffrés AES-256-GCM à l'upload.
Scan antivirus sur chaque document téléversé.
Journalisation complète des accès aux ressources.
Base légale RGPD configurable par dossier.
Révocation instantanée d'une clé compromise.
Rotation des clés sans interruption de service.
Contrôle d'accès strict par organisation.

Checklist avant mise en production

  • Utiliser une clé API live (pas de clé de test).
  • Stocker la clé côté serveur uniquement.
  • Limiter les scopes au strict nécessaire.
  • Tester la création d'un candidat et d'un dossier.
  • Tester l'upload de document et la génération de rapport.
  • Configurer les webhooks et vérifier la signature HMAC.
  • Gérer les erreurs 400, 401, 403, 404, 429 et 500.
  • Vérifier la base légale RGPD pour chaque dossier.
  • Prévoir une procédure de rotation des clés.

Prêt à intégrer l'API ?

Créez votre compte et obtenez votre clé API en 2 minutes.

Obtenir une clé API