Aller au contenu principal

Développeurs

API de transcription pour l'audio enregistré

Avec l'API de transcription Hushscript, téléversez de l'audio enregistré, suivez la tâche et lisez la transcription avec un jeton aux permissions définies.

L’API de transcription Hushscript accepte l’audio enregistré via /v1/, puis permet à votre script de suivre la tâche et de lire la transcription. Ce parcours de transcription en ligne ne propose ni diffusion en direct ni accès direct à un modèle de reconnaissance vocale. Le serveur MCP utilise le même compte, le même solde et le même jeton porteur si votre client préfère des outils aux appels HTTP.

Transcription audio et vidéo via l’API

L’API de transcription audio accepte des fichiers audio préparés, y compris des enregistrements vocaux. Pour une intégration STT (speech-to-text), envoyez des fichiers enregistrés ; la diffusion en direct du microphone n’est pas prise en charge. Pour transcrire une vidéo, téléversez tel quel un fichier MP4 ou MOV avec une piste audio : le serveur lit la piste audio et ignore la vidéo. Extrayez d’abord l’audio de tout autre format vidéo ; l’API n’accepte pas d’URL de vidéo. Le parcours dans le navigateur est expliqué sur la page vidéo en texte.

Démarrage rapide

L’API nécessite un jeton d’accès personnel, et il existe deux façons d’en détenir un. Une personne en crée un sous Tokens sur la page MCP du compte, choisit ses scopes, et décide s’il peut acheter des minutes. Ou un agent ouvre son propre compte sans titulaire humain : POST /v1/agent/accounts démarre une inscription payante, et POST /v1/agent/accounts/{signup_id}/claim échange son secret à usage unique contre un compte réel et un premier jeton. Dans les deux cas, le jeton est affiché une seule fois et ressemble à hsr1:<region>:pat.<id>.<secret>. Un jeton émis via la connexion OAuth du serveur MCP fonctionne aussi ici ; voir Se connecter. Un jeton ne peut jamais créer, lister ni révoquer d’autres jetons, et un compte détient au maximum 25 jetons actifs ; le guide présente le parcours complet du compte d’agent, y compris la rotation des identifiants : Transcription automatique pour agents et scripts.

Une fois le jeton obtenu, appelez directement l’API. Cet exemple représente un nouveau compte personnel avant vérification de carte ou achat ; un compte créé par un agent commence avec le pack de minutes acheté :

curl https://api.hushscript.com/v1/account \
  -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
{
  "balance_seconds": 0,
  "held_seconds": 0,
  "credits_expire_at": null,
  "card_on_file": false,
  "data_region": "eu",
  "limits": {
    "max_active_jobs": 50,
    "max_daily_seconds": 144000,
    "active_jobs": 0,
    "used_today_seconds": 0
  }
}

La réponse indique le solde en secondes, les secondes réservées par les tâches en cours, credits_expire_at (toujours null, car les minutes n’expirent pas), la présence d’une carte enregistrée, la région des données et les limites d’admission (max_active_jobs, max_daily_seconds et les ressources déjà utilisées). La limite quotidienne est la limite effective actuelle du compte ; ne la codez pas en dur. POST /v1/uploads vérifie les minutes disponibles, pas la carte : si elles sont insuffisantes, il renvoie 3001 insufficient_balance.

L’API de transcription est-elle gratuite ?

Il n’existe pas d’offre gratuite générale pour l’API, mais vous pouvez essayer le parcours avant d’écrire du code : l’aperçu public transcrit jusqu’à cinq minutes d’un enregistrement avant la connexion. Un compte personnel éligible reçoit ensuite 30 minutes gratuites après vérification de carte (voir les tarifs pour les conditions). Un compte créé par un agent ne reçoit pas de minutes de bienvenue et commence avec le pack acheté à l’inscription. Dans les deux cas, une transcription complète via l’API nécessite un compte et des minutes.

Automatiser de bout en bout

