Skip to main content

Comment générer des podcasts avec l'API Podhoc : guide complet

Générez des podcasts par IA de manière programmatique avec l'API REST Podhoc. Authentification, cycle créer-interroger-télécharger, limites de débit, estimation des crédits et exemples Python et Node.js prêts pour la production.

Générez des podcasts par IA de manière programmatique avec l’API Podhoc

Pour générer un podcast avec l’API Podhoc, envoyez une requête POST à https://api-ext.podhoc.com/v1/podcasts avec votre en-tête X-Api-Key, les URLs sources, une durée cible entre 1 et 120 minutes et une configuration optionnelle de style et de voix. Le endpoint renvoie un podcast_id que vous interrogez sur /v1/podcasts/{id}/status jusqu’à la fin (généralement 2-5 minutes), puis vous appelez /v1/podcasts/{id}/download pour récupérer une URL MP3 pré-signée valable une heure.

L’API est conçue pour un seul cycle créer-interroger-télécharger. Pas de streams, pas de callbacks, pas de webhooks (pour le moment). L’authentification est un seul en-tête statique. Si vous avez déjà appelé une API REST, vous pouvez intégrer Podhoc en moins d’une heure.


À quoi sert l’API

L’API Podhoc expose le même pipeline de génération qui alimente l’application web, réduit à un petit ensemble de primitives :

  • Création programmatique de podcasts depuis des URLs publiques.
  • Estimation du coût avant de dépenser des crédits.
  • Introspection du compte — solde de crédits, historique d’utilisation, niveau actuel.
  • Gestion du cycle de vie — interrogation de statut et téléchargement pré-signé.

Le pipeline derrière ces primitives est le même système en cinq étapes décrit dans Qu’est-ce qu’un podcast IA ? : ingestion, compréhension, reformatage audio, choix du format et synthèse vocale. L’API rend simplement le tout scriptable.

Cas d’usage courants :

  • Un produit SaaS qui transforme les URLs téléversées par les clients en audio d’onboarding.
  • Un outil interne qui convertit des newsletters hebdomadaires en épisodes prêts pour le trajet.
  • Une plateforme d’apprentissage qui génère automatiquement des versions audio des nouveaux modules.
  • Un workflow de recherche qui synthétise un ensemble de papiers en un seul briefing de 30 minutes.

Pour plus, voir Idées d’intégration avec l’API.


Étape 1 — Provisionner un jeton

L’accès à l’API est limité au plan Pro (29 €/mois, 3500 crédits) et supérieur. Une fois votre abonnement mis à niveau, allez sur app.podhoc.com/account/api-access et créez un jeton.

Il y a deux variantes :

  • Jetons de test — préfixe phk_test_…, moins chers (multiplicateur 1,5x), ensemble restreint de fonctionnalités. Utilisez-les pour le développement et les tests d’intégration en CI.
  • Jetons de production — préfixe phk_prod_…, ensemble complet de fonctionnalités, multiplicateur 2,5x.

Traitez les jetons comme des mots de passe. Stockez-les dans un gestionnaire de secrets (AWS Secrets Manager, HashiCorp Vault, Doppler) et ne les commitez jamais dans le contrôle de source. L’API rejette les requêtes avec des jetons fuités ou révoqués avec un 401 UNAUTHORIZED.

L’authentification est un seul en-tête sur chaque requête :

X-Api-Key: phk_prod_a1b2c3d4e5f6...

L’URL de base est https://api-ext.podhoc.com/v1. Tous les endpoints renvoient du JSON avec un booléen success, un objet data en cas de succès, un objet error en cas d’échec et un objet meta avec request_id et des champs liés aux crédits. L’enveloppe s’inspire des mêmes conventions que Anthropic et d’autres fournisseurs IA modernes — structure prévisible, gestion d’erreurs prévisible.


Étape 2 — Estimer le coût d’abord

Avant d’appeler le endpoint de création, demandez à l’API combien elle facturera. Le endpoint d’estimation est gratuit et vous permet d’implémenter des contrôles de dépense proprement.

curl "https://api-ext.podhoc.com/v1/estimate-cost?duration_minutes=30&source_count=2&voice_count=2" \
  -H "X-Api-Key: $PODHOC_API_KEY"

La réponse détaille le coût pour que vous puissiez appliquer votre propre logique de politique :

{
  "success": true,
  "data": {
    "base_credits": 114,
    "credit_multiplier": 1.5,
    "final_credits": 171,
    "breakdown": {
      "base_cost": 75,
      "multi_source_bonus": 20,
      "custom_weights_bonus": 0,
      "voice_multiplier": 1.2,
      "subtotal_before_cap": 114,
      "cap_applied": null,
      "tier_max_cost": 500
    },
    "formula": "max(30, ceil(30 x 2.5)) + 20 x 1.2 = 114 x multiplier = 171"
  }
}

