EventCollab — API Documentation · Application Client (Organisation multi-rôle)

Base URL : https://api.eventcollab.app/api/v1 Auth : Bearer Token (Laravel Sanctum) Content-Type : application/json


Rôles dans l'application

Rôle Description Accès principal
org_admin Administrateur de l'organisation Tout gérer
trainer Formateur assigné à des classes Séances, présences, évaluations
supervisor Superviseur de groupes/classes Participants, présences, logement
participant Inscrit à un programme Mes inscriptions, paiements, quiz

Authentification

Inscription

POST /auth/register
{
  "name": "Jean Dupont",
  "email": "jean@example.com",
  "phone": "+22961234567",
  "password": "motdepasse",
  "password_confirmation": "motdepasse"
}

Connexion

POST /auth/login
{
  "email": "jean@example.com",
  "password": "motdepasse"
}

Réponse

{
  "success": true,
  "data": {
    "token": "2|xyz789...",
    "user": {
      "id": 12,
      "name": "Jean Dupont",
      "email": "jean@example.com",
      "phone": "+22961234567",
      "organization_id": 3,
      "roles": ["org_admin"]
    }
  }
}

Stocker le token et l'envoyer dans toutes les requêtes suivantes : Authorization: Bearer 2|xyz789...

Profil connecté

GET /auth/me

Déconnexion

POST /auth/logout

Mot de passe oublié

POST /auth/forgot-password
{ "email": "jean@example.com" }

Réinitialiser le mot de passe

POST /auth/reset-password
{
  "token": "reset_token_recu_par_email",
  "email": "jean@example.com",
  "password": "nouveaumotdepasse",
  "password_confirmation": "nouveaumotdepasse"
}

Vérification (code OTP)

POST /auth/verify
{ "code": "123456" }

Renvoyer le code OTP

POST /auth/resend-code

Programmes

Lister les programmes

GET /programs?search=formation&status=actif&type=presentiel&start_date=2026-07-01&per_page=15

Query params : search, status, type, start_date, end_date, sort_by, sort_dir, per_page

Créer un programme _(orgadmin)

POST /programs
{
  "title": "Formation Leadership 2026",
  "description": "Programme intensif de leadership.",
  "type": "presentiel",
  "status": "brouillon",
  "start_date": "2026-08-01",
  "end_date": "2026-08-15",
  "location": "Cotonou, Bénin",
  "max_participants": 30,
  "cover_image": "url_ou_base64"
}

Détail d'un programme

GET /programs/{id}

Modifier un programme

PUT /programs/{id}

Supprimer un programme

DELETE /programs/{id}

Activer le lien de paiement

PATCH /programs/{id}/payment-link
{
  "payment_enabled": true,
  "registration_fee": 75000,
  "fee_bearer": "participant"
}

fee_bearer : "participant" → frais ajoutés sur le montant du participant ; "organization" → frais déduits du net de l'org

Réponse (inclut le lien public à partager) :

{
  "data": {
    "payment_enabled": true,
    "registration_fee": 75000,
    "payment_link": "https://api.eventcollab.app/api/v1/public/pay/aBcDeFgH...",
    "payment_token": "aBcDeFgH..."
  }
}

Simuler les frais d'un programme (avant d'activer le lien)

POST /programs/{id}/simulate-fees
{
  "amount": 75000,
  "fee_bearer": "participant"
}

Réponse

{
  "data": {
    "amount": 75000,
    "fee_bearer": "participant",
    "breakdown": [
      {
        "method_name": "MTN Mobile Money Bénin",
        "base_amount": 75000,
        "aggregator_fee": 1275,
        "platform_fee": 600,
        "total_fee": 1875,
        "charge_amount": 76875,
        "net_amount": 75000
      }
    ]
  }
}

Classes & Groupes

Lister les classes d'un programme

GET /programs/{programId}/classes

Créer une classe

POST /programs/{programId}/classes
{
  "name": "Classe A",
  "description": "Groupe matinal",
  "capacity": 15
}

Assigner des formateurs à une classe

POST /programs/{programId}/classes/{classId}/trainers
{ "trainer_ids": [1, 2] }

Assigner des superviseurs à une classe

POST /programs/{programId}/classes/{classId}/supervisors
{ "supervisor_ids": [3] }

