PassPassPassPass
DOCS
Documentation
Mises à jour
Créer un événement
Accueil
PassPassPassPass

Le service de billetterie pour les organisateurs d'événements.

Découvrir PassPass Pro →

Documentation

Démarrage rapideTous les thèmesTous les articlesMises à jour

Liens rapides

PassPass ProQuestions fréquentesOuvrir un ticketNous contacter

Accès rapide

© 2024 PassPass. Tous droits réservés.
Mentions légalesPassPass - Billetterie pour événements

API publique : référence technique

Référence technique pour consommer l'API REST PassPass. Endpoints, permissions, pagination, structure des réponses et exemples.

Dernière mise à jour : 7 août 2026

Cet article est destiné à la personne qui consomme l'API REST PassPass. Pour une vue d'ensemble et la configuration depuis le dashboard, consultez API publique et Webhooks.

Documentation interactive (Swagger) : api.passpass.be/api/public/docs


Authentification

Chaque requête porte votre clé API dans le header Authorization :

GET /api/v1/events HTTP/1.1
Host: api.passpass.be
Authorization: Bearer pk_live_9f2c4a1b...

La clé est liée à votre organisation. Toutes les données renvoyées sont filtrées automatiquement sur votre organisation.

Le secret de la clé n'est affiché qu'une seule fois à la création. Si vous le perdez, effectuez une rotation depuis le dashboard (l'ancien secret cesse de fonctionner immédiatement).

Validez votre configuration au démarrage avec GET /v1/me : c'est le seul endpoint qui ne requiert aucun scope.


Endpoints disponibles

L'API est en lecture seule. 7 endpoints GET :

  • GET /v1/me : introspection de votre clé API (scopes, organisation, dernière utilisation). Aucun scope requis

  • GET /v1/events : liste de vos événements (tous statuts, brouillons et privés inclus). Scope : events:read

  • GET /v1/events/:id : détail d'un événement. Scope : events:read

  • GET /v1/orders : liste des commandes. Scope : orders:read

  • GET /v1/orders/:id : détail d'une commande. Scope : orders:read

  • GET /v1/events/:eventId/attendees : participants d'un événement. Scope : attendees:read

  • GET /v1/orders/:orderId/attendees : participants d'une commande. Scope : attendees:read


Permissions (scopes)

Les scopes contrôlent les champs renvoyés, pas seulement l'accès aux endpoints. Un champ non autorisé est absent, pas null.

  • events:read : accès aux endpoints événements

  • orders:read : accès aux endpoints commandes (montant, acheteur, billing, line items, statut)

  • orders:read:financial : service_fee, payout_amount, refundable_amount, historical_service_fee

  • orders:read:form_answers : réponses au formulaire de commande

  • attendees:read : accès aux endpoints participants (données minimales, aucune donnée personnelle)

  • attendees:read:contact : first_name, last_name, email

  • attendees:read:financial : ticket_price

  • attendees:read:form_answers : réponses au formulaire participant

  • attendees:read:full : access_token (inclut automatiquement contact et financial)

Les scopes sont figés à la création de la clé. Pour modifier les permissions, créez une nouvelle clé et retirez l'ancienne. access_token est l'identifiant secret derrière le QR code du billet. Ne demandez attendees:read:full que si votre système en a réellement besoin.


Pagination

Toutes les listes sont paginées :

{
  "data": [],
  "total": 137,
  "page": 1,
  "limit": 25,
  "total_pages": 6
}

Paramètres : ?page= (défaut 1) et ?limit= (défaut 25, maximum 100). Paginez toujours jusqu'à total_pages et relisez le limit renvoyé.


Conventions

  • Champs en snake_case (exception : buyer et billing en camelCase)

  • Montants en euros (pas en centimes). 25 = 25,00€

  • Dates en ISO 8601 UTC

  • Champs multilingues : {"fr": "...", "en": "...", "nl": "..."}

  • Champ non autorisé par les scopes : absent, pas null

  • Nouveaux champs possibles sans préavis, ne rejetez pas un champ inconnu


Événements

GET /v1/events renvoie tous vos événements (brouillons et privés inclus, seuls les supprimés sont exclus). Pas de filtre par statut ou date côté API : filtrez côté client sur status / start_at.

Cas d'usage : tableau de bord de jauge, suivi des stocks de tickets, liste d'événements dans un back-office.

{
  "id": 1535,
  "title": {"fr": "Mon événement"},
  "short_description": {"fr": "Description courte"},
  "address_label": {"fr": "Bruxelles"},
  "address_full": {"fr": "Rue de la Loi 1, 1000 Bruxelles"},
  "status": "published",
  "visibility": "public",
  "sold_count": 128,
  "max_capacity": 500,
  "start_at": "2026-06-01T18:00:00.000Z",
  "end_at": "2026-06-01T23:00:00.000Z",
  "timezone": "Europe/Brussels",
  "currency": "EUR",
  "tickets": [
    {
      "id": 4525,
      "type": "ticket",
      "name": {"fr": "Entrée Standard"},
      "description": null,
      "price": 25,
      "vat_rate": 21,
      "max_quantity": 300,
      "sold_count": 128,
      "visibility": "visible",
      "sell_start_at": null,
      "sell_end_at": null
    }
  ],
  "created_at": "2026-01-12T14:22:00.000Z",
  "updated_at": "2026-04-17T09:00:00.000Z"
}

Commandes

GET /v1/orders renvoie les commandes de votre organisation.

Filtres disponibles

  • status : paid (défaut), pending, cancelled, ou all

  • created_after : date ISO-8601, commandes créées à partir de cet instant (inclus)

  • created_before : date ISO-8601, commandes créées jusqu'à cet instant (inclus)

Par défaut, seules les commandes payées sont renvoyées. Passez ?status=all si vous voulez le portrait complet (annulations, paniers en cours). C'est le piège le plus courant pour les rapprochements comptables.

Statuts

  • paid : payée et non annulée

  • cancelled : annulée (qu'elle ait été payée ou non). Les commandes expirées (panier abandonné) s'y retrouvent aussi

  • pending : ni payée ni annulée (panier en cours, virement en attente)

Cas d'usage : export comptable, rapprochement financier, synchronisation CRM.

{
  "id": 65817,
  "event_id": 1535,
  "status": "paid",
  "origin": "online",
  "currency": "EUR",
  "amount_total": 200,
  "buyer": {
    "firstName": "Marie",
    "lastName": "Dupont",
    "email": "marie@example.com"
  },
  "billing": {
    "identifierType": "vat",
    "companyName": "Demo Corp SRL",
    "vat": "BE0123456789",
    "vatCountry": "BE",
    "addressStreet": "Rue de la Loi 1",
    "addressCity": "Bruxelles",
    "addressZip": "1000",
    "addressCountry": "BE"
  },
  "line_items": [
    {
      "type": "ticket",
      "ticket_id": 4525,
      "name": {"fr": "Entrée Standard"},
      "quantity": 2,
      "unit_amount": 100,
      "subtotal": 200
    }
  ],
  "form_answers": null,
  "paid_at": "2026-04-17T10:00:00.000Z",
  "cancelled_at": null,
  "created_at": "2026-04-17T10:00:00.000Z",
  "updated_at": "2026-04-17T10:00:00.000Z",
  "service_fee": 4.6,
  "payout_amount": 195.4,
  "refundable_amount": 4.6,
  "historical_service_fee": 4.6
}

Comprendre les champs

buyer : identité saisie au checkout (prénom, nom, email). En camelCase.

billing : données de facturation société. Présent uniquement si l'acheteur a coché "je commande au nom d'une société" au checkout. Sinon null. En camelCase. Contient : identifierType (vat ou enterprise), companyName, vat, vatCountry, addressStreet, addressCity, addressZip, addressCountry.

line_items : détail de la commande. Chaque ligne a un type :

  • ticket : billet acheté, unit_amount = prix unitaire

  • fee : frais de service (une seule ligne agrégée)

  • discount : code promo / remise, unit_amount négatif

Bloc financier (scope orders:read:financial) :

  • service_fee : frais de service actuels

  • historical_service_fee : frais figés au moment de la vente

  • payout_amount : montant net à reverser à l'organisateur

  • refundable_amount : part des frais encore remboursable

form_answers (scope orders:read:form_answers) : réponses au formulaire personnalisé de la commande.


Participants

GET /v1/events/:eventId/attendees ou GET /v1/orders/:orderId/attendees renvoie les participants. Un participant = un billet.

Seuls les participants au statut active sont renvoyés. Les billets annulés ou en brouillon sont absents.

Cas d'usage : liste d'émargement, contrôle d'accès hors ligne, export nominatif.

{
  "id": "019fdb0d-...",
  "event_id": 1535,
  "order_id": 65817,
  "status": "active",
  "ticket": {
    "id": 4525,
    "type": "ticket",
    "name": {"fr": "Entrée Standard"}
  },
  "first_name": "Marie",
  "last_name": "Dupont",
  "email": "marie@example.com",
  "ticket_price": 100,
  "access_token": "019fdb0d-...",
  "created_at": "2026-04-17T10:00:00.000Z",
  "updated_at": "2026-04-17T10:00:00.000Z",
  "form_answers": [
    {
      "type": "selection",
      "field_id": "abc123...",
      "question_title": {"fr": "Quel est votre statut actuel ?"},
      "answer": {"fr": "Indépendant"}
    },
    {
      "type": "unique-choice",
      "field_id": "def456...",
      "question_title": {"fr": "Régime alimentaire"},
      "answer": {"fr": "Végétarien"}
    },
    {
      "type": "short-text",
      "field_id": "ghi789...",
      "question_title": {"fr": "Nom entreprise"},
      "answer": "Demo Corp"
    },
    {
      "type": "formatted-field",
      "field_id": "jkl012...",
      "question_title": {"fr": "Téléphone"},
      "answer": "+32400000000"
    },
    {
      "type": "formatted-field",
      "field_id": "mno345...",
      "question_title": {"fr": "Code postal"},
      "answer": "1000"
    }
  ]
}

Comprendre les champs

Les champs sont conditionnés par les scopes. Absents si le scope n'est pas accordé :

  • first_name, last_name, email (scope attendees:read:contact)

  • ticket_price (scope attendees:read:financial) : montant en euros

  • form_answers (scope attendees:read:form_answers) : réponses au formulaire participant. Types possibles : selection, unique-choice, short-text, formatted-field. Les types selection et unique-choice ont des réponses multilingues, les autres des réponses string

  • access_token (scope attendees:read:full) : l'identifiant secret derrière le QR code du billet, lu par l'application mobile PassPass Organizer lors du contrôle des entrées. Ce jeton peut par exemple être réattribué sur un badge pour répliquer un QR code lisible par le contrôle de tickets PassPass. Transmettre ce jeton revient à donner l'accès au billet


Introspection

GET /v1/me renvoie les informations de votre clé. Aucun scope requis.

{
  "api_key_id": "019d-...",
  "api_key_prefix": "pk_live_9f2c4a1b",
  "api_key_name": "Production server",
  "organization_id": "019d-...",
  "scopes": ["events:read", "orders:read", "attendees:read"],
  "last_used_at": "2026-04-17T09:58:00.000Z",
  "created_at": "2026-01-12T14:22:00.000Z"
}

Limites

100 requêtes par minute par clé API. Au-delà : HTTP 429. Si votre besoin est du temps réel, utilisez les webhooks plutôt que du polling.


Codes d'erreur

  • 401 : clé absente, invalide ou désactivée

  • 403 : clé valide mais scope insuffisant

  • 404 : ressource inexistante ou hors de votre organisation

  • 400 : paramètre invalide (status, format de date...)

  • 429 : quota dépassé (100 req/min)


API ou Webhooks ?

  • Réagir à une vente en temps réel → Webhooks order.paid

  • Synchroniser un CRM au fil de l'eau → Webhooks + API en rattrapage

  • Export comptable, rapprochement → API /v1/orders?status=all&created_after=...

  • Liste d'émargement, contrôle d'accès → API /v1/events/:id/attendees

  • Tableau de bord jauge / stocks → API /v1/events (sold_count, max_quantity)

  • Rejouer un historique passé → API (les webhooks ne rejouent pas le passé)

Le schéma robuste : webhooks pour le temps réel + appel API périodique pour rattraper ce qu'un incident réseau aurait fait manquer.


Pour toute question technique ou besoin d'accompagnement, n'hésitez pas à contacter notre support.

Contactez-nous

Articles liés

3 articles dans cette catégorie