Documentation · 19 adresses

L'API, route par route

19 adresses, 24 opérations. Pour chacune : ce qu'elle lit, ce qu'elle renvoie, et les erreurs qu'il faut traiter. Tout est déplié, parce qu'on arrive ici en cherchant un nom de champ.

Base : https://wedispatch.fr/api/v1 · Les parcours d'intégration

À lire avant de commencer

Ce que l'API ne sait pas faire

6 fonctions du produit n'ont pas de route publique. Les découvrir au milieu d'un chantier coûte une demi-journée ; les lire ici en coûte deux minutes.

Créer un extrait partageable

La fonction existe, dans l'espace client. Elle n'a pas de route publique : un extrait se fabrique à la main, en écoutant, et c'est précisément ce qu'un programme ne sait pas faire à votre place.

Chercher un mot prononcé dans vos audios

Disponible dans l'espace client, pas par clé. Ce que l'API donne, c'est la position de chaque mot d'UN article donné.

Créer ou lister vos sites

Une clé PORTE un site, elle n'en gère pas. Le rattachement se fait à la création de la clé, dans l'espace client ou par l'échange de code.

Enregistrer un webhook une fois pour toutes

Il n'y a pas de réglage de webhook au niveau du compte. L'adresse se passe À CHAQUE APPEL de génération, et elle n'est pas retenue. Si vous cherchiez où la configurer, la réponse est : nulle part, et c'est voulu.

Déclarer un flux RSS à surveiller

La découverte par flux existe comme mode d'intégration, mais elle se configure dans l'espace client, pas par l'API.

Filtrer ou paginer la liste des articles

`GET /podcasts` ne lit aucun paramètre et rend les trente derniers. Pas de filtre d'état, pas de curseur, pas de date. C'est la limite la plus susceptible de vous surprendre, donc elle est écrite ici et sur la route elle-même.

Commencer

Ce qu'il faut avoir compris avant le premier appel.

Authentification

En-tête de toutes les requêtes

Une clé par site, transmise en en-tête. Aucune route n'est servie sans elle, sauf le catalogue de voix et l'échange de code, signalés comme tels.

Authorization: Bearer wd_live_xxxxxxxxxxxxxxxx

À savoir : Avec l'extension WordPress vous ne manipulerez jamais cette clé : elle s'échange de serveur à serveur. La clé en clair n'existe que pour les intégrations maison, et elle n'est jamais réaffichée après sa création.

Langue des messages d'erreur

En-tête Accept-Language

Les messages d'erreur sont rendus en français par défaut, en anglais si vous le demandez. Le CODE HTTP, lui, ne change jamais : c'est sur lui qu'il faut brancher votre logique, pas sur le texte.

Accept-Language: en

À savoir : Deux routes ne traduisent pas encore leurs messages, dont les recommandations. Traitez le code, pas la phrase.

Limites de débit

Trois routes en portent une

Dix générations par minute, quatre lots par minute, trente aperçus de voix par heure. Les quatorze autres routes n'ont pas de limite de débit. Un dépassement rend un 429.

429 { "error": "…maximum 10 générations par minute…" }

À savoir : Deux de ces trois compteurs vivent en mémoire d'instance : ce sont des garde-fous, pas des garanties contractuelles. Seule la limite de génération est comptée en base.

Les codes de refus

Ce qu'il faut savoir traiter

Dix codes couvrent tout ce que l'API peut refuser. Branchez votre logique dessus, jamais sur le texte du message.

400 requête mal formée, champ absent ou hors bornes
401 clé absente, inconnue ou révoquée
402 la retouche dépasse le budget inclus et n'a pas été confirmée
403 le compte est bloqué, ou la capacité n'est pas ouverte
404 la ressource visée n'existe pas, ou n'est pas la vôtre
409 l'état actuel interdit l'opération demandée
429 une limite de débit ou le volume mensuel est atteint
500 un défaut de notre côté, à signaler
502 un service dont nous dépendons a répondu de travers
503 indisponibilité temporaire, réessayez plus tard

À savoir : UN 409 N'EST PAS UNE ERREUR DE VOTRE CÔTÉ : il dit que l'ordre des opérations ne va pas, une régénération déjà en cours, un audio produit avant le calage mot à mot. Le rejouer à l'identique plus tard marche souvent. Un 400 rejoué à l'identique, jamais.