Créer un groupe dans une classe

POST /programs/{programId}/classes/{classId}/groups
{
  "name": "Groupe 1",
  "supervisor_id": 3
}

Séances & Présences

Lister les séances d'un programme

GET /programs/{programId}/sessions

Créer une séance

POST /programs/{programId}/sessions
{
  "title": "Introduction au Leadership",
  "class_id": 1,
  "trainer_id": 2,
  "date": "2026-08-02",
  "start_time": "09:00",
  "end_time": "12:00",
  "location": "Salle A",
  "description": "Séance d'ouverture"
}

Voir les présences d'une séance

GET /programs/{programId}/sessions/{sessionId}/attendances

Marquer les présences

POST /programs/{programId}/sessions/{sessionId}/attendances
{
  "attendances": [
    { "participant_id": 1, "status": "present" },
    { "participant_id": 2, "status": "absent" },
    { "participant_id": 3, "status": "retard" }
  ]
}

status : present | absent | retard | excuse


Participants

Lister les participants d'un programme

GET /programs/{programId}/participants?status=valide&class_id=1&per_page=20

Inscrire un participant

POST /programs/{programId}/participants
{
  "user_id": 15,
  "class_id": 1,
  "group_id": null,
  "registration_data": {
    "profession": "Ingénieur",
    "entreprise": "Société ABC"
  }
}

Détail d'un participant

GET /programs/{programId}/participants/{participantId}

Valider un participant

POST /programs/{programId}/participants/{participantId}/validate

Rejeter un participant

POST /programs/{programId}/participants/{participantId}/reject
{ "reason": "Dossier incomplet" }

Changer de classe / groupe

PATCH /programs/{programId}/participants/{participantId}/assign
{
  "class_id": 2,
  "group_id": 4
}

Formateurs

Lister les formateurs

GET /trainers

Créer un formateur

POST /trainers
{
  "user_id": 20,
  "specialties": ["Leadership", "Management", "Communication"],
  "bio": "Formateur certifié avec 10 ans d'expérience.",
  "contract_type": "freelance",
  "hourly_rate": 25000
}

Uploader un document formateur

POST /trainers/{id}/documents
Content-Type: multipart/form-data

file: [fichier]
name: "CV Jean Dupont"
type: "cv"

Superviseurs

Lister les superviseurs

GET /supervisors

Créer un superviseur

POST /supervisors
{
  "user_id": 25,
  "bio": "Superviseur expérimenté."
}

Statistiques d'un superviseur

GET /supervisors/{id}/stats

Logement

Créer un lieu d'hébergement

POST /accommodations/venues
{
  "name": "Hôtel du Lac Nokoué",
  "address": "Boulevard de la Marina",
  "city": "Cotonou",
  "country": "Bénin",
  "type": "hotel",
  "total_capacity": 50,
  "contact_name": "M. Adjovi",
  "contact_phone": "+22997111111",
  "contact_email": "reservation@hotellac.bj",
  "price_per_night": 35000,
  "notes": "Parking gratuit, petit-déjeuner inclus"
}

type : hotel | residence | maison | campus | dortoir | autre

Lister les lieux

GET /accommodations/venues?type=hotel&city=Cotonou

Détail d'un lieu (avec chambres et occupation)

GET /accommodations/venues/{venueId}

Ajouter une chambre à un lieu

POST /accommodations/venues/{venueId}/rooms
{
  "name": "Chambre 101",
  "floor": "1er étage",
  "type": "chambre_double",
  "capacity": 2,
  "amenities": ["wifi", "climatisation", "sdb_privee", "tv"],
  "price_per_night": 35000
}

type : chambre_simple | chambre_double | chambre_triple | dortoir | suite | studio | autre

Lister les chambres d'un lieu (avec disponibilités)

GET /accommodations/venues/{venueId}/rooms?program_id=3

Plan logement d'un programme (qui dort où)

GET /programs/{programId}/accommodations

Personnes sans logement dans un programme

GET /programs/{programId}/accommodations/unhoused

Réponse (participants + formateurs + superviseurs sans chambre) :

