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. BPF

Bilan Pédagogique et Financier

Déclaration annuelle obligatoire à la DGEFP/DREETS pour tout organisme de formation enregistré (N° d’activité). Calcul automatique des heures, montants HT, publics (SAL, DE, AUT) et sources de financement (OPCO, CPF, Pôle Emploi, employeur, autofinancement). Export CERFA n°10443*16 conforme.

Endpoints

get/api/v1/bpf/current-year

Statistiques BPF live (année courante)

Renvoie les agrégats temps réel de l'année fiscale courante. Pas de snapshot stocké — chaque appel recalcule à partir des sessions, conventions et factures.

  • BPF
  • Qualiopi
  • DGEFP

Réponses

  • 200Agrégats live
    Réponse 200 · JSON
    {
      "data": {
        "year": 2026,
        "asOf": "2026-05-15T08:00:00Z",
        "totalTrainees": 184,
        "totalHours": 8240,
        "totalRevenueHT": 412540,
        "status": "OPEN"
      }
    }
  • 401Non authentifié

Exemples

GET /api/v1/bpf/current-year · cURL / Shell
curl -X GET https://api.qualiforma.site/api/v1/bpf/current-year \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo"
GET /api/v1/bpf/current-year · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/current-year', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
GET /api/v1/bpf/current-year · Python
import requests