Produire

Envoyer un texte et obtenir un audio. Le mode synchrone publie l'article déjà sonorisé.

POST

Générer l'audio

/api/v1/podcasts

La route principale. Avec `wait` à vrai, la réponse attend la fin de la synthèse et contient l'adresse du fichier : l'article se publie déjà sonorisé, sans délai visible.

Ce que la route lit
  • textobligatoireLe texte intégral, de 100 à 100 000 caractères.
  • titlefacultatifSert au flux podcast et à la page de provenance.
  • canonical_urlfacultatifL'adresse de l'article chez vous.
  • external_idfacultatifVotre identifiant. C'est lui qui garantit la déduplication : le même envoyé deux fois ne produit qu'un audio.
  • rubriquefacultatifDétermine la voix, l'habillage et les statistiques par section. Alias accepté : `section`.
  • authorfacultatifAlimente les statistiques par signature. Alias accepté : `byline`.
  • voicefacultatifIdentifiant de voix. Une voix inconnue est refusée par un 400, pas remplacée en silence.
  • languagefacultatiffr, en, es, de, it, hi, zh, ar, pt, ja, he, ko, nl, sv, pl, ta, te, ru, tr, th, tl, cs, fi.
  • triggerfacultatif`auto` pour soumettre à l'interrupteur du compte, `manual` pour forcer.
  • publish_atfacultatifDate ISO future : prépare l'audio pour une publication programmée.
  • webhook_urlfacultatifAdresse https publique, appelée quand l'audio est prêt. Elle vaut POUR CET APPEL et n'est jamais retenue comme réglage.
  • auto_regeneratefacultatifRégénérer automatiquement quand le texte change.
  • waitfacultatifVrai pour recevoir l'audio dans la réponse. Sans effet au-delà de 20 000 caractères.

Idempotency-Key Rejouer le même appel avec la même clé ne produit pas un second audio.

POST https://wedispatch.fr/api/v1/podcasts
Content-Type: application/json

{
  "text": "Le conseil municipal a adopte hier soir...",
  "title": "Le budget 2027 adopte",
  "external_id": "id-dans-votre-cms",
  "rubrique": "Politique",
  "wait": true
}

Ce qu'elle renvoie : `article_id`, `job_id`, `status`, `embed`, et avec `wait` : `audio_url`, `duration_s`, `version`, `engine`, `voice`, `fallback`.

À traiter : 400 texte, voix, langue ou date invalides · 403 compte bloqué · 429 quota mensuel atteint, ou dix par minute dépassé

À savoir : Un article de plus de 1 000 caractères consomme un crédit de plus par tranche entamée, et la tranche entamée est perdue.

POST

Génération par lot

/api/v1/podcasts/batch

Jusqu'à vingt-cinq articles en une requête, pratique pour un fonds d'archives. Chaque champ unitaire est accepté par entrée, et `language`, `trigger` et `auto_regenerate` acceptent aussi une valeur pour tout le lot.

Ce que la route lit
  • itemsobligatoireTableau non vide, vingt-cinq entrées au maximum. Chaque entrée accepte les mêmes champs que la génération unitaire.
POST https://wedispatch.fr/api/v1/podcasts/batch
{ "items": [
  { "text": "...", "external_id": "a1", "rubrique": "Sports" },
  { "text": "...", "canonical_url": "https://.../article-2" }
] }

Ce qu'elle renvoie : `accepted`, `total`, et `results[]` où chaque entrée porte son propre `status` : `processing`, `ready`, `stale`, `quota`, `blocked`, `skipped` ou `error`.

À traiter : 400 items absent, vide ou au-delà de vingt-cinq · 429 quatre lots par minute dépassé

À savoir : `wait` n'existe PAS sur cette route, et l'en-tête d'idempotence n'y est pas lu. Le volume mensuel restant borne le lot avant les limites de débit : vingt-cinq articles avec dix crédits restants en traite dix et signale le reste en `quota`.

POST

Régénérer entièrement

/api/v1/podcasts/{article_id}/regenerate

Pour un article modifié en profondeur. Consomme un crédit comme une génération. Elle repart aussi d'un compteur de correction vierge (`patch_chars_used`), qui n'est qu'une mesure du texte repris sur cet audio : il n'ouvre aucun droit, et une correction coûte le même prix avant et après.

