Aller au contenu principal
QualiForma
CatalogueDevenir formateurQualiopiIADéveloppeurs
Connexion
  • Catalogue
  • Devenir formateur
  • Qualiopi
  • IA
  • Développeurs
  • Connexion
  • Vue d'ensemble

Démarrage

  • Quickstart
  • Authentification

Référence

  • API Reference (Scalar)

Endpoints

  • Tous les endpoints

Cœur LMS

  • Tenants
  • Utilisateurs
  • Formations
  • Inscriptions
  • Sessions live

Conformité Qualiopi

  • Dashboard Qualiopi
  • Conformité
  • Émargement
  • Questionnaires
  • Réclamations
  • Plans d'amélioration
  • Parcours adaptatifs
  • Compétences formateurs
  • BPF
  • Médiateurs

Paiements & Facturation

  • Paiements
  • Facturation Factur-X
  • Webhooks

Design System

  • Vue d'ensemble
  • Couleurs
  • Typographie
  • Espacement
  • Elevation
  • Motion
  • Radius
  • Composants
  • · Formulaires
  • · Feedback
  • · Navigation
  • · Progression
  • · Données
Swagger UI (s'ouvre dans un nouvel onglet)
  1. Développeurs
  2. Endpoints
  3. Qualiopi

Qualiopi

Export du dossier d'audit par formation et validation pré-publication des 32 indicateurs Qualiopi. Réservé aux comptes ADMIN du tenant.

Endpoints disponibles

  • GET/api/v1/qualiopi/courses/:courseId/audit-export/previewAperçu des documents inclus dans l’export
  • GET/api/v1/qualiopi/courses/:courseId/audit-exportTéléchargement du ZIP d’audit (ADMIN only)
  • GET/api/v1/qualiopi/check-publicationValidation des 32 indicateurs avant publication

GET/qualiopi/courses/:courseId/audit-export/preview

Retourne la liste des documents qui seront inclus dans l'export ZIP avec leur taille estimée et la couverture des 32 indicateurs. Idéal pour afficher un récapitulatif avant le téléchargement.

Aperçu de l’export · Python
import requests

course_id = "crs_abc123"

response = requests.get(
    f'https://api.qualiforma.site/api/v1/qualiopi/courses/{course_id}/audit-export/preview',
    headers={
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': 'votre-tenant'
    }
)

preview = response.json()['data']
print(f"Documents inclus : {preview['documentCount']}")
print(f"Indicateurs couverts : {preview['indicatorsCovered']} / 32")
print(f"Taille estimée : {preview['estimatedSizeMb']} MB")

for doc in preview['documents']:
    print(f"  - [{doc['indicator']}] {doc['name']}")
Aperçu de l’export · cURL / Shell
TOKEN="eyJhbGci..."
COURSE_ID="crs_abc123"

curl "https://api.qualiforma.site/api/v1/qualiopi/courses/$COURSE_ID/audit-export/preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'X-Tenant-ID: votre-tenant'
Aperçu de l’export · TypeScript
interface AuditExportPreview {
  documentCount: number;
  indicatorsCovered: number;
  estimatedSizeMb: number;
  documents: Array<{
    name: string;
    indicator: string;     // ex. "I-7"
    type: string;          // CONVENTION | EMARGEMENT | EVALUATION ...
    sizeBytes: number;
  }>;
}

async function previewAuditExport(
  courseId: string,
  accessToken: string,
  tenantId: string
): Promise<AuditExportPreview> {
  const response = await fetch(
    `https://api.qualiforma.site/api/v1/qualiopi/courses/${courseId}/audit-export/preview`,
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        'X-Tenant-ID': tenantId,
      },
    }
  );
  const { data } = await response.json();
  return data;
}
Aperçu de l’export · PHP
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

$client = new Client(['base_uri' => 'https://api.qualiforma.site/api/v1/']);
$courseId = 'crs_abc123';

