Développeurs
Documentation de l'API du Bot
Une petite API en lecture seule pour que les propriétaires de serveur affichent les données de leur propre serveur Discord sur leur site, dans leurs outils et dans des widgets.
Authentification
Crée un jeton sur la page API du Bot de ton tableau de bord et envoie-le dans l'en-tête Authorization : Authorization: Bearer <token>. Un jeton appartient à un serveur et ne lit que ce serveur. Il n'est affiché qu'une fois ; DayZ Hub ne garde que son empreinte.
curl -H "Authorization: Bearer dhba_..." \ https://dayzhub.net/api/v1/bot/guilds/<guildId>
URL de base: https://dayzhub.net/api/v1/bot
Endpoints
| Method | Path | Scope |
|---|---|---|
GET | /me | — |
GET | /guilds/{guildId} | guild:read |
GET | /guilds/{guildId}/features | guild:read |
GET | /guilds/{guildId}/giveaways | giveaways:read |
GET | /guilds/{guildId}/giveaways/{id} | giveaways:read |
GET | /guilds/{guildId}/tickets/summary | tickets:read |
GET | /guilds/{guildId}/leaderboard/levels | leveling:read |
GET | /guilds/{guildId}/shop/products | shop:read |
GET | /guilds/{guildId}/suggestions/summary | suggestions:read |
GET | /guilds/{guildId}/server-status | server-status:read |
Chaque réponse est du JSON dans la même enveloppe. Les listes sont paginées avec limit (1 à 100) et le curseur de page.nextCursor.
{ "ok": true, "data": [ ... ], "page": { "limit": 25, "hasMore": true, "nextCursor": "eyJpZCI6Ij..." } }
Scopes
Chaque jeton ne détient que les scopes que tu lui as donnés. Tous sont en lecture seule ; rien ne peut être modifié via cette API.
guild:read | État du forfait et liste des fonctionnalités |
giveaways:read | Concours (en cours et terminés) avec le nombre de participations |
tickets:read | Nombre de tickets par statut et catégorie (sans contenu des tickets) |
leveling:read | Classement des niveaux (les membres opposés au traitement sont anonymes) |
shop:read | Produits publics de la boutique de dons |
suggestions:read | Nombre de suggestions par statut |
server-status:read | État public du serveur de jeu (uniquement s'il est listé publiquement) |
Confidentialité des membres
Les membres n'apparaissent que là où la fonctionnalité les montre déjà publiquement, sous forme d'identifiant Discord. Un membre opposé au traitement de ses données est toujours montré comme anonyme, comme ci-dessous. Noms, messages, tickets et réponses de formulaires ne font jamais partie de l'API.
{ "id": null, "anonymous": true }
Limites
Les limites suivent le forfait du serveur. Premium 1 : 2 jetons actifs, 60 requêtes par minute par jeton. Premium 2 : 5 jetons, 120 par minute. Premium 3 : 10 jetons, 300 par minute. Un essai gratuit ou un serveur sponsorisé compte comme Premium 1. Chaque adresse IP peut faire 300 requêtes par minute. Au-delà tu reçois 429 avec l'en-tête Retry-After. Un forfait qui baisse ne révoque aucun jeton : ceux que tu as continuent de fonctionner, seuls les nouveaux sont bloqués jusqu'à ce que tu repasses sous la limite. Le serveur doit avoir un forfait payant ou un essai actif.
Cache
Les réponses portent un ETag et un court cache privé. Envoie If-None-Match pour obtenir 304 quand rien n'a changé. Interroger toutes les 30 à 60 secondes suffit largement.
Navigateurs et CORS
Appelle l'API depuis ton serveur. CORS est désactivé par défaut. Si une page web doit l'appeler depuis le navigateur d'un visiteur, définis un site autorisé sur le jeton ; les requêtes de toute autre origine sont refusées. Tout ce qui est dans une page web est visible des visiteurs.
Ton jeton, ton forfait et tes limites
GET /me ne vérifie pas le forfait. En plus du jeton lui-même, il renvoie plan (premium1, premium2, premium3 ou none), limits (tokens et perMinute de ce forfait) et tokensUsed (jetons actifs du serveur). rateLimitPerMin est le débit dont ce jeton dispose en ce moment.
{ "ok": true, "data": { "guildId": "123456789012345678", "name": "Website", "prefix": "dhba_aB3dE", "scopes": ["guild:read"],
"allowedOrigin": null, "rateLimitPerMin": 120, "createdAt": "2026-10-01T12:00:00.000Z",
"plan": "premium2", "limits": { "tokens": 5, "perMinute": 120 }, "tokensUsed": 2 } }
Identifiants de requête
Chaque réponse porte l'en-tête X-Request-Id. Si tu envoies ton propre X-Request-Id (jusqu'à 64 lettres, chiffres et . _ : -), il est conservé, sinon il est généré. Les erreurs le répètent sous requestId. Indique-le quand tu contactes le support.
X-Request-Id: 3f2b8c1e-5a7d-4e0b-9c64-1d2e3f4a5b6c
{ "ok": false, "error": "rate_limited", "code": "rate_limited", "message": "Too many requests", "requestId": "3f2b8c1e-5a7d-4e0b-9c64-1d2e3f4a5b6c" }
Erreurs
Les erreurs sont du JSON avec ok: false, un code stable dans code (error contient la même valeur), un court message et le requestId. Décide d'après le code, jamais d'après le texte du message.
400 bad_request / bad_cursor | Un paramètre n'est pas valide (limit, cursor, status ou id). |
401 unauthorized / invalid_token | Jeton manquant, mal formé, inconnu ou révoqué. |
403 guild_mismatch | La guilde du chemin n'est pas celle du jeton. |
403 missing_scope | Le jeton n'a pas le scope requis par cet endpoint. |
403 origin_not_allowed | L'en-tête Origin ne correspond pas au site autorisé du jeton. |
403 plan_required | Le serveur n'a ni forfait payant ni essai actif. |
403 feature_not_in_plan | La fonctionnalité ne fait pas partie du forfait du serveur. |
404 not_found / shop_not_enabled | Rien ici (ou la boutique n'est pas activée). |
405 method_not_allowed | Seul GET est disponible ; l'API est en lecture seule. |
429 rate_limited | Trop de requêtes. Attends le nombre de secondes de Retry-After. |
503 unavailable | Temporairement indisponible. Réessaie plus tard. |