Ce que la route lit
  • voicefacultatifChanger de voix au passage.
  • languagefacultatifChanger de langue au passage.
  • publish_atfacultatifProgrammer la mise en ligne de la nouvelle version.
  • webhook_urlfacultatifAppelé quand la nouvelle version est prête.
POST https://wedispatch.fr/api/v1/podcasts/{article_id}/regenerate

Ce qu'elle renvoie : `article_id`, `job_id`, `status`, `regens_included`, `regens_used`.

À traiter : 404 article inconnu · 409 aucun texte stocké à régénérer · 429 plafond de régénérations ou quota mensuel

À savoir : C'est la première cause de consommation involontaire, en général après une petite correction de texte. Regardez d'abord si la retouche suffit : elle ne facture que le passage réécrit, là où une régénération repaie l'article entier.

Suivre

L'état d'un article, et la liste des derniers.

GET

Suivre un article

/api/v1/podcasts/{article_id}

L'état d'un article et, quand il est prêt, l'adresse de son audio. À appeler après un envoi sans `wait`, ou à la réception d'un webhook.

GET https://wedispatch.fr/api/v1/podcasts/{article_id}

Ce qu'elle renvoie : `article_id`, `title`, `status` (`processing`, `ready`, `stale` ou `failed`), `regen_count`, `audio` (`null` ou l'objet complet avec `url`, `duration_s`, `version`), `embed`, `subtitles`.

À traiter : 404 article inconnu · 503 lien audio temporairement indisponible

GET

Lister vos articles

/api/v1/podcasts

Les trente derniers articles du compte, du plus récemment modifié au plus ancien.

GET https://wedispatch.fr/api/v1/podcasts

Ce qu'elle renvoie : `articles[]` : `id`, `title`, `canonical_url`, `audio_status`, `char_count`, `regen_count`, `updated_at`, et selon l'état de la base `rubrique` et `author`.

À savoir : CETTE ROUTE N'ACCEPTE AUCUN PARAMÈTRE. Ni filtre d'état, ni pagination, ni date. Trente lignes, toujours. Si vous avez besoin de retrouver les articles à régénérer, comparez vous-même `audio_status` sur ce que vous recevez.

DELETE

Retirer un audio

/api/v1/podcasts/{article_id}

Supprime les fichiers audio d'un article. L'article, son texte source et ses statistiques d'écoute sont conservés.

DELETE https://wedispatch.fr/api/v1/podcasts/{article_id}

Ce qu'elle renvoie : `ok`, `article_id`, `status`, `removed_versions`, et `kept` qui dit explicitement ce qui n'a pas été supprimé.

À traiter : 400 identifiant invalide · 404 article inconnu · 409 une génération est en cours

À savoir : Aucun crédit n'est remboursé, et la réponse le dit plutôt que de le taire.

GET

Articles proches

/api/v1/recommendations

Les articles les plus proches d'un article donné, pour proposer une écoute suivante.

Ce que la route lit
  • article_idobligatoireEn paramètre de requête, au format UUID.
  • limitfacultatifPar défaut cinq, entre un et vingt.
GET https://wedispatch.fr/api/v1/recommendations?article_id={uuid}&limit=5

Ce qu'elle renvoie : `article_id`, `count`, `recommendations[]` avec `id`, `title`, `rubrique`, `created_at`, `player_url`.

À traiter : 400 article_id absent ou mal formé · 404 article introuvable

Afficher

Le lecteur sur votre page, et les sous-titres.

Afficher le lecteur

Une ligne dans votre gabarit

Le lecteur se pose en une ligne. Le mode automatique retrouve seul l'audio correspondant à la page affichée, à partir de son adresse canonique.

<script src="https://wedispatch.fr/p.js" async></script>
<div data-wd-player data-wd-external-id="12345"></div>

À savoir : Si votre thème filtre le contenu par un point d'entrée inhabituel, l'insertion automatique peut échouer. Le conteneur explicite vous rend la main sur l'emplacement exact.

GET

Sous-titres

/api/v1/podcasts/{article_id}/subtitles

Fichier de sous-titres aligné sur la lecture RÉELLE, pas sur le texte source. C'est ce qui évite la dérive dès le premier nombre développé.

Ce que la route lit
  • formatfacultatif`srt` par défaut, ou `vtt`.