La formule de tarification a un plafond de 500 crédits par requête, appliqué après les multiplicateurs de voix, les bonus multi-source et les bonus de poids personnalisés. Utilisez le détail pour afficher à vos utilisateurs finaux un aperçu “cet épisode coûtera N crédits” avant qu’ils ne confirment.

Vous pouvez aussi récupérer votre solde en direct :

curl https://api-ext.podhoc.com/v1/account/credits \
  -H "X-Api-Key: $PODHOC_API_KEY"

Étape 3 — Créer le podcast

Le endpoint de création est celui qui fait le travail et facture des crédits. La charge utile minimale est une liste d’URLs :

curl -X POST https://api-ext.podhoc.com/v1/podcasts \
  -H "X-Api-Key: $PODHOC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com/article"],
    "language": "fr",
    "target_duration_minutes": 15,
    "style": "deep_dive",
    "voice_config": { "voices": 2 }
  }'

La réponse (HTTP 202 Accepted) vous donne l’identifiant que vous interrogerez :

{
  "success": true,
  "data": {
    "podcast_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "processing",
    "estimated_duration_minutes": 15,
    "credits_charged": 113
  },
  "meta": {
    "request_id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
    "credits_charged": 113,
    "credit_balance": 3387
  }
}

Le paramètre style est l’un des huit formats pédagogiques que Podhoc prend en charge — deep_dive, didactic, feynman_technique, critique, debate, simplified_explanation, pedagogical_framework, alchemist_formula. Chacun produit une sortie nettement différente pour la même source. Voir le guide des styles audio pour savoir quand choisir lequel.

Le paramètre language accepte n’importe lequel des 74 codes de langue pris en charge — en-US, es, fr, de, it, ca, ar, ru, plus 66 autres. La langue source et la langue de sortie sont découplées : passez une URL en anglais avec language: "fr" et vous obtenez un podcast en français.


Étape 4 — Interroger le endpoint de statut

La génération est asynchrone. Le podcast_id est votre identifiant pour le reste du cycle de vie.

curl https://api-ext.podhoc.com/v1/podcasts/$PODCAST_ID/status \
  -H "X-Api-Key: $PODHOC_API_KEY"

Le statut passe par quatre valeurs :

  • requested — accepté, en file d’attente.
  • processing — en cours d’exécution.
  • completed — prêt à télécharger.
  • failed — erreur terminale ; consultez les détails de la réponse.

Interrogez toutes les 10 secondes avec un petit backoff. La plupart des podcasts se terminent en 2-5 minutes quelle que soit la longueur de la source, car le pipeline est parallélisé sur des GPUs cloud. Un client raisonnable implémente l’interrogation avec un plafond strict (15 minutes) et expose une interface “en cours” à l’utilisateur final.


Étape 5 — Télécharger le MP3

Le endpoint de téléchargement renvoie une URL S3 pré-signée qui expire après une heure :

curl https://api-ext.podhoc.com/v1/podcasts/$PODCAST_ID/download \
  -H "X-Api-Key: $PODHOC_API_KEY"
{
  "success": true,
  "data": {
    "download_url": "https://s3.amazonaws.com/...",
    "expires_at": "2026-05-06T11:00:00+00:00",
    "format": "mp3",
    "duration_seconds": 900
  }
}

Streamez l’URL vers votre propre stockage. Si vous avez besoin d’une référence permanente, copiez les octets dans votre bucket S3 / GCS / Azure — l’URL pré-signée est de courte durée, mais l’audio que vous récupérez vit pour toujours dans votre environnement.


Une intégration Python complète

Voici le même cycle sous forme de script exécutable. Il estime le coût, vérifie le solde, crée, interroge et télécharge. La gestion d’erreurs est volontairement explicite pour que vous voyiez où chaque contrat de l’API est appliqué.

import os
import time

import requests

API_KEY = os.environ["PODHOC_API_KEY"]
BASE = "https://api-ext.podhoc.com/v1"
HEADERS = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}


def estimate(duration: int, sources: int, voices: int) -> int:
    r = requests.get(
        f"{BASE}/estimate-cost",
        headers={"X-Api-Key": API_KEY},
        params={
            "duration_minutes": duration,
            "source_count": sources,
            "voice_count": voices,
        },
        timeout=15,
    )
    r.raise_for_status()
    return r.json()["data"]["final_credits"]


def balance() -> int:
    r = requests.get(f"{BASE}/account/credits", headers={"X-Api-Key": API_KEY}, timeout=15)
    r.raise_for_status()
    return r.json()["data"]["credits"]