response = requests.get(
    'https://api.qualiforma.site/api/v1/bpf/current-year',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
GET /api/v1/bpf/current-year · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->get('bpf/current-year', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
get/api/v1/bpf/year/:year

Snapshot BPF d’une année fiscale

Retourne le snapshot figé du BPF pour une année donnée. Le snapshot est créé par POST /generate. Si aucun snapshot n'existe, renvoie 404.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025Année fiscale (YYYY)

Réponses

  • 200Snapshot trouvé
    Réponse 200 · JSON
    {
      "data": {
        "year": 2025,
        "totalTrainees": 412,
        "totalHours": 18640,
        "totalRevenueHT": 894320.55,
        "financingSources": {
          "opco": 412500,
          "cpf": 184200.55,
          "poleEmploi": 96300,
          "employer": 144320,
          "self": 57000
        },
        "byCategory": [
          {
            "code": "SAL",
            "label": "Salariés",
            "count": 268,
            "hours": 11240,
            "revenueHT": 612800
          },
          {
            "code": "DE",
            "label": "Demandeurs d’emploi",
            "count": 87,
            "hours": 4700,
            "revenueHT": 156300.55
          },
          {
            "code": "AUT",
            "label": "Autres publics",
            "count": 57,
            "hours": 2700,
            "revenueHT": 125220
          }
        ],
        "status": "GENERATED",
        "generatedAt": "2026-02-10T09:30:00Z",
        "submittedAt": null
      }
    }
  • 404Aucun snapshot pour cette année (lancer /generate)

Exemples

GET /api/v1/bpf/year/:year · cURL / Shell
curl -X GET https://api.qualiforma.site/api/v1/bpf/year/2025 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo"
GET /api/v1/bpf/year/:year · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
GET /api/v1/bpf/year/:year · Python
import requests

response = requests.get(
    'https://api.qualiforma.site/api/v1/bpf/year/2025',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
GET /api/v1/bpf/year/:year · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->get('bpf/year/2025', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
post/api/v1/bpf/year/:year/generate

Calculer ou regénérer le snapshot BPF

Calcule le BPF officiel à partir de toutes les sessions, conventions et factures de l'année. Idempotent : un nouvel appel écrase le snapshot précédent tant que celui-ci n'est pas SUBMITTED.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025—

Corps de requête

Content-Type : application/json

Body · JSON
{
  "force": false
}

Réponses

  • 200Snapshot généré
    Réponse 200 · JSON
    {
      "data": {
        "year": 2025,
        "status": "GENERATED",
        "generatedAt": "2026-02-10T09:30:00Z",
        "totalTrainees": 412,
        "totalHours": 18640,
        "totalRevenueHT": 894320.55
      }
    }
  • 409Snapshot déjà SUBMITTED — passer force=true pour forcer le recalcul

Exemples

POST /api/v1/bpf/year/:year/generate · cURL / Shell
curl -X POST https://api.qualiforma.site/api/v1/bpf/year/2025/generate \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo" \
  -H "Content-Type: application/json" \
  -d '{
  "force": false
}'
POST /api/v1/bpf/year/:year/generate · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025/generate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "force": false
  }),
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
POST /api/v1/bpf/year/:year/generate · Python
import requests

response = requests.post(
    'https://api.qualiforma.site/api/v1/bpf/year/2025/generate',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
        'Content-Type': 'application/json',
    },
    json={
        'force': False,
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
POST /api/v1/bpf/year/:year/generate · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->post('bpf/year/2025/generate', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
        'json' => [
            'force' => false,
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
get/api/v1/bpf/year/:year/export

Export PDF — CERFA n°10443*16

Génère le formulaire CERFA officiel n°10443*16 prérempli à partir du snapshot. Stream HTTP, Content-Type application/pdf.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025—

Réponses

  • 200PDF binaire (Content-Type application/pdf)
  • 404Snapshot inexistant — lancer /generate d’abord

Exemples

GET /api/v1/bpf/year/:year/export · cURL / Shell
curl -X GET https://api.qualiforma.site/api/v1/bpf/year/2025/export \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo"
GET /api/v1/bpf/year/:year/export · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025/export', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
GET /api/v1/bpf/year/:year/export · Python
import requests

response = requests.get(
    'https://api.qualiforma.site/api/v1/bpf/year/2025/export',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
GET /api/v1/bpf/year/:year/export · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->get('bpf/year/2025/export', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
get/api/v1/bpf/year/:year/export-csv

Export CSV brut (ligne par ligne)

Export tabulaire détaillé : une ligne par stagiaire avec heures, financement, catégorie. Utile pour audit DREETS ou réconciliation comptable.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025—
separatorquerynon;Séparateur CSV — défaut «;» (compatible Excel FR)

Réponses

  • 200Fichier CSV (Content-Type text/csv; charset=utf-8)
    Réponse 200 · JSON
    "traineeId;category;hours;financingSource;amountHT\nstg_001;SAL;42;OPCO;1820.00\nstg_002;DE;38;POLE_EMPLOI;980.00"
  • 404Snapshot inexistant

Exemples

GET /api/v1/bpf/year/:year/export-csv · cURL / Shell
curl -X GET https://api.qualiforma.site/api/v1/bpf/year/2025/export-csv?separator=%3B \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo"
GET /api/v1/bpf/year/:year/export-csv · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025/export-csv?separator=%3B', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
GET /api/v1/bpf/year/:year/export-csv · Python
import requests

response = requests.get(
    'https://api.qualiforma.site/api/v1/bpf/year/2025/export-csv?separator=%3B',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
GET /api/v1/bpf/year/:year/export-csv · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->get('bpf/year/2025/export-csv?separator=%3B', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
post/api/v1/bpf/year/:year/submit

Marquer comme soumis à la DGEFP

Verrouille le snapshot : aucun recalcul possible sans force=true. Enregistre la date de soumission et l'identifiant de récépissé DGEFP pour traçabilité.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025—

Corps de requête

Content-Type : application/json

Body · JSON
{
  "submittedAt": "2026-04-30",
  "receiptId": "DGEFP-2026-FR-9482103",
  "notes": "Soumission via télé-procédure DGEFP, validée 14:22."
}

Réponses

  • 200Snapshot verrouillé
    Réponse 200 · JSON
    {
      "data": {
        "year": 2025,
        "status": "SUBMITTED",
        "submittedAt": "2026-04-30T00:00:00Z",
        "receiptId": "DGEFP-2026-FR-9482103"
      }
    }
  • 409Snapshot déjà SUBMITTED

Exemples

POST /api/v1/bpf/year/:year/submit · cURL / Shell
curl -X POST https://api.qualiforma.site/api/v1/bpf/year/2025/submit \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo" \
  -H "Content-Type: application/json" \
  -d '{
  "submittedAt": "2026-04-30",
  "receiptId": "DGEFP-2026-FR-9482103",
  "notes": "Soumission via télé-procédure DGEFP, validée 14:22."
}'
POST /api/v1/bpf/year/:year/submit · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025/submit', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "submittedAt": "2026-04-30",
    "receiptId": "DGEFP-2026-FR-9482103",
    "notes": "Soumission via télé-procédure DGEFP, validée 14:22."
  }),
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
POST /api/v1/bpf/year/:year/submit · Python
import requests

response = requests.post(
    'https://api.qualiforma.site/api/v1/bpf/year/2025/submit',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
        'Content-Type': 'application/json',
    },
    json={
        'submittedAt': '2026-04-30',
        'receiptId': 'DGEFP-2026-FR-9482103',
        'notes': 'Soumission via télé-procédure DGEFP, validée 14:22.',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
POST /api/v1/bpf/year/:year/submit · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->post('bpf/year/2025/submit', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
        'json' => [
            'submittedAt' => '2026-04-30',
            'receiptId' => 'DGEFP-2026-FR-9482103',
            'notes' => 'Soumission via télé-procédure DGEFP, validée 14:22.',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
get/api/v1/bpf/year/:year/breakdown

Détail par publics et financements

Ventilation fine du BPF : par catégorie de public (SAL = salariés, DE = demandeurs d'emploi, AUT = autres) et par source de financement. Utilisé pour les tableaux du formulaire CERFA.

  • BPF
  • Qualiopi
  • DGEFP

Paramètres

NomTypeRequisExempleDescription
yearpathoui2025—

Réponses

  • 200Ventilation détaillée
    Réponse 200 · JSON
    {
      "data": {
        "year": 2025,
        "totalTrainees": 412,
        "totalHours": 18640,
        "totalRevenueHT": 894320.55,
        "financingSources": {
          "opco": 412500,
          "cpf": 184200.55,
          "poleEmploi": 96300,
          "employer": 144320,
          "self": 57000
        },
        "byCategory": [
          {
            "code": "SAL",
            "label": "Salariés",
            "count": 268,
            "hours": 11240,
            "revenueHT": 612800
          },
          {
            "code": "DE",
            "label": "Demandeurs d’emploi",
            "count": 87,
            "hours": 4700,
            "revenueHT": 156300.55
          },
          {
            "code": "AUT",
            "label": "Autres publics",
            "count": 57,
            "hours": 2700,
            "revenueHT": 125220
          }
        ]
      }
    }
  • 404Snapshot inexistant

Exemples

GET /api/v1/bpf/year/:year/breakdown · cURL / Shell
curl -X GET https://api.qualiforma.site/api/v1/bpf/year/2025/breakdown \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-Tenant-ID: qualiforma-demo"
GET /api/v1/bpf/year/:year/breakdown · JavaScript
const response = await fetch('https://api.qualiforma.site/api/v1/bpf/year/2025/breakdown', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'X-Tenant-ID': 'qualiforma-demo',
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const data = await response.json();
console.log(data);
GET /api/v1/bpf/year/:year/breakdown · Python
import requests

response = requests.get(
    'https://api.qualiforma.site/api/v1/bpf/year/2025/breakdown',
    headers={
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'X-Tenant-ID': 'qualiforma-demo',
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()
print(data)
GET /api/v1/bpf/year/:year/breakdown · PHP
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

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

try {
    $response = $client->get('bpf/year/2025/breakdown', [
        'headers' => [
            'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
            'X-Tenant-ID' => 'qualiforma-demo',
        ],
    ]);
    $data = json_decode($response->getBody()->getContents(), true);
    var_dump($data);
} catch (GuzzleException $e) {
    fwrite(STDERR, $e->getMessage());
}
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