Les mêmes appels /v1/ fonctionnent avec un jeton créé par une personne dans l’application ou obtenu par un agent après une inscription payante (voir Transcription automatique pour agents et scripts). Enregistrer une carte nécessite une page Checkout hébergée dans un navigateur ; un agent peut piloter ce navigateur. Les achats ultérieurs hors session peuvent être refusés si l’émetteur de la carte exige une authentification.

  1. Lire le compte. GET /v1/account. Si vous devez acheter des minutes et que card_on_file vaut false, enregistrez d’abord une carte.

  2. Enregistrer une carte, une fois. POST /v1/billing/setup-session renvoie un checkout_url, un session_id et un expires_at :

    curl -X POST https://api.hushscript.com/v1/billing/setup-session \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
    {
      "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8",
      "session_id": "seti_1PxYzQ2eZvKYlo2C",
      "expires_at": "2026-09-11T15:45:00Z"
    }

    Ouvrez l’URL dans un navigateur que vous contrôlez et complétez la page Stripe hébergée ; rien n’est débité et Hushscript ne voit jamais la carte. Ensuite, GET /v1/billing/cards la liste avec son identifiant. POST /v1/billing/cards/default change la carte par défaut si le compte en détient plusieurs.

  3. Acheter des minutes. GET /v1/billing/packs liste les cinq packs avec id, seconds, amount et currency :

    curl https://api.hushscript.com/v1/billing/packs \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"

    POST /v1/billing/purchase avec pack, quick_payment_method_id (l’identifiant de la carte enregistrée) et un idempotency_key débite la carte hors session et répond avec le nouveau balance_seconds :

    curl -X POST https://api.hushscript.com/v1/billing/purchase \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "pack": "300min",
        "quick_payment_method_id": "pm_2QeT4bY7uX9mK3nP",
        "idempotency_key": "purchase-2026-09-11-02"
      }'
    { "balance_seconds": 18000 }

    Cela nécessite le scope billing, la facturation activée sur le jeton et la facturation activée pour le compte. Un corps sans identifiant de carte, ou une carte refusée, est rejeté avec 4021 pat_purchase_requires_app ; une carte pour laquelle l’émetteur exige une authentification est rejetée avec 4023 pat_purchase_requires_authentication. Ni l’un ni l’autre n’ouvre une page que personne ne peut terminer.

  4. Téléverser. POST /v1/uploads avec size_bytes, duration_seconds (de 15 secondes à 10 heures), un title optionnel, transcription_options, matter_code et un idempotency_key :

    curl -X POST https://api.hushscript.com/v1/uploads \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "size_bytes": 41943040,
        "duration_seconds": 1200,
        "title": "Q3 board call",
        "transcription_options": { "speaker_detection": true },
        "idempotency_key": "upload-2026-09-11-02"
      }'

    matter_code est un texte libre de 64 caractères au plus, et il n’a de sens que pour un jeton appartenant à un espace de travail : il apparaît en regard de la tâche dans le registre et les rapports d’usage de cet espace de travail. Un espace de travail dont la politique de dossiers est réglée sur obligatoire rejette un téléversement sans code, avec org_matter_code_required. client_code est accepté et ignoré, car le client est un attribut du dossier, défini par un administrateur de l’espace de travail.

    Cet appel réserve des crédits et renvoie un job_id plus une première page d’URL de parties présignées :

    {
      "job_id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8",
      "part_urls": [
        { "n": 1, "url": "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." }
      ]
    }

    Faites un PUT de chaque partie vers son URL (parties de 32 MiB par défaut, la dernière plus petite) :

    curl -X PUT "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." \
      --data-binary @part-01.bin

    Récupérez les pages suivantes via GET /v1/uploads/{job}/part-urls?start=<n>, et appelez POST /v1/uploads/{job}/heartbeat bien avant le délai d’inactivité de 20 minutes lors d’un transfert long. Quand les URL présignées sont indisponibles, ou qu’une partie échoue, PUT /v1/uploads/{job}/parts/{n} envoie plutôt les octets de cette partie via l’API ; un PUT répété remplace la partie, donc les nouvelles tentatives sont sûres. Formats acceptés : mp3, m4a, mp4 ou mov (la piste audio est utilisée, les pistes vidéo sont ignorées), wav, flac, ogg ou opus, vérifiés côté serveur ; extrayez l’audio de tout autre format vidéo avant de le téléverser.

  5. Démarrer et attendre. POST /v1/uploads/{job}/complete avec le n et l’etag de chaque partie envoyée à une URL présignée (omettez parts si toutes les parties sont passées par l’API) :

    curl -X POST https://api.hushscript.com/v1/uploads/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8/complete \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "parts": [
          { "n": 1, "etag": "\"9f86d081884c7d65\"" }
        ]
      }'

    Ensuite, interrogez GET /v1/jobs/{id} : state passe par uploading, queued et processing jusqu’à done ou failed, et une tâche terminée comprend un transcript_id :

    curl https://api.hushscript.com/v1/jobs/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8 \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
    {
      "id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8",
      "state": "done",
      "transcript_id": "trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9"
    }
  6. Lire le résultat. GET /v1/transcripts/{id} renvoie les métadonnées et le texte complet, avec les noms des locuteurs, la langue détectée, les étiquettes et la date de suppression automatique :

    curl https://api.hushscript.com/v1/transcripts/trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9 \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"

    GET /v1/transcripts pagine la liste.