def create(urls: list[str], duration: int, language: str, style: str) -> str:
    r = requests.post(
        f"{BASE}/podcasts",
        headers=HEADERS,
        json={
            "urls": urls,
            "language": language,
            "target_duration_minutes": duration,
            "style": style,
        },
        timeout=30,
    )
    r.raise_for_status()
    return r.json()["data"]["podcast_id"]


def wait_for(podcast_id: str, max_seconds: int = 900) -> None:
    started = time.time()
    while time.time() - started < max_seconds:
        r = requests.get(
            f"{BASE}/podcasts/{podcast_id}/status",
            headers={"X-Api-Key": API_KEY},
            timeout=15,
        )
        r.raise_for_status()
        status = r.json()["data"]["status"]
        if status == "completed":
            return
        if status == "failed":
            raise RuntimeError(f"Generation failed: {r.json()}")
        time.sleep(10)
    raise TimeoutError(f"Podcast {podcast_id} did not complete within {max_seconds}s")


def download(podcast_id: str, dest: str) -> None:
    r = requests.get(
        f"{BASE}/podcasts/{podcast_id}/download",
        headers={"X-Api-Key": API_KEY},
        timeout=15,
    )
    r.raise_for_status()
    audio = requests.get(r.json()["data"]["download_url"], timeout=60)
    audio.raise_for_status()
    with open(dest, "wb") as f:
        f.write(audio.content)


if __name__ == "__main__":
    cost = estimate(duration=15, sources=1, voices=2)
    if balance() < cost:
        raise SystemExit(f"Insufficient credits ({balance()} < {cost})")

    pid = create(
        urls=["https://example.com/article"],
        duration=15,
        language="fr",
        style="deep_dive",
    )
    wait_for(pid)
    download(pid, "podcast.mp3")
    print(f"Saved podcast.mp3")

Un équivalent Node.js utilise le même flux avec fetch. Les deux sont documentés dans la référence API complète.

Note de traduction : à relire par un locuteur natif francophone.


Limites de débit et comment les respecter

Type de jetonRequêtes/minuteRequêtes/heureGénérations concurrentes
Test2201
Production303005

Atteindre une limite renvoie HTTP 429 avec un en-tête Retry-After. Un client correct respecte cet en-tête et met en file la prochaine tentative en conséquence. Les limites de production sont calibrées pour des intégrations SaaS typiques — la plupart des équipes ne s’en approchent jamais. Si vous le faites, parlez-nous d’un quota entreprise.

La pratique standard pour durcir tout client API s’applique ici : mettez un timeout sur chaque requête (15-30 secondes suffisent), plafonnez les tentatives (trois essais avec backoff exponentiel) et exposez les erreurs 5xx à votre opérateur au lieu de les avaler. La RFC OAuth 2.1 est démesurée pour une API à jeton statique comme celle-ci, mais son hygiène opérationnelle vaut la peine d’être empruntée — journalisez les IDs de requête (meta.request_id) sur chaque erreur pour que le support puisse corréler.


Ce que les jetons de test ne peuvent pas faire

Les jetons de test sont délibérément restreints pour que vous puissiez intégrer à moindre coût sans brûler des crédits de production. Spécifiquement :

  • Durée maximum d’épisode : 5 minutes.
  • Langues autorisées : anglais (en-US, en) uniquement.
  • URLs par requête : 1.
  • Voix maximum : 2.
  • custom_focus, source_weights et auto_publish : non disponibles.

Toute tentative renvoie 400 TEST_TOKEN_RESTRICTED. Passez à un jeton de production (toujours dans le même compte Pro) lorsque vous êtes prêt à expédier.


Webhooks, téléversements de fichiers et ce qui n’est pas pris en charge (encore)

Quelques capacités qui existent dans l’application web ne sont pas dans l’API aujourd’hui :

  • Téléversements de fichiers. Vous pouvez passer des URLs mais pas des octets bruts PDF / DOCX / TXT. Si votre contenu est derrière une authentification, hébergez-le publiquement avec une URL signée ou contactez-nous pour une voie entreprise.
  • Corps de texte brut. Le paramètre urls est le seul mécanisme d’ingestion ; vous ne pouvez pas POSTer un champ text_content.
  • Webhooks / callbacks. Les changements de statut sont observés via interrogation. Une couche de webhooks est sur notre feuille de route ; pour l’instant, une boucle d’interrogation de 10 secondes est le motif recommandé.

Ces lacunes sont intentionnelles — l’API est livrée avec une surface minimale viable et nous l’élargirons à mesure que les motifs d’intégration se stabilisent.


Que construire ensuite