GET https://wedispatch.fr/api/v1/podcasts/{article_id}/subtitles?format=vtt

Ce qu'elle renvoie : Le fichier lui-même, en texte brut. Ce n'est pas du JSON.

À traiter : 400 format inconnu · 404 article ou calage introuvable · 409 audio produit avant le calage mot à mot

Retoucher

Agir sur un audio déjà produit sans tout régénérer.

GET

La position de chaque mot

/api/v1/podcasts/{article_id}/words

Le premier des deux temps d'une retouche : un passage se désigne par des index de mots, il faut donc d'abord savoir où chaque mot tombe dans la bande son.

GET https://wedispatch.fr/api/v1/podcasts/{article_id}/words

Ce qu'elle renvoie : `article_id`, `title`, `duration_s`, `words[]` avec pour chaque mot son début et sa fin.

À traiter : 403 la retouche n'est pas ouverte sur ce compte · 409 le moteur utilisé ne produit pas de calage mot à mot · 409 audio antérieur au calage

POST

Retoucher un passage

/api/v1/podcasts/{article_id}/correct

Vous réécrivez le passage fautif, lui seul est resynthétisé et recousu dans l'audio existant. L'adresse du fichier ne change pas, donc vos pages n'ont rien à mettre à jour.

Ce que la route lit
  • from_wordobligatoireIndex du premier mot à remplacer, dans le tableau rendu par la route précédente.
  • to_wordobligatoireIndex du dernier mot, inclus.
  • textobligatoireCe qu'il faut entendre à la place.
  • accept_credit_usefacultatifConfirme que vous acceptez de dépenser le ou les crédits. Toute retouche en coûte au moins un : sans ce champ, la demande est refusée en 402 avec son prix.
POST https://wedispatch.fr/api/v1/podcasts/{article_id}/correct
{
  "from_word": 142,
  "to_word": 149,
  "text": "deux virgule quatre millions d'euros"
}

Ce qu'elle renvoie : `ok`, `version`, `duration_s`, `patch_chars`, `patch_chars_used`, `credits_used`, `review`.

À traiter : 402 la dépense n'a pas été confirmée · 403 la retouche n'est pas ouverte sur ce compte · 409 audio sans calage mot à mot

À savoir : Le prix est rendu SUR LE REFUS, dans `credits_required` : c'est au moment où l'on est refusé qu'on a besoin de savoir ce que la demande coûterait. Un crédit ouvre mille caractères et chaque retouche ouvre les siens, il n'existe donc pas de retouche à zéro crédit. `review` à vrai signale une couture serrée qui mérite une écoute avant diffusion.

Régler

Les réglages du compte lisibles et modifiables par clé.

GET

Lire les réglages

/api/v1/profile

Tous les réglages du compte, groupés par domaine, plus ce que votre offre ouvre réellement.

GET https://wedispatch.fr/api/v1/profile

Ce qu'elle renvoie : `player`, `reading` (dont le lexique de prononciation), `sound`, `gate`, `capabilities`, `player_templates`, et `editable` : la liste exacte des champs qu'une clé peut écrire.

À savoir : `editable` est la source de vérité. Plutôt que de recopier la liste ci-dessous dans votre code, lisez-la : elle vous dira ce qui est modifiable le jour où elle changera.

GET

Lire le lexique de prononciation

/api/v1/pronunciations

Les corrections de prononciation du compte, celles qui s'appliquent à tous les articles avant synthèse.

GET https://wedispatch.fr/api/v1/pronunciations

Ce qu'elle renvoie : `pronunciations` (la liste `{ de, vers }`), `count`, `max`.

À savoir : La LECTURE n'est pas réservée : un compte qui perd l'option doit pouvoir relire et exporter ce qu'il avait posé. C'est l'écriture qui l'est.

POST

Ajouter ou corriger une prononciation

/api/v1/pronunciations

Fusionne dans le lexique existant : ce que vous n'envoyez pas n'est pas touché. Un mot déjà présent voit sa prononciation remplacée, jamais dupliquée.

POST https://wedispatch.fr/api/v1/pronunciations
{ "de": "Ploërmel", "vers": "Plo-air-mel" }

Ce qu'elle renvoie : La liste complète après le geste, plus `added`, `replaced`, `ignored`.