try {
    $response = $client->get("qualiopi/courses/{$courseId}/audit-export/preview", [
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
            'X-Tenant-ID' => 'votre-tenant',
        ],
    ]);
    $preview = json_decode($response->getBody()->getContents(), true)['data'];

    echo "Documents inclus : {$preview['documentCount']}\n";
    echo "Indicateurs couverts : {$preview['indicatorsCovered']} / 32\n";
    echo "Taille estimee : {$preview['estimatedSizeMb']} MB\n";

    foreach ($preview['documents'] as $doc) {
        echo "  - [{$doc['indicator']}] {$doc['name']}\n";
    }
} catch (GuzzleException $e) {
    fwrite(STDERR, "Erreur: " . $e->getMessage() . PHP_EOL);
}

GET/qualiopi/courses/:courseId/audit-export

Télécharge l'archive ZIP complète du dossier d'audit pour la formation. Le contenu est généré à la volée à partir des données du tenant. Streaming HTTP pour les gros dossiers (centaines de MB).

Télécharger l’export · Python
import requests

course_id = "crs_abc123"

# Téléchargement du ZIP (stream pour les gros dossiers)
with requests.get(
    f'https://api.qualiforma.site/api/v1/qualiopi/courses/{course_id}/audit-export',
    headers={
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': 'votre-tenant'
    },
    stream=True
) as response:
    response.raise_for_status()
    with open(f'audit-{course_id}.zip', 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)

print(f"Dossier d'audit exporté : audit-{course_id}.zip")
Télécharger l’export · cURL / Shell
TOKEN="eyJhbGci..."
COURSE_ID="crs_abc123"

# Téléchargement direct du ZIP
curl -X GET "https://api.qualiforma.site/api/v1/qualiopi/courses/$COURSE_ID/audit-export" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'X-Tenant-ID: votre-tenant' \
  -o "audit-$COURSE_ID.zip"

# Le ZIP contient :
#   /convention/         contrats + conventions de formation
#   /emargement/         feuilles d'émargement signées
#   /evaluation/         questionnaires pre/post + analyse IA
#   /attestation/        attestations de fin de formation
#   /programme/          programmes pédagogiques + objectifs
#   /trainers/           CV + certifications formateurs
#   /qualiopi-report.pdf rapport agrégé 32 indicateurs
Télécharger l’export · TypeScript
async function downloadAuditExport(
  courseId: string,
  accessToken: string,
  tenantId: string
): Promise<Blob> {
  const response = await fetch(
    `https://api.qualiforma.site/api/v1/qualiopi/courses/${courseId}/audit-export`,
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        'X-Tenant-ID': tenantId,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`Export refusé : ${response.status}`);
  }

  return await response.blob();
}

// Sauvegarde côté navigateur
const blob = await downloadAuditExport('crs_abc123', token, tenant);
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'audit-crs_abc123.zip';
a.click();
URL.revokeObjectURL(url);
Télécharger l’export · PHP
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

$client = new Client(['base_uri' => 'https://api.qualiforma.site/api/v1/']);
$courseId = 'crs_abc123';
$outputFile = "audit-{$courseId}.zip";

try {
    // Streaming HTTP pour les gros dossiers (centaines de MB)
    $response = $client->get("qualiopi/courses/{$courseId}/audit-export", [
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
            'X-Tenant-ID' => 'votre-tenant',
        ],
        'sink' => $outputFile, // ecrit directement sur disque
        'stream' => true,
    ]);

    echo "Dossier d'audit exporte : {$outputFile}\n";
} catch (GuzzleException $e) {
    fwrite(STDERR, "Erreur: " . $e->getMessage() . PHP_EOL);
}

GET/qualiopi/check-publication

Évalue la conformité Qualiopi d'une formation et retourne la liste des bloquants / avertissements. À appeler en pré-flight avant tout PATCH /courses/:id avec status: PUBLISHED.

Validation pré-publication · Python
import requests

course_id = "crs_abc123"

response = requests.get(
    'https://api.qualiforma.site/api/v1/qualiopi/check-publication',
    headers={
        'Authorization': f'Bearer {access_token}',
        'X-Tenant-ID': 'votre-tenant'
    },
    params={'courseId': course_id}
)

result = response.json()['data']

