Conversion d’article en parole (ATS)
Convertissez un article complet en une version audio narrée et une transcription, transmises de manière asynchrone à votre URL de rappel.
Le point de terminaison ATS (Article to Speech) accepte le texte d’un article et génère une narration au format MP3 ainsi qu’un fichier de transcription synchronisée (.srt). La génération s’effectue de manière asynchrone : la requête renvoie immédiatement le code 202 Accepted » et les fichiers finaux sont transmis à l’ callbackURL que vous avez fournie. Il s’agit du même service que celui utilisé par le plugin WordPress ATS.
N’attendez pas la réponse HTTP pour votre fichier audio. Le point de terminaison répond immédiatement par un code 202 et envoie le résultat via une requête POST à votre callbackURL une fois la génération terminée.
Authentification
Incluez la clé API de votre entreprise en tant que jeton Bearer dans l’en-tête Authorization.
Authorization: Bearer your_api_key
Corps de la requête
Envoyez un corps JSON contenant le texte brut de l’article et un objet postData décrivant la requête.
| Paramètre | Obligatoire | Type | Description |
|---|---|---|---|
| text | requis | chaîne | Le texte intégral de l’article à convertir en parole. |
| postData | requis | objet | Métadonnées de la demande. Voir les champs ci-dessous. |
Objet postData
| Champ | Obligatoire | Type | Par défaut | Description |
|---|---|---|---|---|
| name | requis | chaîne | — | Titre de l’article. Utilisé comme titre de la demande de génération audio. |
| articleId | requis | chaîne | — | Votre identifiant unique pour l’article. Il sert de clé d’idempotence (voir la section Idempotence ci-dessous) et est renvoyé dans le rappel. |
| voiceId | requis | chaîne | — | La voix à utiliser pour la narration. Utilisez un identifiant provenant du liste des voix. |
| callbackURL | requis | chaîne (URL) | — | URL HTTPS vers laquelle Moknah enverra (via une requête POST) les URL de l’audio et de la transcription finalisés. La valeur la plus récente est enregistrée pour l’entreprise. |
| preprocessType | facultatif | chaîne | "0" | Mode de préparation du texte, transmis sous forme de chaîne de caractères. Utilisez « 0 » pour aucun traitement (narration mot pour mot) ou « 2 » pour un prétraitement par IA (narration plus propre ; double le coût en caractères). Il doit s’agir d’une chaîne JSON ; un nombre brut tel que 0 ou 2 est rejeté lors du traitement du texte. |
| regenerate | facultatif | booléen | false | Lorsque cette option est activée, elle force une nouvelle génération, même si cet articleId a déjà été généré. |
Exemple de demande
curl -X POST "https://api.moknah.io/process-text" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
"postData": {
"name": "AI is evolving fast",
"articleId": "post-123",
"voiceId": "12",
"callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
"preprocessType": "0",
"regenerate": false
}
}'
import requests
response = requests.post(
"https://api.moknah.io/process-text",
headers={
"Authorization": "Bearer your_api_key",
"Content-Type": "application/json"
},
json={
"text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
"postData": {
"name": "AI is evolving fast",
"articleId": "post-123",
"voiceId": "12",
"callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
"preprocessType": "0",
"regenerate": False
}
}
)
# 202 Accepted — the audio is delivered to your callbackURL
print(response.status_code, response.text)
const response = await fetch(
'https://api.moknah.io/process-text',
{
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.',
postData: {
name: 'AI is evolving fast',
articleId: 'post-123',
voiceId: '12',
callbackURL: 'https://your-site.com/wp-json/ats/v1/callback',
preprocessType: '0',
regenerate: false
}
})
}
);
// 202 Accepted — result arrives at your callbackURL
Réponse immédiate
Si la requête est acceptée, le point de terminaison répond immédiatement :
Processing started. Results will be sent to the callback URL.
Charge utile de rappel
Une fois la génération terminée, Moknah envoie une requête POST à votre callbackURL avec le corps JSON suivant :
{
"articleId": "post-123",
"response": {
"audioFile": "https://api-storage.moknah.io/.../******.mp3",
"srtFile": "https://api-storage.moknah.io/.../******.srt",
"signature": "<hmac-sha256-hex>"
}
}
| Champ | Description |
|---|---|
| articleId | Le même articleId que celui que vous avez envoyé dans la requête. |
| response.audioFile | URL publique de la narration MP3 générée, ou null si la génération a échoué. |
| response.srtFile | URL publique du fichier de transcription synchronisée (.srt), ou null si la génération a échoué. |
| response.signature | Signature HMAC-SHA256 que vous pouvez utiliser pour vérifier l’authenticité de la charge utile (voir ci-dessous). |
Un rappel est également envoyé lorsque la génération ne produit aucun fichier audio. Dans ce cas, `response.audioFile` et `response.srtFile` sont nuls (la signature couvre tout de même `articleId|null|null`). Considérez tout rappel dont le champ `audioFile` ou `srtFile` est nul comme un échec : ne marquez pas l’article comme terminé et renvoyez-le en définissant `regenerate` sur `true`.
Vérification de la signature
La signature est un HMAC-SHA256 (hexadécimal) de la chaîne articleId|audioFile|srtFile , généré à l’aide de l’empreinte hexadécimale SHA-256 de votre clé API. Recalculez-la de votre côté et comparez-la pour confirmer que le rappel provient bien de Moknah et n’a pas été altéré.
import crypto from 'crypto';
const keyHash = crypto.createHash('sha256').update(API_KEY).digest('hex');
const payload = `${articleId}|${audioFile}|${srtFile}`;
const expected = crypto.createHmac('sha256', keyHash).update(payload).digest('hex');
const isValid = expected === signature;
import hashlib, hmac
key_hash = hashlib.sha256(API_KEY.encode()).hexdigest()
payload = f"{article_id}|{audio_file}|{srt_file}"
expected = hmac.new(key_hash.encode(), payload.encode(), hashlib.sha256).hexdigest()
is_valid = hmac.compare_digest(expected, signature)
Idempotence et régénération
- Les requêtes sont identifiées par l’articleId pour chaque entreprise. Un nouvel articleId déclenche une nouvelle génération.
- Si un article est en cours de génération, les demandes répétées sont rejetées avec le code 409 ALREADY_PROCESSING.
- Si un article a déjà été généré et que le paramètre « regenerate » est défini sur « false », l’audio existant est renvoyé à votre callbackURL sans nouvelle génération (et sans nouvelle facturation).
- Définissez regenerate sur true pour forcer une nouvelle génération pour un articleId existant.
- Si une tentative précédente a échoué, le résultat stocké pour cet articleId peut être vide. Une requête ultérieure avec regenerate défini sur false risque alors de renvoyer ce résultat vide ; pour y remédier, renvoyez la requête avec regenerate défini sur true (ou utilisez un nouvel articleId).
Concurrence et débit
La narration de chaque article s’effectue en générant ses phrases en parallèle via le fournisseur de synthèse vocale, lequel applique une limite de simultanéité partagée à l’échelle de votre compte. Soumettre plusieurs articles simultanément risque de dépasser cette limite et d’entraîner l’échec de certaines phrases, compromettant ainsi la génération des articles dans leur intégralité.
- Lors de la rédaction d’une page en plusieurs parties, ne traitez que quelques articles à la fois (environ trois) au lieu de les soumettre tous simultanément.
- Relancez le traitement de tout article ayant échoué en définissant `regenerate` sur `true` ; les articles déjà générés sont mis en cache et n’ont pas besoin d’être renvoyés.
- Le point de terminaison /process-text est également soumis à une limitation de débit par client ; les pics dépassant cette limite entraînent une erreur « 429 Too Many Requests » (Trop de requêtes), veillez donc à espacer vos envois ou à les regrouper par lots.
Facturation
Le coût en caractères est calculé en multipliant le nombre de caractères du text par le facteur de prétraitement (1 par défaut, 2 lorsque preprocessType est égal à 2). Les crédits ne sont déduits que lorsque la génération est effectivement effectuée. La nouvelle livraison d’un article déjà généré est gratuite ; en cas d’échec de la génération ou de la livraison, les crédits déduits sont automatiquement remboursés.
Erreurs
| Statut | Code | Description |
|---|---|---|
401 |
AUTH_FAILED | En-tête Authorization manquant ou clé API invalide. |
422 |
VALIDATION_ERROR | Texte manquant, ou champs postData invalides ou manquants. |
400 |
INVALID_VOICE_ID | L’identifiant de voix fourni n’existe pas. |
409 |
ALREADY_PROCESSING | Cet article est déjà en cours de génération. Réessayez une fois l’opération terminée. |
422 |
PROCESSING_ERROR | La génération a échoué. Les crédits déduits sont remboursés. |
422 |
REFUND_FAILED | Le traitement a échoué et le remboursement automatique n’a pas abouti. Contactez api@moknah.io. |
Pour toute question ou tout problème concernant l’API, contactez-nous à l’adresse api@moknah.io.