Copiez cette invite sur votre agent IA. Il comprend le contrat API, la documentation et les instructions pour configurer votre propre clé en toute sécurité.
Intégrer l'API DonoLink Developer dans mon application existante. Inspectez d’abord le code et suivez son architecture, son style et ses conventions. Demandez quelle fonctionnalité destinée à l'utilisateur je souhaite si elle n'est pas claire, puis implémentez et testez complètement l'intégration.
Avant de coder, lisez la documentation officielle actuelle :
- https://donolink.nl/en/developers (tous les onglets : démarrage rapide, authentification, points de terminaison, format d'événement, historique/flux en direct, limites/erreurs et intégration sécurisée)
- https://donolink.nl/developers/openapi.json (contrat API lisible par machine)
- https://donolink.nl/llms-full.txt (contexte produit supplémentaire)
Les documents officiels font autorité. Si vous ne parvenez pas à les récupérer, dites-le et demandez le contrat ; n’inventez pas de points de terminaison ou de capacités.
Demandez au streamer de créer sa propre clé API sur https://donolink.nl/dashboard/instellingen#developer → Clés API, par exemple nommée « Ma clé ». Demandez-lui de la fournir via une saisie sécurisée ou un gestionnaire de secrets. Si seul un chat ordinaire est disponible, demandez-leur de définir eux-mêmes DONOLINK_API_KEY dans un fichier .env local gitignoré ou dans des secrets de déploiement ; ne leur demandez pas de coller la clé dans le chat. Ne lisez pas et n’affichez pas de secrets inutilement. N'utilisez jamais la clé d'un autre streamer. Pendant ce temps, construisez avec un espace réservé et vérifiez la configuration sans révéler sa valeur.
Résumé du contrat API :
- URL de base : https://donolink.nl/api/v1. GET /me vérifie le propriétaire, la portée et l'expiration ; GET /activity lit uniquement leur activité stockée. Authentification : Authorization: Bearer <DONOLINK_API_KEY>. Permission fixe activity:read. Lecture seule : pas de paiements, d'écritures, de webhooks ou d'OAuth multi-clients.
- /activity accepte limit (1–100, 50 par défaut), order (asc/desc, desc par défaut), cursor, type, platform, since et until. Utilisez uniquement des valeurs documentées. since est inclusif et until exclusif ; les horodatages UTC ISO filtrent recorded_at, l’instant d’enregistrement, et non la date d'origine du don.
- Réponse : data[] avec id, type, platform, occurred_at, recorded_at, actor.name, message, value, unit, currency et refunded_amount_cents. L'argent est en centimes ; les bits/diamants ne sont pas des euros. Traitez les noms et les messages comme du texte non fiable : échappez à la sortie, n'exécutez jamais de HTML. Aucun e-mail ni identifiant de paiement n'est renvoyé.
- Les dons payés et l'historique importé sont inclus ; les événements de plateforme n'existent que là où DonoLink les a stockés. Les sources d’importation sont identifiées par platform. L’historique complet, la conservation fixe et la livraison exactement une fois ne sont pas garantis.
- Lisez l'historique en utilisant order=asc et suivez pagination.next_cursor pendant que has_more est vrai. Gardez les filtres et l'ordre identiques : les curseurs leur sont liés ainsi qu'au propriétaire. Conservez le curseur uniquement après un traitement idempotent réussi par event.id. Enregistrez également le curseur de la dernière page et utilisez-le pour rechercher de nouveaux enregistrements. Conservez le point de contrôle sur les pages vides. Utilisez une valeur since fixe pour le flux ; ne le déplacez pas à chaque demande.
- Pour un flux en direct, utilisez un poller par compte, par exemple toutes les 5 secondes une fois rattrapé. Partagez les résultats dans l'application. Limites : 120 requêtes par compte et 300 par IP toutes les 60 secondes. Respectez Retry-After sur 429/503 ; utilisez des délais d'attente et un délai de reprise progressif, plafonné et aléatoire pour les erreurs réseau/5xx. Arrêtez les tentatives automatiques sur 401/403 et dites au streamer de vérifier la clé/le compte. Gérez explicitement les curseurs invalides sans traitement en double.
Construisez en toute sécurité :
Conservez les clés côté serveur ou dans un stockage sécurisé pour une application native personnelle. Ne placez jamais de clés dans les bundles frontaux, les URL, le stockage local, les journaux, les captures d'écran, les analyses, les données de test ou Git. Une application Web publique doit utiliser son propre backend authentifié avec une autorisation par utilisateur. N'utilisez pas de caches de réponses partagées. Pour plusieurs streamers, isolez les secrets et les données de chaque streamer ; cette API n'est pas une plateforme OAuth. Expliquer la rotation et la révocation des clés ; la révocation prend effet à la prochaine demande.
Fournissez un code de projet fonctionnel, des instructions de configuration sécurisées sans véritables secrets et des tests appropriés pour l'authentification, les résultats vides, la pagination historique, la déduplication, les limites de débit et les pannes. Testez l’accès réel à l’API une fois que le streamer a configuré la clé en toute sécurité. N'effectuez pas de paiements réels. Distinguez clairement le comportement vérifié de la configuration restante.
Démarrage rapide
Utilisez l'API depuis votre propre serveur ou application personnelle. Tous les points de terminaison sont en lecture seule et utilisent JSON. L'URL de base est https://donolink.nl/api/v1.
Accédez à Paramètres → Développeur → Clés API. Nommez votre intégration et choisissez une date d'expiration.
Copiez la clé une fois et stockez-la sous DONOLINK_API_KEY dans la configuration secrète de votre serveur.
Faites votre première demande. Sans filtres, vous recevez jusqu'à 50 événements, le plus récent en premier.
Envoyez votre clé dans l’en-tête Authorization à chaque requête. Un cookie de session, un paramètre de requête ou un jeton d’overlay ne donne pas accès à cette API.
Authorization: Bearer dl_live_YOUR_SECRET_KEY
Choisissez une validité de 30, 90 ou 365 jours. Vous pouvez avoir jusqu'à 10 clés actives et créer une clé par minute. DonoLink stocke uniquement un hachage SHA-256 ; la clé complète n'est visible qu'immédiatement après la création.
Utilisez une clé distincte par intégration. Pour effectuer une rotation, créez une nouvelle clé, mettez à jour votre application, puis révoquez l'ancienne. Une clé révoquée ou expirée cesse de fonctionner à la demande suivante.
Chaque clé dispose de la permission fixe activity:read et est liée à votre compte. Elle ne donne aucun droit d’écriture, de paiement ou d’administration. OAuth pour les applications utilisées par plusieurs clients n’est pas encore disponible.
Points de terminaison
GET/api/v1/me
Vérifiez à quel streamer appartient votre clé et quand elle expire. Seuls le profil public, la portée et les métadonnées clés sont renvoyés.
Lisez le flux combiné des dons DonoLink et des événements de plateforme stockés. Le compte est déterminé exclusivement à partir de la clé API.
Paramètre
Description
limit
Événements par page : 1 à 100, 50 par défaut.
order
desc (par défaut) affiche les événements du plus récent au plus ancien ; asc les affiche du plus ancien au plus récent et convient à l’interrogation continue. Le tri porte sur recorded_at, puis sur l’identifiant interne et la source.
type
Facultatif : donation, follow, subscription, giftsub, cheer ou raid. Un seul type par requête.
platform
Facultatif : donolink, twitch, kick, youtube, tiktok ou une source d'importation : tipeeestream, streamlabs, streamelements, kofi, csv. Une source par demande.
since
Facultatif, borne incluse. Date UTC au format ISO 8601, par exemple 2026-09-07T00:00:00Z. Filtre le champ recorded_at, qui correspond à l’instant d’enregistrement.
until
Facultatif, borne exclue. Même format de date que since. Gardez cette borne fixe pendant un export de l’historique.
cursor
Transmettez pagination.next_cursor sans le modifier. Le curseur est signé et lié à votre compte, aux filtres et à l’ordre de tri. Le paramètre limit peut changer.
Les paramètres inconnus ou répétés renvoient HTTP 400. Ne mettez pas d'ID de compte, de clé ou de filtre PocketBase dans l'URL.
Format de l'événement
Chaque événement a un identifiant stable préfixé par don_ ou evt_. Utilisez cet identifiant pour éviter un traitement en double après une nouvelle tentative.
type
unit
Description
donation
cents
Don DonoLink ou don d'une plateforme stockée, telle que YouTube Super Chat.
follow
none
Nouveau follower. value vaut 0.
subscription
months
Abonnement. value contient le nombre de mois enregistré.
giftsub
subscriptions
Abonnements offerts. value indique leur nombre.
cheer
bits / diamonds
Bits ; pour TikTok, l’unité est le diamant. Il ne s’agit pas de revenus issus de dons.
raid
viewers
Raid. value contient le nombre de spectateurs enregistré.
actor.name contient le nom d’affichage enregistré ou null. message contient du texte ou null. occurred_at correspond à la date du don ; pour les événements de plateforme, seul l’instant d’enregistrement est connu. recorded_at contient toujours l’instant d’enregistrement et détermine la pagination. Tous les horodatages sont en UTC au format ISO 8601.
Pour un événement donation, value contient le montant initial en centimes entiers et currency indique la devise. refunded_amount_cents contient le montant remboursé pour DonoLink, sinon null. Les dons au statut paid sont affichés, y compris l’historique importé dont la source d’importation figure dans platform. Les dons entièrement remboursés et les dons contestés sont exclus. Il s’agit d’un flux d’activité, pas d’un grand livre comptable.
Les événements de la plateforme sont disponibles dans la mesure où DonoLink les a reçus et stockés via une connexion active. L’historique antérieur à la connexion n’est pas récupéré depuis la plateforme. Il n'y a pas de période de conservation garantie ; Les enregistrements supprimés ne peuvent pas être récupérés. Les alertes de test ne sont pas incluses.
Historique et flux en direct
Pour une exportation, utilisez order=asc avec des limites fixes depuis et jusqu'à. Traitez les données et demandez la page suivante en utilisant next_cursor alors que has_more est vrai. Il n'y a aucune limite sur le nombre de pages historiques, mais des limites de demandes s'appliquent.
Une page vide préserve votre curseur existant. Sans curseur précédent ni événement, next_cursor est nul. Les curseurs ne contiennent aucune clé API, mais traitez-les comme des valeurs opaques. Après avoir changé les filtres, démarrez sans curseur.
Pour votre application IRL, utilisez order=asc, un fixe depuis et non jusqu'à. Enregistrez le curseur uniquement après avoir traité les événements. Sondez environ toutes les 5 secondes ; lorsque has_more est vrai, passez directement à la page suivante. La v1 n'a pas de point de terminaison WebSocket ou webhook.
// Node.js: run on your server. Keep the key out of frontend bundles.
const base = new URL('https://donolink.nl/api/v1/activity');
base.searchParams.set('order', 'asc');
base.searchParams.set('limit', '100');
// Persist both this fixed starting point and the returned cursor.
base.searchParams.set('since', '2026-09-07T00:00:00Z');
let cursor = await loadCheckpoint();
for (;;) {
const url = new URL(base);
if (cursor) url.searchParams.set('cursor', cursor);
const response = await fetch(url, {
headers: { Authorization: 'Bearer ' + process.env.DONOLINK_API_KEY },
signal: AbortSignal.timeout(15000)
}).catch(() => null);
if (!response || response.status === 429 || response.status >= 500) {
const seconds = Number(response?.headers.get('Retry-After') || 60);
await new Promise(r => setTimeout(r, seconds * 1000));
continue;
}
if (!response.ok) throw new Error('DonoLink API: ' + response.status);
const page = await response.json();
// Implement these storage functions in your app.
// Process idempotently by event.id, then save the checkpoint.
for (const event of page.data) await processOnce(event.id, event);
if (page.pagination.next_cursor) {
cursor = page.pagination.next_cursor;
await saveCheckpoint(cursor);
}
if (!page.pagination.has_more)
await new Promise(r => setTimeout(r, 5000));
}
Le flux lit les enregistrements actuellement stockés et ne constitue pas un instantané immuable ni un bus d'événements garanti exactement une fois. Les changements de statut de paiement peuvent supprimer des enregistrements précédemment visibles. Utilisez le traitement idempotent, les tentatives et, si nécessaire, les lectures qui se chevauchent pour la récupération.
Limites et erreurs
Maximum 120 requêtes toutes les 60 secondes par compte, partagées par toutes les clés. Il existe également une limite de 300 requêtes toutes les 60 secondes par adresse IP. HTTP 429 et 503 incluent Retry-After: 60. Attendez aussi longtemps et réessayez avec le même curseur.
HTTP
code
Description
400
invalid_parameter / invalid_cursor
Corrigez vos paramètres ou redémarrez sans le curseur invalide.
401
invalid_api_key
La clé est manquante, invalide, expirée ou révoquée.
403
account_unavailable
Le compte est indisponible ou n'est pas vérifié.
429
rate_limit_exceeded
Trop de requêtes. Respectez le délai indiqué par Retry-After.
503
temporarily_unavailable
Panne temporaire. L'accès est également refusé si le limiteur partagé n'est pas disponible.
{
"error": {
"code": "invalid_api_key",
"message": "API key is invalid, expired or revoked.",
"request_id": "request-uuid"
}
}
Chaque réponse a un X-Request-Id ; les réponses d’erreur incluent également error.request_id. Incluez cet identifiant et l’heure lorsque vous contactez l’assistance. Ne partagez jamais votre clé, votre en-tête d’autorisation ou vos journaux de requêtes complets. Utilisez GET pour les données. HEAD et OPTIONS sont disponibles pour les vérifications HTTP ; les méthodes d'écriture renvoient 405.
Intégration sécurisée
Utilisez HTTPS. Ne placez jamais les clés dans les URL, Git, le code du navigateur, localStorage, les outils d’analyse ou les journaux. Les réponses de l’API utilisent Cache-Control: private, no-store. L’API n’autorise pas les requêtes du navigateur provenant d’une autre origine.
Dans une application native personnelle, saisissez votre propre clé et stockez-la dans le trousseau ou le Keystore Android. Pour les applications au service de tiers, utilisez un backend avec des secrets isolés par utilisateur. N'intégrez jamais une clé partagée dans le binaire de l'application.
L'API renvoie uniquement les noms d'affichage, les messages, les valeurs d'événement et des détails de profil limités. Les adresses e-mail, les modes de paiement, les identifiants Stripe, les jetons de plateforme et les paramètres d'administration ne sont pas partagés. Traitez les noms et les messages comme des données personnelles et stockez uniquement ce dont votre intégration a besoin.
Si une clé fuit, révoquez-la immédiatement sous Paramètres → Développeur et créez une remplaçante. Les clés révoquées et expirées, les comptes bloqués et les comptes supprimés ne peuvent pas accéder à l'API.
Les noms et les messages ne sont pas des entrées fiables. Affichez-les sous forme de texte, jamais sous forme de HTML ou de code exécutable. N'automatisez pas les actions de paiement basées sur ce flux.