Référence de l'API
Tous les points de terminaison REST de l'API Woupi v1, avec leur authentification, leurs portées, leurs paramètres et des exemples.
URL de base
Tous les points de terminaison REST se trouvent sous https://api.woupi.buzz/v1. Les points de terminaison OAuth (/oauth2/token, /oauth2/device, /oauth2/validate, /oauth2/revoke) sont décrits dans Authentification. Les requêtes et les réponses utilisent JSON; envoyez Content-Type: application/json avec les corps de POST et de PATCH.
En-têtes obligatoires
| En-tête | Valeur |
|---|---|
Authorization | Bearer <access_token> |
Client-Id | L'identifiant client de l'application à laquelle appartient le jeton. Absent ou différent de l'application du jeton : 401. |
curl -s https://api.woupi.buzz/v1/users \
-H "Authorization: Bearer wpa_Jx8cQm2VtN5rLw0bZy7Hd4Ks1Pf9Ge6Ua3Oi2Te5Yq" \
-H "Client-Id: k3v9x2m7q1w8e4r6t0y5u2i9o3p7a1"Types de jetons
Chaque point de terminaison ci-dessous indique le type de jeton d'accès qu'il accepte et les portées qu'il exige.
| Type | Signification |
|---|---|
| app | Jeton d'application obtenu avec l'octroi client_credentials (applications confidentielles). Agit au nom de l'application elle-même, sans utilisateur. |
| user | Jeton d'utilisateur obtenu avec le flux par code d'autorisation, le flux par code d'appareil ou le générateur de jetons du portail. Agit au nom de l'utilisateur qui l'a accordé; un jeton d'application reçoit 401 missing user token. |
| any | Un jeton d'application ou un jeton d'utilisateur. |
Un jeton d'utilisateur à qui il manque une portée requise reçoit 403 Missing scope: <scope>. Les portées sont listées dans Portées; les erreurs et les limites de débit, dans Limites de débit et erreurs.
Conventions
- Les identifiants sont des chaînes, même lorsqu'ils ressemblent à des nombres :
"1042".broadcaster_idetuser_idsont des identifiants d'utilisateurs Woupi. - Les dates sont au format ISO 8601 en UTC, par exemple
2026-09-24T18:30:05.000Z. - Les réponses de liste ont la forme
{ "data": [...], "pagination": { "cursor": "..." } }. - Les erreurs ont la forme
{ "error": "Unauthorized", "status": 401, "message": "..." }.
Pagination
Les points de terminaison paginés acceptent first (taille de la page, de 1 à 100, 20 par défaut) et after (un curseur). Passez le pagination.cursor d'une réponse dans after pour obtenir la page suivante; lorsque pagination n'a pas de cursor, il n'y a plus de résultats.
curl -s "https://api.woupi.buzz/v1/channels/followers?broadcaster_id=1042&first=50&after=MTI4" \
-H "Authorization: Bearer USER_ACCESS_TOKEN" \
-H "Client-Id: YOUR_CLIENT_ID"Points de terminaison
OAuth
Échange un code d'autorisation, un jeton d'actualisation, un code d'appareil ou les identifiants de l'application contre un jeton d'accès. Le corps est encodé en formulaire ou en JSON. L'actualisation remplace l'ancien jeton; client_credentials ne renvoie pas de jeton d'actualisation.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
grant_type | corps | string | Oui | authorization_code, refresh_token, client_credentials ou urn:ietf:params:oauth:grant-type:device_code. |
client_id | corps | string | Oui | Identifiant client de votre application (ou authentification HTTP Basic). |
client_secret | corps | string | Non | Secret client; obligatoire pour les applications confidentielles, absent pour les applications publiques. |
code | corps | string | Non | Code d'autorisation (authorization_code). |
redirect_uri | corps | string | Non | URL de redirection identique à celle de la demande d'autorisation (authorization_code). |
code_verifier | corps | string | Non | Vérificateur PKCE (S256); obligatoire si la demande contenait un code_challenge. |
refresh_token | corps | string | Non | Jeton d'actualisation (refresh_token). |
device_code | corps | string | Non | Code d'appareil reçu de /oauth2/device. |
Exemple de réponse
{
"access_token": "wpa_Qm9vT2x3c1Zkd2xHb1ZrN1d5b2Y3cF9YdUtwNFk",
"refresh_token": "wpr_V2Z4Yk1uR3N0bDdhS2pQcTlzWHZ0M2Y1aDBKbkU",
"expires_in": 14400,
"scope": "chat:read chat:write",
"token_type": "bearer"
}Démarre le flux par code d'appareil (jeux, consoles, outils sans navigateur). Affichez user_code et verification_uri, puis interrogez /oauth2/token toutes les interval secondes.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
client_id | corps | string | Oui | Identifiant client de votre application. |
scope | corps | string | Non | Portées demandées, séparées par des espaces. |
Exemple de réponse
{
"device_code": "wpd_c3R1ZmZ5RGV2aWNlQ29kZUV4YW1wbGVfMTIzNDU",
"user_code": "KJQX-7M4P",
"verification_uri": "https://woupi.buzz/activate",
"verification_uri_complete": "https://woupi.buzz/activate?code=KJQX-7M4P",
"expires_in": 1800,
"interval": 5
}Vérifie un jeton d'accès envoyé dans l'en-tête Authorization: OAuth <jeton> (ou Bearer). login et user_id valent null pour un jeton d'application. Un jeton invalide renvoie 401.
Paramètres
Aucun paramètre.
Exemple de réponse
{
"client_id": "k3v9x0q2m7w1r8t5y4u6i0o9p2a3sd",
"login": "nova",
"user_id": "42",
"scopes": [
"chat:read",
"chat:write"
],
"expires_in": 13872
}Révoque un jeton d'accès ou d'actualisation. La réponse est 200 que le jeton ait été trouvé ou non.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
client_id | corps | string | Oui | Identifiant client de l'application qui a reçu le jeton. |
token | corps | string | Oui | Jeton d'accès ou jeton d'actualisation à révoquer. |
Exemple de réponse
{}Utilisateurs
Renvoie des utilisateurs par identifiant ou par nom. Sans paramètre, un jeton d'utilisateur renvoie son propre utilisateur. email n'est inclus que pour l'utilisateur du jeton, avec la portée user:read:email.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
id | requête | string[] | Non | Identifiant d'utilisateur (répétable). |
login | requête | string[] | Non | Nom d'utilisateur (répétable). Au plus 100 valeurs id et login au total. |
Exemple de réponse
{
"data": [
{
"id": "42",
"login": "nova",
"display_name": "Nova",
"avatar_url": "https://woupi.buzz/uploads/u42/avatar-1790262000000.png",
"bio": "Speedruns et clavardage tous les soirs.",
"level": 7,
"created_at": "2026-03-02T18:25:11.000Z",
"email": "[email protected]"
}
]
}Liste paginée des chaînes suivies par l'utilisateur du jeton, avec le nombre total.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
user_id | requête | string | Oui | Identifiant de l'utilisateur du jeton. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"broadcaster_id": "57",
"broadcaster_login": "pixelpoutine",
"broadcaster_name": "PixelPoutine",
"followed_at": "2026-09-24T15:00:00.000Z"
}
],
"pagination": {
"cursor": "NTc"
},
"total": 12
}Chaînes
Renvoie les informations de diffusion des chaînes : titre, catégorie, langue, état en direct et classification de contenu. content_rating (0, 16 ou 18) est la classification effective : le minimum de la catégorie peut relever celle choisie par la chaîne.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string[] | Oui | Identifiant de chaîne (répétable, 100 au maximum). |
Exemple de réponse
{
"data": [
{
"broadcaster_id": "42",
"broadcaster_login": "nova",
"broadcaster_name": "Nova",
"title": "Any% en direct",
"category_id": "7",
"category_name": "Minecraft",
"language": "English",
"is_live": true,
"content_rating": 16,
"content_labels": [
"language",
"violence"
]
}
]
}Modifie le titre, la catégorie ou la classification de contenu de votre chaîne. Déclenche l'événement channel.update. Répond 204.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
title | corps | string | Non | Nouveau titre de diffusion (140 caractères au maximum). |
category_id | corps | string | Non | Identifiant de catégorie existant; "" ou "0" retire la catégorie. |
content_rating | corps | number | Non | Classification choisie par la chaîne : 0 (tous publics), 16 ou 18. Le GET renvoie la classification effective, que le minimum de la catégorie peut relever. |
content_labels | corps | string[] | Non | Étiquettes de contenu parmi violence, language, sexual, drugs, gambling; [] les retire. |
Exemple de réponse
204 — aucun contenu
Liste paginée des personnes qui suivent votre chaîne, avec le nombre total.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
user_id | requête | string | Non | Ne renvoie que cet utilisateur s'il suit la chaîne. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"user_id": "318",
"user_login": "maplefox",
"user_name": "MapleFox",
"followed_at": "2026-09-24T15:00:00.000Z"
}
],
"pagination": {
"cursor": "MzE4"
},
"total": 1543
}Diffusions
Liste paginée des chaînes actuellement en direct, avec le nombre de spectateurs.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
user_id | requête | string[] | Non | Identifiant de chaîne (répétable). |
user_login | requête | string[] | Non | Nom de chaîne (répétable). Au plus 100 valeurs user_id et user_login au total. |
category_id | requête | string | Non | Ne renvoie que les diffusions de cette catégorie. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"id": "1790262000000",
"user_id": "42",
"user_login": "nova",
"user_name": "Nova",
"category_id": "7",
"category_name": "Minecraft",
"type": "live",
"title": "Any% en direct",
"viewer_count": 128,
"started_at": "2026-09-24T15:00:00.000Z",
"language": "English",
"thumbnail_url": "https://woupi.buzz/uploads/live/42.jpg?v=1790262300",
"content_rating": 0,
"content_labels": []
}
],
"pagination": {}
}Renvoie l'URL du serveur d'ingestion (stream_url) et la clé de stream de votre chaîne, à saisir dans OBS ou un autre encodeur; full_url les combine pour ffmpeg. srt_url est l'URL d'ingestion SRT complète (clé incluse, à coller telle quelle comme serveur), ou null si le SRT n'est pas proposé. La clé est secrète : quiconque la possède peut diffuser sur la chaîne. Elle change lorsque le diffuseur la régénère dans son tableau de bord.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
Exemple de réponse
{
"data": [
{
"broadcaster_id": "42",
"stream_url": "rtmp://rtmp.woupi.buzz:1935/live",
"stream_key": "3f9a1c7e2b8d4f60a5c9e1b7d3f2a8c4",
"full_url": "rtmp://rtmp.woupi.buzz:1935/live/3f9a1c7e2b8d4f60a5c9e1b7d3f2a8c4",
"srt_url": "srt://rtmp.woupi.buzz:8890?streamid=publish:live/3f9a1c7e2b8d4f60a5c9e1b7d3f2a8c4"
}
]
}Catégories
Renvoie des catégories par identifiant ou par slug.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
id | requête | string[] | Non | Identifiant de catégorie (répétable). |
slug | requête | string[] | Non | Slug de catégorie (répétable). Au moins un id ou slug, 100 au total. |
Exemple de réponse
{
"data": [
{
"id": "7",
"name": "Minecraft",
"slug": "minecraft",
"box_art_url": "https://static-cdn.jtvnw.net/ttv-boxart/27471_IGDB-285x380.jpg"
}
]
}Recherche jusqu'à 20 catégories; les noms qui commencent par la recherche viennent en premier.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
query | requête | string | Oui | Texte recherché dans le nom ou le slug (1 à 100 caractères). |
Exemple de réponse
{
"data": [
{
"id": "7",
"name": "Minecraft",
"slug": "minecraft",
"box_art_url": "https://static-cdn.jtvnw.net/ttv-boxart/27471_IGDB-285x380.jpg"
}
]
}Vidéos
Renvoie des vidéos par identifiant, ou la liste paginée des rediffusions et clips d'une chaîne, du plus récent au plus ancien.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
id | requête | string[] | Non | Identifiant de vidéo ou de clip (répétable, 100 au maximum). |
user_id | requête | string | Non | Chaîne dont lister les vidéos. Fournissez id ou user_id, pas les deux. |
kind | requête | string | Non | video (rediffusions) ou clip; avec user_id seulement. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"id": "1204",
"user_id": "42",
"user_login": "nova",
"user_name": "Nova",
"kind": "video",
"title": "Any% en direct",
"duration_s": 7385,
"view_count": 311,
"created_at": "2026-09-24T15:00:00.000Z",
"url": "https://woupi.buzz/video/1204",
"thumbnail_url": "https://woupi.buzz/media-vod/42/1790262000000.jpg",
"source_video_id": null,
"content_rating": 0
}
],
"pagination": {
"cursor": "MTIwNA"
}
}Clips
Crée un clip au nom de l'utilisateur du jeton à partir d'une rediffusion. Déclenche l'événement channel.clip.create. Répond 202.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
video_id | corps | string | Oui | Identifiant de la rediffusion source (pas un clip). |
start_s | corps | integer | Oui | Début du clip, en secondes depuis le début de la vidéo. |
length | corps | integer | Oui | Durée du clip : 15, 30 ou 60 secondes. |
Exemple de réponse
{
"data": [
{
"id": "1311",
"url": "https://woupi.buzz/clip/1311"
}
]
}Clavardage
Envoie un message dans le clavardage d'une chaîne au nom de l'utilisateur du jeton. Les modes du clavardage s'appliquent : un message refusé renvoie is_sent: false et la raison dans drop_reason (chat.sys.followersOnly, chat.sys.subsOnly, chat.sys.emotesOnly, chat.sys.bannedWords, chat.sys.slowMode).
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | corps | string | Oui | Chaîne où envoyer le message. |
message | corps | string | Oui | Texte du message (1 à 300 caractères). |
Exemple de réponse
{
"data": [
{
"message_id": "1790262123456-k3f9qz",
"is_sent": true
}
]
}Renvoie les modes du clavardage d'une chaîne.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de la chaîne. |
Exemple de réponse
{
"data": [
{
"broadcaster_id": "42",
"emote_mode": false,
"follower_mode": true,
"subscriber_mode": false,
"slow_mode": true,
"slow_mode_s": 10
}
]
}Modifie les modes du clavardage de votre chaîne; les champs omis gardent leur valeur. Déclenche l'événement channel.chat_settings.update et renvoie les nouveaux réglages.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
slow_mode_s | corps | integer | Non | Délai entre deux messages d'une même personne, de 0 à 600 secondes (0 désactive). |
followers_only | corps | boolean | Non | Réserve le clavardage aux personnes qui suivent la chaîne. |
subs_only | corps | boolean | Non | Réserve le clavardage aux personnes abonnées. |
emotes_only | corps | boolean | Non | N'accepte que les émoticônes. |
banned_words | corps | string[] | Non | Remplace la liste des mots interdits (100 au maximum). |
Exemple de réponse
{
"data": [
{
"broadcaster_id": "42",
"emote_mode": false,
"follower_mode": true,
"subscriber_mode": false,
"slow_mode": true,
"slow_mode_s": 30
}
]
}Modération
Supprime un message récent du clavardage de votre chaîne. Répond 204, ou 404 si le message n'est plus dans l'historique récent.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
message_id | requête | string | Oui | Identifiant du message (message_id de l'événement channel.chat.message). |
Exemple de réponse
204 — aucun contenu
Abonnements
Liste paginée des abonnements actifs à votre chaîne, avec le nombre total.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
broadcaster_id | requête | string | Oui | Identifiant de votre chaîne; doit être l'utilisateur du jeton. |
user_id | requête | string[] | Non | Ne renvoie que ces personnes abonnées (répétable, 100 au maximum). |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"user_id": "77",
"user_login": "loonie",
"user_name": "Loonie",
"expires_at": "2026-10-24T15:00:00.000Z",
"tier": "1000"
}
],
"pagination": {
"cursor": "Nzc"
},
"total": 38
}EventSub
Crée un abonnement. Un webhook reste en vérification jusqu'à ce que votre URL renvoie le défi; un abonnement WebSocket est actif immédiatement.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
type | corps | string | Oui | Type d'événement, par exemple channel.follow. |
version | corps | string | Oui | Version du type : 1. |
condition | corps | object | Oui | Condition du type, par exemple { "broadcaster_user_id": "42" }. |
transport | corps | object | Oui | { "method": "webhook", "callback", "secret" } (jeton d'application) ou { "method": "websocket", "session_id" } (jeton utilisateur). |
Exemple de réponse
{
"data": [
{
"id": "f1c2d3e4-5b6a-4c7d-8e9f-0a1b2c3d4e5f",
"type": "channel.follow",
"version": "1",
"status": "webhook_callback_verification_pending",
"condition": {
"broadcaster_user_id": "42"
},
"transport": {
"method": "webhook",
"callback": "https://example.com/webhooks/woupi"
},
"created_at": "2026-09-24T15:00:00.000Z",
"cost": 0
}
],
"total": 1,
"total_cost": 0,
"max_total_cost": 10000
}Liste les abonnements de votre application. Les abonnements WebSocket ne sont visibles qu'avec le jeton de l'utilisateur qui les a créés.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
status | requête | string | Non | Filtre par statut, par exemple enabled. |
type | requête | string | Non | Filtre par type d'événement. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"id": "f1c2d3e4-5b6a-4c7d-8e9f-0a1b2c3d4e5f",
"type": "channel.follow",
"version": "1",
"status": "enabled",
"condition": {
"broadcaster_user_id": "42"
},
"transport": {
"method": "webhook",
"callback": "https://example.com/webhooks/woupi"
},
"created_at": "2026-09-24T15:00:00.000Z",
"cost": 0
}
],
"pagination": {},
"total": 1,
"total_cost": 0,
"max_total_cost": 10000
}Supprime un abonnement (réponse 204).
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
id | requête | string | Oui | Identifiant de l'abonnement. |
Exemple de réponse
204 — aucun contenu
Drops
Les campagnes Drops de votre application avec leurs récompenses.
Paramètres
Aucun paramètre.
Exemple de réponse
{
"data": [
{
"id": "12",
"name": "Semaine de lancement",
"description": "Regardez 30 minutes pour débloquer l'épée légendaire.",
"status": "approved",
"is_active": true,
"category_id": "7",
"category_name": "Minecraft",
"account_link_url": "https://example.com/link",
"starts_at": "2026-09-20T15:00:00.000Z",
"ends_at": "2026-10-04T15:00:00.000Z",
"rewards": [
{
"id": "34",
"name": "Épée légendaire",
"required_minutes": 30,
"image_url": "https://woupi.buzz/uploads/u42/drop-34-1790262000000.png"
}
]
}
]
}Droits Drops réclamés. Un jeton d'application voit tous ceux de votre application; un jeton utilisateur (portée drops:read) ne voit que ceux de son utilisateur.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
user_id | requête | string | Non | Filtre par personne (avec un jeton utilisateur : uniquement la vôtre). |
campaign_id | requête | string | Non | Filtre par campagne. |
fulfillment_status | requête | string | Non | CLAIMED ou FULFILLED. |
first | requête | integer | Non | Nombre d'éléments par page, de 1 à 100 (20 par défaut). |
after | requête | string | Non | Curseur pagination.cursor de la page précédente. |
Exemple de réponse
{
"data": [
{
"id": "3f1c2b9e-7d4a-4c1e-9b2a-5e6f7a8b9c0d",
"campaign_id": "12",
"reward_id": "34",
"reward_name": "Épée légendaire",
"user_id": "318",
"fulfillment_status": "CLAIMED",
"is_test": false,
"claimed_at": "2026-09-24T15:00:00.000Z",
"fulfilled_at": null
}
],
"pagination": {
"cursor": "NTc"
}
}Met à jour le statut de livraison. Le résultat regroupe les identifiants par statut : SUCCESS, NOT_FOUND ou UNAUTHORIZED.
Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
entitlement_ids | corps | string[] | Oui | Jusqu'à 100 identifiants de droits. |
fulfillment_status | corps | string | Oui | FULFILLED (livré en jeu) ou CLAIMED (annuler la livraison). |
Exemple de réponse
{
"data": [
{
"status": "SUCCESS",
"ids": [
"3f1c2b9e-7d4a-4c1e-9b2a-5e6f7a8b9c0d"
]
}
]
}