StudEvent API
L'API publique de StudEvent permet à ton BDE d'intégrer la billetterie directement sur son site : afficher tes événements, vendre des places, valider des billets, recevoir des notifications temps réel.
https://studevent-app.com/api/v1Bearer sk_live_…JSON · UTF-8Toutes les requêtes utilisent HTTPS et retournent du JSON. L'API est versionnée via le préfixe /v1. Les ruptures de compatibilité ouvriront une nouvelle version — la v1 restera servie sans changement.
Authentification
Toutes les requêtes doivent porter un header Authorization avec une clé API créée depuis ton dashboard Paramètres → API & Webhooks. Chaque clé est rattachée à ton organisation et porte un ensemble de scopes qui limitent ce qu'elle peut faire.
curl https://studevent-app.com/api/v1/events \
-H "Authorization: Bearer sk_live_XXXXXXXXXXXXXXXXXXXXXXXX"Scopes disponibles
| Champ | Type | Description |
|---|---|---|
events:read | string | Lecture des événements & tarifs publiés. |
orders:read | string | Lecture des commandes (statut, total, billets). |
tickets:read | string | Lecture des billets émis. |
tickets:write | string | Marquer un billet comme scanné (point d’entrée custom). |
checkout:write | string | Créer un checkout — démarrer un paiement Stripe. |
webhooks:manage | string | CRUD sur les endpoints webhooks via l’API. |
⚠️ Stocke tes clés côté serveur uniquement. Une clé sk_live_… exposée dans du JavaScript public donne accès à toutes les commandes et billets de ton BDE.Erreurs
L'API retourne des codes HTTP standards. Les erreurs renvoient un objet JSON avec un type machine-friendly et un message humain.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": {
"type": "invalid_api_key",
"message": "Unknown or revoked API key."
}
}| Champ | Type | Description |
|---|---|---|
400 | invalid_request | Paramètres manquants ou invalides. |
401 | authentication_required / invalid_api_key | Header Authorization absent ou clé inconnue. |
403 | permission_denied / insufficient_scope | La clé n’a pas le scope requis pour cette action. |
404 | resource_not_found | La ressource ciblée n’existe pas dans ton organisation. |
429 | rate_limited | Limite de débit atteinte — réessaie après le délai indiqué. |
500 | internal_error | Erreur côté serveur StudEvent — réessaie ou contacte-nous. |
Pagination
Les endpoints de liste retournent { object: "list", data: [...], has_more, next_cursor }. Pour récupérer la page suivante, repasse next_cursor dans le paramètre cursor.
# Première page
curl "https://studevent-app.com/api/v1/events?limit=20" -H "Authorization: Bearer $KEY"
# Page suivante
curl "https://studevent-app.com/api/v1/events?limit=20&cursor=2026-05-22T10:14:32Z" \
-H "Authorization: Bearer $KEY"Événements
Objets publics — la base pour afficher ta billetterie sur ton site.
Lister les événements
/v1/eventsscope: events:read| Champ | Type | Description |
|---|---|---|
status | string? | draft, published (défaut), closed, archived. |
limit | int? | 1 à 100, défaut 20. |
cursor | string? | ISO timestamp, retourné via next_cursor. |
curl "https://studevent-app.com/api/v1/events?limit=10" \
-H "Authorization: Bearer $STUDEVENT_KEY"Récupérer un événement
/v1/events/{id_or_slug}scope: events:readRenvoie l'événement avec ses ticket_types inline (tarif, quota, disponibilité). Accepte soit l'UUID, soit le slug.
curl https://studevent-app.com/api/v1/events/gala-2026 \
-H "Authorization: Bearer $STUDEVENT_KEY"Checkout
Crée une commande en statut pending et reçois l'URL Stripe vers laquelle rediriger l'acheteur. Une fois le paiement validé, le billet est émis automatiquement par notre webhook Stripe et l'événement order.paid est envoyé à tes endpoints souscrits.
/v1/checkout/sessionsscope: checkout:write| Champ | Type | Description |
|---|---|---|
event_idrequired | string | UUID de l’événement publié. |
ticket_type_idrequired | string | UUID du tarif choisi. |
emailrequired | string | Email de l’acheteur (le billet y sera envoyé). |
first_namerequired | string | Prénom du porteur. |
last_namerequired | string | Nom du porteur. |
responses | object? | Map des réponses au formulaire custom (clé → valeur). |
curl -X POST https://studevent-app.com/api/v1/checkout/sessions \
-H "Authorization: Bearer $STUDEVENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_id": "a1b2c3d4-…",
"ticket_type_id": "tt_…",
"email": "leo@example.com",
"first_name": "Léo",
"last_name": "Martin",
"responses": { "promo_id": "2027", "campus_id": "lyon" }
}'Commandes
/v1/orders/{ref}scope: orders:readAccepte un display_ref (O-2026-XXXXXXXX) ou un UUID. Renvoie la commande avec ses tickets émis inline.
curl https://studevent-app.com/api/v1/orders/O-2026-X4F8K2QM \
-H "Authorization: Bearer $STUDEVENT_KEY"Billets
/v1/tickets/{ref}scope: tickets:readRécupère un billet par display_ref (T-2026-XXXXXXXX) ou UUID.
Scan
Endpoint server-to-server pour valider un billet à l'entrée — utile si tu construis ton propre point de contrôle (tourniquet, app native, etc.). Pour le scanner web standard, utilise l'interface dashboard intégrée.
/v1/tickets/{ref}/scanscope: tickets:write| Champ | Type | Description |
|---|---|---|
qr | string? | QR payload brut — si fourni, la signature HMAC est vérifiée. |
gate_id | string? | UUID de la porte/zone, pour les statistiques. |
device_id | string? | Identifiant libre du device scanner. |
curl -X POST https://studevent-app.com/api/v1/tickets/T-2026-XFXPBBC5/scan \
-H "Authorization: Bearer $STUDEVENT_KEY" \
-H "Content-Type: application/json" \
-d '{"gate_id": "porte-A", "device_id": "ipad-01"}'Webhooks
Les webhooks permettent à ton site BDE de recevoir des notifications en temps réel quand quelque chose se passe sur StudEvent : un billet vient d'être payé, un participant vient de passer à l'entrée, une commande a été remboursée. Tu configures un ou plusieurs endpoints HTTPS, et StudEvent y envoie des requêtes POST JSON signées.
Vérifier la signature
Chaque requête webhook porte un header studevent-signature au format t=<timestamp>,v1=<hex_hmac>. Le HMAC est calculé sur la chaîne `${timestamp}.${rawBody}` avec ton signing_secret.
import crypto from "node:crypto";
export function verify(req, body) {
const header = req.headers["studevent-signature"] ?? "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto
.createHmac("sha256", process.env.STUDEVENT_WEBHOOK_SECRET)
.update(`${parts.t}.${body}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(parts.v1, "hex"),
);
}Rejette toute requête où |now − t| > 300s pour empêcher les attaques par rejeu.Types d'événements
| Champ | Type | Description |
|---|---|---|
order.paid | event | Une commande est passée à status=paid. Le billet a été émis. |
order.refunded | event | La commande a été remboursée par le BDE. |
ticket.created | event | Un nouveau billet a été émis (juste avant order.paid). |
ticket.scanned | event | Un billet est passé à l’entrée (premier scan valide). |
refund.created | event | Audit du remboursement effectué — qui, quand, raison. |
Format du payload
POST https://mon-bde.fr/api/studevent-webhook
Headers:
studevent-signature: t=1748044819,v1=abc123…
studevent-event: order.paid
Content-Type: application/json
{
"id": "evt_8KqLm2",
"type": "order.paid",
"created": 1748044819,
"data": {
"order_id": "o_…",
"order_ref": "O-2026-X4F8K2QM",
"event_id": "a1b2c3d4-…",
"email": "leo@example.com",
"total_cents": 4500,
"currency": "eur"
}
}Gérer les endpoints
Gérables soit depuis ton dashboard (Paramètres → API & Webhooks), soit via l'API avec le scope webhooks:manage.
/v1/webhook_endpointsscope: webhooks:manage/v1/webhook_endpointsscope: webhooks:manage/v1/webhook_endpoints/{id}scope: webhooks:managecurl -X POST https://studevent-app.com/api/v1/webhook_endpoints \
-H "Authorization: Bearer $STUDEVENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://mon-bde.fr/api/studevent-webhook",
"enabled_events": ["order.paid", "ticket.scanned", "refund.created"],
"description": "Sync vers notre intranet"
}'⚠️ Le signing_secret n'est visible qu'une seule fois à la création.
Exemple : afficher tes events sur ton site
Quelques lignes côté serveur sur ton site BDE :
export const revalidate = 60;
export default async function EventsPage() {
const res = await fetch("https://studevent-app.com/api/v1/events?limit=20", {
headers: { Authorization: `Bearer ${process.env.STUDEVENT_KEY}` },
next: { revalidate: 60 },
});
const { data: events } = await res.json();
return (
<ul>
{events.map((e) => (
<li key={e.id}>
<a href={`/events/${e.slug}`}>{e.name}</a>
<span>{new Date(e.starts_at).toLocaleDateString("fr-FR")}</span>
</li>
))}
</ul>
);
}Exemple : tunnel d'achat sur ton site
Affiche ton propre formulaire sur ton site, et appelle /v1/checkout/sessions pour rediriger vers Stripe. Le billet sera émis automatiquement et l'événement order.paid arrivera sur ton webhook.
export async function POST(req) {
const form = await req.formData();
const res = await fetch("https://studevent-app.com/api/v1/checkout/sessions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.STUDEVENT_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
event_id: form.get("event_id"),
ticket_type_id: form.get("ticket_type_id"),
email: form.get("email"),
first_name: form.get("first_name"),
last_name: form.get("last_name"),
}),
});
if (!res.ok) {
const err = await res.json();
return Response.json(err, { status: res.status });
}
const { url } = await res.json();
return Response.redirect(url, 303);
}Pour les IA — MCP server
StudEvent fournit un serveur MCP officiel (@studevent/mcp) qui expose tous les endpoints v1 comme tools utilisables directement depuis Claude Desktop, Cursor, Windsurf, Codex, ou tout client MCP compatible. Tu peux par exemple demander à Claude « liste mes events publiés », « crée un checkout pour Léo sur le gala », ou « combien de billets scannés ce soir ? ».
Configuration Claude Desktop
Édite ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\Claude\claude_desktop_config.json (Windows) :
{
"mcpServers": {
"studevent": {
"command": "npx",
"args": ["-y", "@studevent/mcp"],
"env": { "STUDEVENT_API_KEY": "sk_live_XXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}Configuration Cursor
Édite ~/.cursor/mcp.json (même format que Claude Desktop). Cursor redémarrera le serveur MCP automatiquement.
Configuration Windsurf
Édite ~/.codeium/windsurf/mcp_config.json (même format). Active la fonction MCP dans les paramètres Cascade.
Tools disponibles
| Champ | Type | Description |
|---|---|---|
list_events | events:read | Liste les events publiés. |
get_event | events:read | Détail event + ticket_types. |
create_checkout_session | checkout:write | Crée une commande + URL Stripe. |
get_order | orders:read | Récupère une commande par ref. |
get_ticket | tickets:read | Récupère un billet par ref. |
scan_ticket | tickets:write | Valide un billet à l’entrée. |
list_webhook_endpoints | webhooks:manage | Liste les endpoints webhooks. |
create_webhook_endpoint | webhooks:manage | Crée un endpoint. |
delete_webhook_endpoint | webhooks:manage | Supprime un endpoint. |
Le serveur MCP utilise ta clé API standard — les scopes de la clé limitent ce que l'IA pourra faire. Crée une clé dédiée « Claude Desktop » avec les scopes strictement nécessaires.
llms.txt — contexte pour LLM
StudEvent expose deux fichiers au standard llms.txt pour donner du contexte aux LLM sans navigation web :
# Colle la doc dans un prompt
curl https://studevent-app.com/llms-full.txt | pbcopy
# Ou donne juste l'URL à ton IA — la plupart savent fetcher
echo "Voici la doc StudEvent: https://studevent-app.com/llms-full.txt"OpenAPI spec
La spec OpenAPI 3.1 est servie à /api/v1/openapi.json (CORS ouvert). Utilise-la pour :
- Codex / Cursor / Copilot — partage l'URL pour qu'ils comprennent les types et endpoints.
- Postman / Insomnia / Hoppscotch — Import → URL → tous les endpoints sont prêts à tester.
- Code-gen —
openapi-typescript,hey-api,openapi-generator, etc. pour générer un client typé.
# Génère un client TS typé
npx openapi-typescript https://studevent-app.com/api/v1/openapi.json \
-o ./src/lib/studevent.d.tsChangelog
| Champ | Type | Description |
|---|---|---|
2026-05-23 | v1.0 | Sortie de l’API publique : events, checkout, orders, tickets, scan, webhooks. |
Prêt à intégrer ?
Crée ta première clé depuis Paramètres → API & Webhooks. Toute question : dev@studevent-app.com.