Documentation API

Une API REST pour lire votre catalogue, suivre vos statistiques et réagir aux événements de votre compte. Toutes les réponses sont en JSON, encodées en UTF-8.

Télécharger la spécification

Authentification

Chaque requête doit porter un jeton personnel dans l'en-tête Authorization. Les jetons se créent depuis l'espace développeur de votre compte.

curl https://agafy.fr/api/v1/me \
  -H "Authorization: Bearer VOTRE_JETON" \
  -H "Accept: application/json"

Un jeton perdu ne peut pas être retrouvé : révoquez-le et créez-en un nouveau.

Portées

Une portée limite ce qu'un jeton peut faire. Accordez uniquement le nécessaire : un jeton compromis n'expose alors qu'une partie de vos données.

PortéeAccès accordé
read:profileLire le profil
read:tracksLire le catalogue
read:analyticsLire les statistiques
write:tracksModifier les titres
read:fansLire les fans et segments

Limites

60 requêtes par minute et par jeton. Au-delà, l'API répond 429 avec un en-tête Retry-After indiquant le délai en secondes. Les listes sont paginées (per_page, 50 maximum).

Endpoints

GET /v1/me read:profile
GET /v1/tracks read:tracks
GET /v1/tracks/{id} read:tracks
PATCH /v1/tracks/{id} write:tracks
GET /v1/tracks/{id}/stream-url read:tracks
GET /v1/search?q= read:tracks
GET /v1/recommendations read:tracks
GET /v1/artists/{id} read:tracks
GET /v1/artists/{id}/tracks read:tracks
GET /v1/analytics read:analytics
GET /v1/fans read:fans

Exemple de réponse

{
  "data": [
    {
      "id": 412,
      "title": "Horizon",
      "duration": 214,
      "plays": 18430,
      "artist": { "id": 27, "name": "Nova" }
    }
  ],
  "current_page": 1,
  "last_page": 9,
  "total": 172
}

Erreurs

CodeSignification
401Jeton absent, expiré ou révoqué
403Portée insuffisante ou ressource d'un autre compte
404Ressource introuvable ou non publique
422Validation échouée — détail dans errors
429Limite de débit atteinte

Webhooks

Configurez une URL dans l'espace développeur pour recevoir les événements en POST. Répondez avec un code 2xx : sinon la livraison est retentée cinq fois selon un délai croissant (1, 4, 16 puis 64 minutes).

ÉvénementDéclencheur
track.publishedTitre publié
presave.createdPré-enregistrement de fan
tip.receivedPourboire reçu
subscription.createdAbonnement artiste créé
test.pingTest manuel
{
  "event": "track.published",
  "created_at": "2026-07-20T10:14:02+00:00",
  "data": { "track_id": 412, "title": "Horizon", "artist_id": 27 }
}

Vérifier la signature

Chaque requête porte l'en-tête X-Melodix-Signature. Comparez-la au HMAC-SHA256 du corps brut calculé avec le secret de votre endpoint, en utilisant une comparaison à temps constant.

// PHP
$signature = hash_hmac('sha256', file_get_contents('php://input'), $secret);
$header = str_replace('sha256=', '', $_SERVER['HTTP_X_MELODIX_SIGNATURE'] ?? '');

if (! hash_equals($signature, $header)) {
    http_response_code(403);
    exit;
}
// Node.js
const crypto = require('crypto');
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const received = (req.headers['x-melodix-signature'] || '').replace('sha256=', '');

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
  return res.sendStatus(403);
}