{
  "data": {
    "participants": [{ "user_id": 15, "name": "Ama Koffi", "role": "participant" }],
    "trainers":     [{ "user_id": 20, "name": "Marc Ahounou", "role": "trainer" }],
    "supervisors":  [{ "user_id": 25, "name": "Alice Fiogbé", "role": "supervisor" }],
    "total_unhoused": 3
  }
}

Affecter une personne à une chambre

POST /programs/{programId}/accommodations/assign
{
  "room_id": 5,
  "user_id": 15,
  "occupant_role": "participant",
  "check_in": "2026-08-01",
  "check_out": "2026-08-15",
  "notes": "Chambre accessible PMR demandée"
}

occupant_role : participant | trainer | supervisor | organizer | other

Affecter plusieurs personnes en masse

POST /programs/{programId}/accommodations/assign-bulk
{
  "assignments": [
    { "room_id": 5, "user_id": 15, "role": "participant", "check_in": "2026-08-01" },
    { "room_id": 6, "user_id": 20, "role": "trainer",     "check_in": "2026-07-31" }
  ]
}

Enregistrer un check-out

PATCH /programs/{programId}/accommodations/assignments/{assignmentId}/checkout
{ "check_out": "2026-08-15" }

Annuler une affectation

DELETE /programs/{programId}/accommodations/assignments/{assignmentId}

Évaluations de connaissance

Lister les évaluations

GET /evaluations?program_id=3

Créer une évaluation

POST /evaluations
{
  "program_id": 3,
  "seance_id": 12,
  "class_id": 1,
  "title": "QCM Module 1",
  "description": "Évaluation de fin de module 1",
  "duration_minutes": 30,
  "max_attempts": 2,
  "passing_score": 60,
  "total_points": 100,
  "auto_correct": true,
  "shuffle_questions": true,
  "available_from": "2026-08-05 09:00:00",
  "available_until": "2026-08-05 12:00:00",
  "questions": [
    {
      "type": "qcm",
      "question": "Qu'est-ce que le leadership situationnel ?",
      "options": ["Style unique", "Adaptation au contexte", "Autorité hiérarchique", "Travail d'équipe"],
      "correct_answer": [1],
      "points": 2,
      "order": 1
    },
    {
      "type": "vrai_faux",
      "question": "Un leader doit toujours imposer ses décisions.",
      "correct_answer": false,
      "points": 1,
      "order": 2
    },
    {
      "type": "ouverte",
      "question": "Décrivez votre style de leadership.",
      "points": 5,
      "order": 3
    }
  ]
}

Démarrer une tentative (participant)

POST /evaluations/{id}/start

Réponse : questions mélangées (sans les bonnes réponses), attempt_id

Soumettre les réponses

POST /evaluations/{id}/attempts/{attemptId}/submit
{
  "answers": [
    { "question_id": 1, "answer": [1] },
    { "question_id": 2, "answer": false },
    { "question_id": 3, "answer": "Le leadership est avant tout une affaire d'écoute..." }
  ]
}

Corriger manuellement une réponse ouverte (formateur/admin)

POST /evaluations/{id}/attempts/{attemptId}/answers/{answerId}/correct
{
  "score": 4,
  "comment": "Bonne réflexion, manque un exemple concret."
}

Kahoot Live

Lister les quiz

GET /kahoot/quizzes?program_id=3

Créer un quiz

POST /kahoot/quizzes
{
  "program_id": 3,
  "title": "Quiz Récap — Journée 1",
  "description": "Quiz de fin de journée",
  "questions": [
    {
      "question": "Quel est le premier principe du leadership ?",
      "options": [
        { "text": "Commander", "is_correct": false },
        { "text": "Écouter", "is_correct": true },
        { "text": "Punir", "is_correct": false },
        { "text": "Ignorer", "is_correct": false }
      ],
      "time_seconds": 20,
      "points": 100,
      "order": 1
    }
  ]
}

Démarrer une session live (formateur)

POST /kahoot/quizzes/{quizId}/start

Réponse : session_code (ex: "KH-4729") à afficher sur le beamer

Rejoindre une session (participant)

POST /kahoot/sessions/join
{ "session_code": "KH-4729" }

Diffuser la question suivante (formateur — WebSocket)

POST /kahoot/sessions/{sessionId}/broadcast

Répondre à une question (participant)