if result['canPublish']:
    print(f"Formation prête à publier ({result['score']}/100)")
else:
    print(f"Bloquants ({len(result['blockers'])}) :")
    for blocker in result['blockers']:
        print(f"  - [{blocker['indicator']}] {blocker['message']}")
    print(f"Avertissements ({len(result['warnings'])}) :")
    for warn in result['warnings']:
        print(f"  - {warn['message']}")
Validation pré-publication · cURL / Shell
TOKEN="eyJhbGci..."
COURSE_ID="crs_abc123"

curl "https://api.qualiforma.site/api/v1/qualiopi/check-publication?courseId=$COURSE_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'X-Tenant-ID: votre-tenant'

# Réponse :
# {
#   "data": {
#     "canPublish": false,
#     "score": 78,
#     "indicatorsCovered": 25,
#     "indicatorsTotal": 32,
#     "blockers": [
#       { "indicator": "I-9",
#         "message": "Programme pédagogique manquant" }
#     ],
#     "warnings": [
#       { "message": "Aucun questionnaire pré-formation configuré" }
#     ]
#   }
# }
Validation pré-publication · TypeScript
interface PublicationCheck {
  canPublish: boolean;
  score: number;                  // 0-100
  indicatorsCovered: number;
  indicatorsTotal: number;
  blockers: Array<{ indicator: string; message: string }>;
  warnings: Array<{ message: string }>;
}

async function checkPublication(
  courseId: string,
  accessToken: string,
  tenantId: string
): Promise<PublicationCheck> {
  const url = new URL('https://api.qualiforma.site/api/v1/qualiopi/check-publication');
  url.searchParams.set('courseId', courseId);

  const response = await fetch(url, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'X-Tenant-ID': tenantId,
    },
  });

  const { data } = await response.json();
  return data;
}

// Pattern : pré-flight avant PATCH status=PUBLISHED
const check = await checkPublication('crs_abc123', token, tenant);
if (!check.canPublish) {
  console.error('Bloquants :', check.blockers);
  return;
}
await publishCourse('crs_abc123');
Validation pré-publication · PHP
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

$client = new Client(['base_uri' => 'https://api.qualiforma.site/api/v1/']);
$courseId = 'crs_abc123';

try {
    $response = $client->get('qualiopi/check-publication', [
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
            'X-Tenant-ID' => 'votre-tenant',
        ],
        'query' => ['courseId' => $courseId],
    ]);
    $result = json_decode($response->getBody()->getContents(), true)['data'];

    if ($result['canPublish']) {
        echo "Formation prete a publier ({$result['score']}/100)\n";
    } else {
        echo "Bloquants (" . count($result['blockers']) . ") :\n";
        foreach ($result['blockers'] as $blocker) {
            echo "  - [{$blocker['indicator']}] {$blocker['message']}\n";
        }
        echo "Avertissements (" . count($result['warnings']) . ") :\n";
        foreach ($result['warnings'] as $warn) {
            echo "  - {$warn['message']}\n";
        }
    }
} catch (GuzzleException $e) {
    fwrite(STDERR, "Erreur: " . $e->getMessage() . PHP_EOL);
}
QualiForma

La plateforme de formation professionnelle certifiee Qualiopi.

Plateforme

  • Catalogue
  • Espace formateur
  • Étude de besoin

Societe

  • A propos
  • Contact

Ressources

  • Développeurs
  • Référence API
  • Webhooks

Legal

  • CGV
  • Mentions legales
  • Confidentialite

Catalogue par catégorie

  • Management
  • Digital
  • Communication
  • Langues
  • Sécurité
  • Gestion

Comparatifs

  • QualiForma vs Didask
  • QualiForma vs Edusign
  • QualiForma vs Klaxoon
  • QualiForma vs 360Learning

Glossaire Qualiopi

  • I01 — Conditions d'information
  • I05 — Adaptation des prestations
  • I11 — Évaluations en cours
  • I22 — Compétences des intervenants
  • I30 — Recueil des appréciations
  • Voir les 32 indicateurs →

© 2026 QualiForma. Tous droits reserves.

Certifie Qualiopi