À traiter : 400 aucune entrée exploitable (`de` et `vers` requis, 80 caractères au plus) · 403 le lexique n'est pas ouvert sur ce compte · 409 lexique plein (200 entrées)

À savoir : Un appel qui n'a RIEN posé rend une erreur, jamais un 200 : sans quoi votre interface afficherait « enregistré » pour une correction qui n'existe pas. La casse ne crée pas de doublon, les accents si : « Ploërmel » et « Ploermel » sont deux entrées, et c'est voulu.

DELETE

Retirer une prononciation

/api/v1/pronunciations

Par mot source, casse ignorée. Retirer un mot absent n'est pas une erreur.

DELETE https://wedispatch.fr/api/v1/pronunciations
{ "de": "Ploërmel" }

Ce qu'elle renvoie : La liste complète après le geste, plus `removed`.

À traiter : 400 ni `de`, ni `pronunciations`, ni `all: true`

À savoir : Tout vider EXIGE `all: true`. Un DELETE sans corps est ce qu'un client HTTP envoie quand il se trompe d'appel ; lui faire effacer deux cents entrées irrécupérables serait un piège.

PUT

Modifier les réglages

/api/v1/profile

Vingt-cinq champs sont modifiables par clé, dont le lexique de prononciation, la voix par défaut, les règles de voix et l'apparence du lecteur.

PUT https://wedispatch.fr/api/v1/profile
{ "default_voice": "...", "player_template": "..." }

Ce qu'elle renvoie : `ok`, plus `ignored[]` si vous avez envoyé des champs qui ne sont pas modifiables par clé.

À traiter : 400 aucun champ modifiable dans le corps envoyé · 403 le réglage demandé n'est pas ouvert sur ce compte · 409 le réglage exige un calage mot à mot absent

À savoir : Un champ non modifiable n'est pas une erreur : il est écarté et RENDU dans `ignored`, pour que vous le voyiez au lieu de le supposer appliqué. Le mode d'accès conditionnel n'est jamais modifiable par clé, délibérément.

Mesurer

La consommation et les écoutes. Des comptages, jamais des personnes.

GET

L'état du compte

/api/v1/account

Le volume souscrit, la consommation du mois, et ce que l'offre inclut.

GET https://wedispatch.fr/api/v1/account

Ce qu'elle renvoie : `plan_label`, `volume`, `usage` (dont `credits_used`, `credits_quota`, `articles_left`), `included`, `access`, `offre`, `urls`.

À savoir : `plans` et `next_plan` sont vides et le resteront : ils datent des anciens forfaits et ne sont gardés que pour ne casser aucune intégration existante. La structure de `offre` n'est pas décrite ici, faute d'avoir été auditée : lisez-la plutôt que de la supposer.

GET

La consommation du mois

/api/v1/usage

Ce qui a été consommé sur la période en cours, en crédits et en caractères.

GET https://wedispatch.fr/api/v1/usage

Ce qu'elle renvoie : `period`, `quota_credits`, `credits_used`, `credits_left`, `percent_used`, `warning`, `blocked`, `generations`, `regenerations`, `listens`, `audio_minutes`.

GET

Les écoutes

/api/v1/stats

Des comptages agrégés, par article, par rubrique et par signature. Jamais par personne : l'information n'existe pas.

GET https://wedispatch.fr/api/v1/stats

Ce qu'elle renvoie : `generated_at`, `totals`, `last_30_days`, `articles`, `authors`.

À savoir : Aucun paramètre : pas de filtre de période, pas de pagination. La structure interne des agrégats n'est pas détaillée ici faute d'audit : elle est stable, mais nous préférons vous la faire lire que vous la décrire de mémoire.

POST

Nous dire ce qui n'allait pas

/api/v1/feedback

Un retour court, envoyé par l'extension WordPress au moment où quelqu'un la désactive, et UNIQUEMENT s'il a cliqué « Envoyer ». Documentée ici parce qu'elle existe : une route qu'on n'écrit pas est une route qu'on oublie de sécuriser.

POST https://wedispatch.fr/api/v1/feedback
{ "type": "desactivation", "motif": "affichage", "texte": "…", "version": "1.27.0" }

Ce qu'elle renvoie : `ok`. Toujours 200 : l'appelant est en train de désactiver une extension, son geste ne doit dépendre d'aucune de nos pannes.