Les options de transcription sont celles de l’application, à l’identique : language_code ou détection automatique, speaker_detection, medical_mode (nécessite language_code en en, es, fr ou de, facturé à +100 %), translation_targets (+25 % par langue), multichannel, keyterms_prompt, un prompt en texte libre, et les dictionary_ids et prompt_preset_id enregistrés que liste GET /v1/transcription-context.

Certaines fonctions du compte restent accessibles uniquement via MCP : importation depuis un lien, modification ou suppression de transcriptions, Insights, exports, enregistrement de dictionnaires et de modèles d’invite, et paramètres du compte. Elles n’ont pas encore de route /v1/ ; le serveur MCP les couvre toutes avec le même jeton.

Authentification

Chaque appel /v1/ porte un jeton porteur dans l’en-tête Authorization, vérifié selon les mêmes scopes que ceux qu’utilise le serveur MCP :

Scope Autorisations
transcripts:read Lire et exporter les transcriptions, leurs métadonnées et la liste des éléments supprimés
transcripts:write Modifier, étiqueter, traduire, restaurer et supprimer des transcriptions
transcribe Téléverser des enregistrements, importer depuis un lien et lancer des transcriptions
insights Lire, générer et supprimer des Insights
context Gérer les dictionnaires enregistrés et les modèles d’invite
account:read Lire le solde, l’utilisation, les transactions et les réservations
settings:write Modifier les paramètres du compte
org:read Lire les membres de l’espace de travail, le registre, les factures et le journal d’audit
org:write Modifier les droits des membres, planifier le passage à la garde de l’organisation (permanente), et placer ou lever une conservation légale
export Demander un export complet du compte, vérifier son statut et le télécharger
billing Enregistrer une carte et acheter des packs de minutes

Un appel en dehors des scopes du jeton échoue avec pat_scope_missing, en 403. Le scope billing ne permet aucune action tant que la facturation n’est pas activée à la fois sur le jeton et sur le compte. Un appel de facturation avec l’un des deux réglages désactivé échoue avec le même pat_scope_missing ; réémettre le jeton n’active pas le réglage du compte. Un jeton ne peut pas créer, lister ni révoquer de jetons, et un compte détient au maximum 25 jetons actifs.

Ces 11 scopes sont sélectionnables par l’appelant. pat:rotate est un scope à part, accordé au premier jeton d’un compte d’agent et à ses successeurs renouvelés ; il permet à ce jeton de se remplacer lui-même, pas de gérer d’autres jetons. Vous ne pouvez pas le sélectionner en créant un jeton dans l’application.

Points de terminaison

Le document OpenAPI de production liste 38 opérations méthode/chemin sur 37 chemins. Chaque opération ci-dessous est protégée par le scope indiqué :

Méthode Chemin Scope
POST /v1/agent/accounts none
POST /v1/agent/accounts/{signup_id}/claim none
POST /v1/agent/credentials/rotate pat:rotate
GET /v1/account account:read
POST /v1/billing/setup-session billing
GET /v1/billing/cards billing
POST /v1/billing/cards/default billing
GET /v1/billing/packs billing
POST /v1/billing/purchase billing
GET /v1/billing/transactions account:read
GET /v1/billing/ledger account:read
GET /v1/billing/holds account:read
POST /v1/uploads transcribe
GET /v1/uploads/{job}/part-urls transcribe
PUT /v1/uploads/{job}/parts/{n} transcribe
POST /v1/uploads/{job}/heartbeat transcribe
POST /v1/uploads/{job}/complete transcribe
GET /v1/jobs transcribe
GET /v1/jobs/{id} transcribe
GET /v1/transcripts transcripts:read
GET /v1/transcripts/deleted transcripts:read
GET /v1/transcripts/{id} transcripts:read
GET /v1/transcription-context context
GET /v1/org org:read
GET /v1/org/members org:read
PATCH /v1/org/members/{user_id} org:write
GET /v1/org/matters org:read
GET /v1/org/transcripts org:read
POST /v1/org/transcripts/{id}/hold org:write
DELETE /v1/org/transcripts/{id}/hold org:write
POST /v1/org/custody org:write
GET /v1/org/invoices org:read
GET /v1/org/ledger org:read
GET /v1/org/ledger.csv org:read
GET /v1/org/usage org:read
GET /v1/org/usage.csv org:read
GET /v1/org/audit org:read
GET /v1/org/audit.csv org:read

/v1/agent/accounts ouvre une inscription sans interface et sans jeton pour l’instant, /v1/agent/accounts/{signup_id}/claim transforme une inscription payée en un compte réel et son premier jeton, et /v1/agent/credentials/rotate génère un successeur pour le jeton appelant et le retire dès que le successeur sert pour la première fois, sans toucher à aucun autre identifiant du compte. Le guide Transcription automatique pour agents et scripts couvre les trois de bout en bout.

