Aller au contenu
API HILLS v1 Accès anticipé

Guides

Erreurs

Le format des erreurs, tous les statuts et codes renvoyés par l’API, les erreurs à retenter, et un gestionnaire d’erreurs Node prêt à copier.

Mis à jour le

Quand une requête échoue, l’API renvoie un statut 4xx ou 5xx et un corps JSON avec un code stable. Basez votre logique sur code. Le texte de error s’adresse à des personnes et peut changer.

Le format

{
  "error": "This API key doesn't have the earnings:read scope.",
  "code": "insufficient_scope",
  "scope": "earnings:read"
}
Champ Toujours présent Signification
error Oui Ce qui s’est mal passé, en toutes lettres. Peut être journalisé ou affiché à un opérateur sans risque.
code Oui Un code stable. Voir les tableaux ci-dessous.
field Avec invalid Le paramètre ou le champ du corps en cause.
scope Avec insufficient_scope Le scope dont la clé a besoin.

Quelques erreurs ajoutent leurs propres champs. Par exemple, 409 upload_incomplete liste les parties missing et wrong_size.

Erreurs possibles sur tous les endpoints

Statut code Signification Retenter ?
400 invalid Un paramètre est incorrect. field l’indique. Non. Corrigez la requête.
401 unauthenticated Aucun en-tête Authorization: Bearer. Non
401 invalid_key La clé n’existe pas. Non
401 key_revoked La clé a été révoquée. Créez-en une nouvelle. Non
401 key_expired La clé a expiré. Créez-en une nouvelle. Non
401 test_keys_retired Une clé hm_test_, retirée le 12 octobre 2026. Utilisez une clé hm_live_. Non
403 insufficient_scope La clé n’a pas le scope requis par cet endpoint. scope l’indique. Non
403 account_inactive Votre compte n’est pas actif. Non
403 api_not_in_plan Votre offre n’inclut pas l’API. Elle est incluse dans Enterprise et Custom. Non
404 not_found Endpoint inexistant, ou ressource qui ne vous appartient pas. Non
429 rate_limited Limite par minute de cette clé dépassée. Oui, après Retry-After secondes
500 server_error Un problème est survenu de notre côté. Oui, avec un délai croissant

404 not_found couvre à la fois « n’existe pas » et « appartient à un autre compte ». L’API ne vous révèle jamais l’existence de la sortie de quelqu’un d’autre.

Erreurs propres à certains endpoints

Statut code Où Signification
409 exists POST /members/invite Un compte existe déjà avec cette adresse e-mail.
413 too_large POST /ddex/validate Trop volumineux pour un test. Livrez-le avec POST /ddex.
413 too_large POST /ddex Plus de 20 Go (corps brut) ou de 512 Mo (multipart). Utilisez un envoi direct.
429 busy POST /ddex/validate Trop de tests simultanés. Réessayez dans un instant.
409 upload_incomplete POST /ddex/uploads/{id}/commit Parties manquantes ou de mauvaise taille. Envoyez-les, puis finalisez à nouveau.
409 already_committed Envois directs Déjà finalisé. status_url pointe vers la livraison.
409 commit_in_progress POST /ddex/uploads/{id}/commit Une autre finalisation de cet envoi est en cours.
400 invalid_url POST /webhooks, PATCH /webhooks/{id} Pas une URL https publique sur le port 443.
409 too_many POST /webhooks Vous avez déjà 20 endpoints.
409 endpoint_disabled Test et nouvelle tentative de webhook L’endpoint est désactivé. Réactivez-le d’abord.

Chaque page de la référence liste les erreurs de chaque endpoint. Scopes et erreurs regroupe les erreurs communes.

Erreurs de validation

Une 400 invalid désigne le premier problème rencontré :

{
  "error": "updated_since is an ISO date or time.",
  "code": "invalid",
  "field": "updated_since"
}

Un seul champ est signalé à la fois. Corrigez-le et renvoyez la requête. Si vous construisez un formulaire au-dessus de l’API, affichez error à côté du champ désigné par field.

Les fichiers DDEX fonctionnent autrement. Un lot DDEX qui pose problème ne renvoie pas de 400. Le test renvoie 200 avec toutes les vérifications et un verdict, et une livraison renvoie 202 puis signale les problèmes sortie par sortie. Voir Livraison DDEX.

Quoi retenter

  • Retentez les 429 et les 5xx, ainsi que les erreurs réseau comme les délais dépassés et les connexions réinitialisées.
  • Ne retentez pas les autres 4xx. La même requête obtiendra la même réponse. Corrigez d’abord la requête, la clé ou ses scopes.

Pour une 429, attendez le nombre de secondes indiqué dans Retry-After. Pour une 5xx, attendez plus longtemps après chaque essai (1 s, 2 s, 4 s…) et abandonnez au bout de quelques tentatives. Voir Limites de débit.

Les lectures peuvent être retentées sans risque. Réfléchissez avant de retenter une écriture : un POST /ddex relancé après une réponse perdue peut mettre le lot deux fois en file d’attente. Vérifiez d’abord sa présence avec GET /ddex.

Un gestionnaire d’erreurs Node

export class HillsError extends Error {
  constructor(status, body, headers) {
    super(body.error ?? `HTTP ${status}`);
    this.status = status;
    this.code = body.code;
    this.field = body.field;
    this.scope = body.scope;
    this.retryAfter = Number(headers.get("Retry-After")) || null;
  }
}

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

export async function hills(path, init = {}, tries = 4) {
  for (let i = 1; ; i++) {
    const res = await fetch("https://api.hillsmusic.com/v1" + path, {
      ...init,
      headers: { ...init.headers, Authorization: `Bearer ${process.env.HILLS_API_KEY}` },
    });
    const body = await res.json().catch(() => ({}));
    if (res.ok) return body;
    const err = new HillsError(res.status, body, res.headers);
    const retryable = res.status === 429 || res.status >= 500;
    if (!retryable || i >= tries) throw err;
    await sleep(err.retryAfter ? err.retryAfter * 1000 : 1000 * 2 ** (i - 1));
  }
}

try {
  await hills("/earnings");
} catch (err) {
  if (err.code === "insufficient_scope") console.error(`Add ${err.scope} to this key.`);
  else if (err.code === "api_not_in_plan") console.error("The plan doesn't include the API.");
  else throw err;
}

Avec curl, ajoutez -w '%{http_code}' pour voir le statut, ou -i pour voir les en-têtes :

curl -i "https://api.hillsmusic.com/v1/releases/999999" \
  -H "Authorization: Bearer $HILLS_API_KEY"
# HTTP/2 404
# {"error":"…","code":"not_found"}

Prêt à vous intégrer ?

Demandez l’accès à l’API : nous vous répondons sous 1–3 business days.