POST /kahoot/sessions/{sessionId}/answer
{
  "question_index": 0,
  "answer_index": 1
}

Terminer la session et voir le classement

POST /kahoot/sessions/{sessionId}/end
GET  /kahoot/sessions/{sessionId}/results

Attestations & Certificats

Lister les certificats

GET /certificates

Lister les modèles de certificats

GET /certificate-templates

Créer un modèle de certificat

POST /certificate-templates
{
  "name": "Certificat Standard EventCollab",
  "html_template": "<html>...</html>",
  "variables": ["participant_name", "program_title", "completion_date"]
}

Émettre un certificat pour un participant

POST /certificates/issue
{
  "participant_id": 15,
  "template_id": 1,
  "data": {
    "completion_date": "2026-08-15"
  }
}

Émettre en masse (tous les participants validés)

POST /certificates/issue-bulk
{
  "program_id": 3,
  "template_id": 1
}

Révoquer un certificat

PATCH /certificates/{id}/revoke

Vérifier un certificat (public, sans auth)

GET /public/certificates/{number}/verify

Documents

Lister les documents générés

GET /documents

Générer un document (PDF/Word)

POST /documents/generate
{
  "template_id": 2,
  "participant_id": 15,
  "data": { "date": "2026-08-15" }
}

Télécharger / voir un document

GET /documents/{id}

Paiements (côté organisateur)

Tableau de bord paiements

GET /payments/dashboard

Lister les paiements reçus

GET /payments?status=paye&program_id=3&per_page=20

Vérifier manuellement un paiement

POST /payments/{id}/verify

Lien de paiement public (partagé aux participants)

Ces routes n'ont pas besoin d'authentification.

Afficher le formulaire de paiement

GET /public/pay/{token}

Réponse : infos du programme + toutes les méthodes de paiement avec aperçu des frais

{
  "data": {
    "program": {
      "title": "Formation Leadership 2026",
      "registration_fee": 75000,
      "fee_bearer": "participant"
    },
    "payment_methods": [
      {
        "id": 1,
        "name": "MTN Mobile Money",
        "code": "mtn_bj",
        "fee_preview": {
          "base_amount": 75000,
          "aggregator_fee": 1275,
          "platform_fee": 600,
          "total_fee": 1875,
          "charge_amount": 76875,
          "who_pays": "participant"
        }
      }
    ]
  }
}

Payer via le lien public

POST /public/pay/{token}
{
  "payment_method_id": 1,
  "phone": "+22961234567",
  "payer_name": "Ama Koffi",
  "payer_email": "ama@example.com",
  "participant_id": 15
}

Réponse : temp_ref pour le polling

Polling statut du paiement

GET /public/pay/{token}/status/{tempRef}
{
  "data": {
    "status": "completed",
    "payment_status": "paye",
    "paid_at": "2026-08-01T10:35:22Z"
  }
}

Paiement in-app (participant connecté)

Le participant est connecté avec son token Sanctum.

Mes inscriptions + statut paiement

GET /my/enrollments

Détail paiement d'une inscription (méthodes + frais)

GET /my/enrollments/{participantId}/payment

Payer depuis l'app

POST /my/enrollments/{participantId}/pay
{
  "payment_method_id": 1,
  "phone": "+22961234567"
}

Si phone est omis, utilise le numéro du profil utilisateur.

Historique de mes paiements

GET /my/payments?status=paye

Statut d'un paiement (polling)

GET /my/payments/{paymentId}/status

Portefeuille & Retraits _(orgadmin)

Solde du portefeuille

GET /wallet/balance
{
  "data": {
    "available_balance": 2450000,
    "pending_withdrawal": 500000,
    "total_credited": 3200000,
    "total_debited": 750000,
    "gross_collected": 3280000,
    "aggregator_fees": 55760,
    "platform_fees": 26240,
    "currency": "XOF"
  }
}

Lister les comptes de retrait

GET /wallet/accounts

Ajouter un compte de retrait

POST /wallet/accounts
{
  "payment_method_id": 1,
  "phone": "+22961234567",
  "account_name": "Jean Dupont",
  "label": "Mon MTN Principal"
}

Demander un retrait