Une fois votre première intégration en place, l’étape naturelle suivante est d’adopter l’API dans une véritable surface produit. Quelques points de départ :

  • Couplez l’API avec un bot Telegram pour permettre à vos utilisateurs de déclencher la génération depuis le chat.
  • Combinez la création de podcasts avec nos huit styles audio pour permettre à vos utilisateurs de choisir le traitement pédagogique par source.
  • Animez des workflows PDF vers podcast en hébergeant le PDF publiquement d’abord, puis en passant l’URL.
  • Lisez Idées d’intégration avec l’API pour des motifs concrets que nous avons vus des équipes expédier avec l’API dans les 30 premiers jours.

L’objectif de l’API est de sortir Podhoc du navigateur et de l’amener dans votre produit. Le cycle en cinq étapes est volontairement petit. Construisez le wrapper fin, testez contre vos propres URLs et itérez.

Provisionner un jeton API →

Questions fréquentes

À quoi sert l'API Podhoc ?
L’API Podhoc vous permet de générer des podcasts par IA de manière programmatique à partir d’URLs publiques. Vous pouvez intégrer la création de podcasts dans votre propre produit, automatiser la génération en lot d’épisodes, construire des outils internes qui transforment des documents en audio et orchestrer des workflows multi-étapes combinant la génération avec d’autres services.
Quel plan inclut l'accès à l'API ?
L’accès à l’API est inclus dans le plan Pro (29 €/mois, 3500 crédits) et supérieur. Les plans Free et Creator n’incluent pas de jetons API. Vous trouverez les tarifs sur podhoc.com et pourrez créer des jetons sur app.podhoc.com/account/api-access une fois abonné.
Quelle est la différence entre les jetons de test et de production ?
Les jetons de test (phk_test_…) sont moins chers (multiplicateur de crédits 1,5x) mais limités : épisodes de 5 minutes maximum, anglais uniquement, 1 URL par requête, 2 voix maximum, pas de focus personnalisé, pas de pondération de sources, pas de publication automatique. Ils sont destinés au développement et aux tests d’intégration. Les jetons de production (phk_prod_…) coûtent 2,5x crédits et débloquent l’ensemble complet : épisodes de 120 minutes, les 73 langues de sortie, URLs illimitées par requête, toutes les options de voix, focus personnalisé, pondération des sources et publication automatique.
Quelles sont les limites de débit de l'API ?
Jetons de test : 2 requêtes/minute, 20 requêtes/heure, 1 génération concurrente. Jetons de production : 30 requêtes/minute, 300 requêtes/heure, 5 générations concurrentes. Lorsque vous atteignez une limite, l’API renvoie HTTP 429 avec un en-tête Retry-After indiquant quand réessayer. Les limites de production sont calibrées pour des intégrations SaaS typiques ; si vous avez besoin de plus de débit, contactez-nous pour un quota entreprise.
Combien de temps dure la génération et comment dois-je interroger ?
La plupart des podcasts se terminent en 2-5 minutes quelle que soit la longueur de la source, car le LLM et le pipeline TTS s’exécutent en parallèle sur des GPUs cloud. Interrogez GET /v1/podcasts/{id}/status toutes les 10 secondes avec un backoff exponentiel pour rester poli. Arrêtez sur statut completed ou failed. Pour des intégrations sensibles à la latence, affichez une interface “Génération en cours” à l’utilisateur pendant que vous interrogez en arrière-plan.
Quelles sources puis-je passer à l'API ?
L’API n’accepte que des URLs publiques — articles, billets de blog, papiers de recherche hébergés sur arXiv ou des dépôts institutionnels, vidéos YouTube avec transcription et toute URL dont le corps est accessible sans authentification. Les téléversements de fichiers (PDF/DOCX/TXT) et le contenu texte brut ne sont pas pris en charge via l’API aujourd’hui ; si vos sources sont derrière une authentification, hébergez-les publiquement d’abord ou contactez-nous pour discuter d’une intégration entreprise.
Comment le coût en crédits est-il calculé ?
Le coût de base est max(30, ceil(duration_minutes × 2,5)). Le bonus multi-source ajoute 20 crédits, le bonus poids personnalisés ajoute 10, le multi-voix multiplie par 1,2, et le plafond est de 500 crédits par requête. Le coût final API multiplie la base par 1,5 (jeton de test) ou 2,5 (jeton de production). Utilisez GET /v1/estimate-cost pour prévisualiser avant de générer — il renvoie le détail complet.
Quels codes d'erreur dois-je gérer ?
Les plus courants sont 400 INVALID_REQUEST (champs manquants ou mal formés), 400 INVALID_DURATION (hors plage 1-120 minutes), 400 TEST_TOKEN_RESTRICTED (fonctionnalité indisponible sur jetons de test — passez en production), 401 UNAUTHORIZED (jeton révoqué ou expiré), 402 INSUFFICIENT_CREDITS, 404 PODCAST_NOT_FOUND et 429 RATE_LIMITED (reculez selon Retry-After). Toutes les erreurs partagent la même enveloppe JSON avec champs code, message et details optionnels.