Dub: translate and speak
POST /api/dubTranslate a text into a target language and speak the translation, in one paid call. Send POST /api/dub with the required fields text and targetLanguage and pay quoted per request from $0.14 over x402 or MPP (there is no free tier). It returns raw bytes, not JSON, with Content-Type audio/mpeg, audio/ogg, audio/aac, audio/flac, audio/wav or audio/pcm.
The translation runs on the /v1/chat/completions gateway tier and the speech on /api/tts (tier "standard", $0.140) or /api/tts-hd (tier "hd", $0.260); the price is the sum of the two. Answers the audio as raw bytes (mp3, opus, aac, flac, wav or pcm) with the translation, the detected source language and the models that served in the X-Dub-Translation header (base64 JSON); add json: 1 or format "json" for a JSON answer with the audio base64 in it. targetLanguage is a BCP-47 tag or an English name. The same ten standard voice names and named voices as the speech tiers. Text capped at 2000 chars, checked before any model call, and the cap applies to the translation. A failed step answers an error naming the step and is not charged. Model-backed.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
text | string | yes | Text to translate and speak (max 2000 chars; the cap also applies to the translation) Also accepted as content, str, string, input, body, data. |
targetLanguage | string | yes | Target language: a BCP-47 tag (es, pt-BR, zh-Hans, ja) or an English name (Spanish, Brazilian Portuguese) |
sourceLanguage | string | no | Optional source language, same forms; detected when omitted |
voice | string | no | Voice: alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer (default: alloy), or a named voice (george, sarah, adam, alice, bella, bill, brian, callum, charlie, chris, daniel, eric, harry, jessica, laura, liam, lily, matilda, river, roger, will) |
format | string | no | Audio format: mp3, opus, aac, flac, wav, pcm (default: mp3), or "json" for a JSON answer carrying the audio base64 as mp3 |
tier | string | no | "standard" (default, speech on /api/tts) or "hd" (speech on /api/tts-hd, priced at that tier's sum) |
json | boolean | no | true (or ?json=1) answers JSON with the audio base64 instead of raw bytes |
Example request
curl -i -X POST https://agent402.tools/api/dub \
-H "Content-Type: application/json" \
-d '{"text":"Hello from Agent402! Every tool is paid per call.","targetLanguage":"es","voice":"nova","format":"mp3","json":true}'
Without payment this returns HTTP 402 Payment Required with the exact price for dub; any x402 v2 or MPP client pays it and retries.
Example response
A 200 carries raw bytes, not JSON, with Content-Type audio/mpeg, audio/ogg, audio/aac, audio/flac, audio/wav or audio/pcm: the file itself.
From an MCP client
catalog.call {
"slug": "dub",
"params": {
"text": "Hello from Agent402! Every tool is paid per call.",
"targetLanguage": "es",
"voice": "nova",
"format": "mp3",
"json": true
}
}
The hosted connector at https://agent402.tools/mcp needs a payment for dub; the stdio package pays it from a wallet or from an AGENT402_CREDITS_KEY issued earlier. Local install: npx -y agent402-mcp.
Errors and behavior
textandtargetLanguageare required. An input the tool rejects returns an HTTP 4xx whose body carrieserror,tool,expected,requiredandexample, so the caller can correct it.- A paid call that ends in any status of 400 or above is not charged over x402, MPP or a prepaid credits key: settlement is canceled when the tool fails. The exception is a Tempo push credential, a transfer the buyer sent before the call: it settles before the tool runs, so if the tool then fails the payment is recorded as a refund owed to the paying wallet.
- Wallet-only: this tool runs a model, so it has no proof-of-work tier. A prepaid card-credits key issued earlier (
Authorization: Bearer a402_...) also pays it. - Model-backed: the answer is generated by a model, so the same input can produce a different result.
- Priced per request: the 402 quotes this body, between $0.14 and $0.26.
- A
GETorHEADto /api/dub returns the same 402 quote, so the price can be read without a body. - An
Idempotency-Keyheader does not replay this tool's answer: the replay cache holds JSON answers only, so a retried paid call runs and is charged again.
Paid call (JavaScript agent)
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const client = new x402Client();
client.setSpendControls?.({ maxAmountPerPayment: "$0.26" }); // refuse any quote above this tool's price
registerExactEvmScheme(client, { signer: privateKeyToAccount(KEY) });
const payFetch = wrapFetchWithPayment(fetch, client);
const res = await payFetch("https://agent402.tools/api/dub", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"text": "Hello from Agent402! Every tool is paid per call.",
"targetLanguage": "es",
"voice": "nova",
"format": "mp3",
"json": true
}),
});
Related tools
Text-to-speech
POST /api/ttsConvert text to speech with the eleven-v4-turbo model: returns audio (the base64-encoded file in the format asked.
Text-to-speech (HD)
POST /api/tts-hdConvert text to speech with the eleven-v4 model, the most expressive speech tier (inline audio tags such as [whispering].
Text-to-speech (lite)
POST /api/tts-liteConvert text to speech with Kokoro-82M, a fraction of the price of /api/tts.
Text-to-speech (OpenAI-compatible)
POST /v1/audio/speechOpenAI-compatible text-to-speech over x402 - point any OpenAI SDK's audio.speech.create() at base_url.
Speech-to-text (Pro)
POST /api/transcribe-proTranscribe audio to text with the gpt-transcribe model - the same model as /api/transcribe with a longer cap.