POST /wallet/withdrawals
{
  "payout_account_id": 2,
  "amount": 500000,
  "note": "Retrait mensuel"
}

Annuler un retrait (si encore en attente)

POST /wallet/withdrawals/{id}/cancel

Statut d'un retrait (polling)

GET /withdrawals/{id}/status

Rapports & Analytics

Dashboard général

GET /reports/dashboard

Rapport de présence

GET /reports/attendance?program_id=3&class_id=1

Progression des participants

GET /reports/participants?program_id=3

Rapport financier

GET /reports/financial?program_id=3&from=2026-08-01&to=2026-08-31

Performance des formateurs

GET /reports/trainers?program_id=3

Checklists & Tâches

Créer une checklist

POST /checklists
{
  "program_id": 3,
  "title": "Checklist logistique",
  "description": "Préparation salle de formation"
}

Ajouter des tâches

POST /checklists/{id}/tasks
{
  "tasks": [
    { "title": "Réserver le matériel", "due_date": "2026-07-30", "assigned_to": 5 },
    { "title": "Préparer les badges", "due_date": "2026-07-31", "assigned_to": 5 }
  ]
}

Mettre à jour une tâche

PUT /checklists/{id}/tasks/{taskId}
{ "status": "done" }

Tâches en retard

GET /tasks/overdue

Formulaires d'évaluation (satisfaction)

Créer un formulaire

POST /org-forms
{
  "title": "Satisfaction formation Leadership",
  "program_id": 3,
  "fields": [
    { "label": "Note globale", "type": "rating", "required": true },
    { "label": "Commentaires", "type": "textarea", "required": false }
  ],
  "is_active": true
}

Voir les résultats d'un formulaire

GET /org-forms/{id}/results

Répondre à un formulaire (participant via lien partagé)

POST /public/forms/{shareLink}/respond
Authorization: Bearer {token}
{
  "answers": [
    { "field": "Note globale", "value": 4 },
    { "field": "Commentaires", "value": "Très bonne formation, formateur compétent." }
  ]
}

Méthodes de paiement disponibles

Pour initier un paiement

GET /payment-methods/for-payment

Pour effectuer un retrait

GET /payment-methods/for-withdrawal

Simuler les frais d'un montant

POST /payment-methods/simulate-fee
{
  "amount": 50000,
  "payment_method_id": 1
}

WebSocket (Kahoot Live)

Connexion : ws://api.eventcollab.app:8080/app/{APP_KEY}

Canal Événement Description
quiz-session.{sessionId} question.broadcast Nouvelle question diffusée
quiz-session.{sessionId} session.ended Fin de session + classement

Exemple avec Laravel Echo / Pusher SDK :

Echo.channel(`quiz-session.${sessionId}`)
  .listen('QuestionBroadcast', (e) => {
    // e.question, e.options, e.time_seconds
    displayQuestion(e)
  })
  .listen('SessionEnded', (e) => {
    // e.results, e.ranking
    showResults(e)
  })

Codes de réponse

Code Signification
200 Succès
201 Créé
401 Non authentifié — token manquant ou expiré
403 Accès refusé — rôle insuffisant ou ressource d'une autre org
404 Ressource introuvable
422 Erreur de validation — voir le champ errors
429 Trop de requêtes
500 Erreur serveur

Format de réponse standard :

{
  "success": true,
  "data": { ... },
  "message": "Opération réussie"
}

Format d'erreur :

{
  "success": false,
  "message": "Validation error",
  "errors": {
    "phone": ["Le numéro de téléphone est invalide."]
  }
}

Pagination

Toutes les listes paginées retournent :

{
  "data": [...],
  "meta": {
    "current_page": 1,
    "last_page": 5,
    "per_page": 15,
    "total": 72
  },
  "links": {
    "first": "...",
    "last": "...",
    "prev": null,
    "next": "https://api.eventcollab.app/api/v1/programs?page=2"
  }
}

Multi-tenant — Important pour les développeurs

Toutes les ressources sont automatiquement filtrées par organisation. Un token appartenant à l'org #3 ne verra jamais les données de l'org #5. Il n'est pas nécessaire d'envoyer organization_id dans les requêtes — c'est déduit du token.


Généré le 2026-06-28 — EventCollab API v1 — GroupDev SAS