Chaque liste accepte un limit et un cursor opaque, et renvoie un next_cursor qui vaut null sur la dernière page. Renvoyez le curseur inchangé ; il encode la position, si bien qu’une page n’est jamais sautée ni répétée quand des lignes arrivent entre deux appels.

La définition complète et à jour, avec les paramètres et les schémas de réponse de chaque opération, est le document OpenAPI : traitez-le comme la source de vérité plutôt que ce tableau. Il est accessible avec tout jeton porteur quel que soit son scope, si bien qu’un client peut le récupérer avec les identifiants qu’il détient déjà.

Interface MCP

Vous préférez des outils au HTTP brut ? Le serveur MCP place le même compte derrière 56 outils au lieu de ces points de terminaison, pour un client qui utilise déjà MCP plutôt que REST. Il annonce uniquement les outils autorisés par les scopes du jeton connecté.

Limites

Les requêtes effectuées avec le jeton d’un compte humain sont limitées à 1 200 par minute et par jeton. Les jetons renouvelés d’un compte d’agent partagent ce budget à l’échelle du compte. Les routes de facturation qui appellent Stripe partagent un budget plus strict de 60 par minute et par compte pour les appelants PAT : session de configuration, achat, changement de carte par défaut, suppression de carte et requêtes de liste des cartes non servies par le cache. La limitation ordinaire répond 429 rate_limited avec Retry-After en secondes ; attendez ce délai avant de réessayer. Les achats d’un compte d’agent ou effectués avec le PAT d’un compte humain partagent un plafond de 3 tentatives par période glissante de 24 heures et par compte. L’achat à l’inscription de l’agent compte ; les refus ou erreurs après réservation d’une tentative comptent aussi. Un achat depuis une session de navigateur humaine en est exempté. Un refus dû au plafond répond en HTTP 429 avec 4038 agent_purchase_capped et Retry-After. Les enregistrements peuvent durer de 15 secondes à 10 heures. GET /v1/account indique les limites d’admission actuelles du compte (max_active_jobs, max_daily_seconds).

Bac à sable

Il n’existe pas de bac à sable général pour la transcription : les appels /v1/ ordinaires utilisent des comptes réels, et les achats dépensent de l’argent réel. L’exception est la validation d’inscription : POST /v1/agent/accounts accepte dry_run: true, renvoie un identifiant d’inscription dry_ qui ne permet pas de récupérer un compte, et n’ouvre aucune session Stripe ni aucun compte.

Erreurs

Une erreur est un corps JSON qui porte un code numérique stable et un slug error, au statut HTTP indiqué ci-dessous. Les corps d’erreur /v1/ sont une projection figée : error, code, et un ensemble fixe de clés de détail. La structure des erreurs de /api n’est pas figée et peut en porter davantage. Les codes qu’un appelant automatisé doit gérer :

Statut Code Slug Signification
401 2000 unauthorized Jeton porteur manquant ou invalide
403 2022 pat_forbidden La route n’accepte aucun jeton
403 2023 pat_scope_missing Le jeton n’a pas le scope requis pour cet appel, ou la facturation est désactivée sur le compte
403 4021 pat_purchase_requires_app Aucune carte enregistrée n’a été nommée, ou le paiement a été refusé ; rien n’a été débité
403 4023 pat_purchase_requires_authentication L’émetteur de la carte demande une vérification que l’appelant ne peut pas effectuer ; la carte elle-même est valide
402 3001 insufficient_balance Solde insuffisant pour accepter la tâche
402 3002 card_declined La carte enregistrée a été refusée
402 3003 org_insufficient_balance La réserve de l’espace de travail qui finance ce téléversement est insuffisante
404 4000 not_found Tâche, téléversement ou ressource introuvable
409 4001 wrong_state La ressource n’est pas dans un état qui permette cela
422 1021 duration_out_of_range La durée déclarée est inférieure à 15 secondes ou supérieure à 10 heures
429 4038 agent_purchase_capped Le compte a atteint son plafond de tentatives d’achat avec un jeton ; attendez le délai Retry-After
429 5000 rate_limited Trop de requêtes ; attendez Retry-After
502 6001 provider_error Un service en amont a échoué
500 9000 internal_error Une erreur serveur inattendue

Le document OpenAPI nomme le code exact que chaque opération peut renvoyer, et le serveur MCP publie le catalogue complet sous forme de ressource hushscript://error-codes.

Commencer à transcrire avec 30 minutes gratuites

Prévisualisez jusqu'à 5 minutes avant de créer un compte, et un nouveau compte personnel bénéficie d'un aperçu gratuit de son premier téléversement dans l'application. La transcription complète nécessite un compte et des minutes ; les comptes personnels éligibles reçoivent 30 minutes gratuites une seule fois, après une vérification de carte ou avec un premier achat. Sans abonnement.

Commencer avec 30 minutes gratuites