À savoir : Ne contient jamais de contenu d'article ni rien sur un auditeur. Les champs inconnus sont ignorés sans erreur, pour qu'une version future de l'extension ne perde pas son retour sur un détail de forme.

Les voix

Le catalogue, et un aperçu sonore avant de choisir.

GET

Le catalogue de voix

/api/v1/voices

Les voix disponibles pour votre compte, y compris vos voix signature.

GET https://wedispatch.fr/api/v1/voices

Ce qu'elle renvoie : `engine`, `default`, `voices[]` avec `id`, `label`, `gender`, `style`, `langs[]`, et `sample` quand un extrait existe.

À savoir : Cette route est servie SANS clé, parce que la documentation et le démonstrateur en dépendent. En revanche, une clé PRÉSENTÉE et refusée fait échouer l'appel : elle ne retombe jamais sur le catalogue public, ce qui masquerait une clé morte.

POST

Écouter une voix

/api/v1/voices/preview

Un extrait sonore sur votre propre texte, avant de choisir. Ne consomme aucun crédit.

Ce que la route lit
  • textobligatoireDe 100 à 3 000 caractères.
  • voicefacultatifSinon la voix par défaut du compte.
  • languagefacultatifSinon la langue par défaut.
POST https://wedispatch.fr/api/v1/voices/preview
{ "text": "...", "voice": "..." }

Ce qu'elle renvoie : Le fichier audio lui-même. L'en-tête `X-WeDispatch-Billed` vaut zéro, et l'en-tête `X-WeDispatch-Voice` dit quelle voix a réellement parlé.

À traiter : 400 texte trop court ou trop long · 429 trente aperçus par heure dépassés

À savoir : Une voix inconnue n'est PAS refusée ici : elle est remplacée par la voix par défaut. Lisez l'en-tête de réponse pour savoir laquelle a servi, sans quoi vous croirez avoir écouté celle que vous aviez demandée.

Accès conditionnel

Pour un contenu réservé : vérifier un jeton d'écoute côté serveur.

GET

La configuration d'accès

/api/v1/access

Le mode d'accès du compte et le secret qui permet de signer des jetons d'écoute.

GET https://wedispatch.fr/api/v1/access

Ce qu'elle renvoie : `mode`, `preview_seconds`, `token_ttl_s`, `secret`, `client_id`.

À savoir : Le secret ne sort jamais du serveur. Cette route est à appeler depuis votre back-office, jamais depuis une page.

POST

Vérifier un jeton d'écoute

/api/v1/access/check

Pour un contenu réservé : votre serveur vérifie qu'un jeton donne bien droit à cet article.

Ce que la route lit
  • articleobligatoireL'identifiant de l'article demandé.
  • tokenfacultatifLe jeton présenté. Son absence rend simplement un refus motivé.
POST https://wedispatch.fr/api/v1/access/check
{ "article": "{article_id}", "token": "..." }

Ce qu'elle renvoie : `valid`, `status`, `reason`, `detail`, `mode`. Le motif dit précisément pourquoi : jeton absent, mal formé, signature invalide, mauvais article, ou expiré.

À traiter : 400 champ article manquant

POST

Échanger un code contre une clé

/api/v1/connect/exchange

Ce que fait l'extension WordPress à l'installation : elle échange un code à durée courte contre sa propre clé, de serveur à serveur. L'utilisateur ne voit jamais la clé.

Ce que la route lit
  • codeobligatoireLe code obtenu à l'écran d'autorisation.
  • secretobligatoireLe secret de votre installation.
POST https://wedispatch.fr/api/v1/connect/exchange
{ "code": "...", "secret": "..." }

Ce qu'elle renvoie : `api_key`, `plan`, `tier`, `site`, `label`.

À traiter : 400 code expiré ou invalide · 400 maximum dix clés actives atteint · 404 compte introuvable

À savoir : C'est la seule route, avec le catalogue de voix, qui ne demande pas de clé : elle sert justement à en obtenir une.

Un cas qui n'est pas couvert ?

Cette documentation décrit ce que le code fait, pas ce que nous aimerions qu'il fasse. Si vous cherchez une route qui n'y est pas, elle n'existe probablement pas : dites-nous ce que vous vouliez faire, c'est utile même quand la réponse est non.

Vous préférez ne pas coder ? L'extension WordPress fait la même chose sans clé à manipuler.