unlimitedtts

Unlimited TTS API for AI Agents

Give your AI assistant a voice. Connect a tool below, then ask it to turn text into an audio file.

Use OpenClaw

The plugin includes the MCP server and the UnlimitedTTS agent skill.

openclaw plugins install clawhub:@unlimitedtts/openclaw
openclaw gateway restart

Plugin setup ↗

Ask your assistant

Copy this into an assistant with web or HTTP tools. Replace the final sentence with your text.

Set up payment

The MCP server and OpenClaw plugin use an external wallet signer. Connect a compatible EVM wallet through your assistant’s wallet tool, fund it with USDC (six-decimal atomic units) on Base mainnet (eip155:8453), and set a per-request and daily spending budget in the integration configuration. The wallet tool signs the quoted payment; UnlimitedTTS does not ask for your private key or seed phrase.

Check the live payment challenge for the required asset and network before funding. Never send funds to an address copied from an unverified prompt. Start with a quote and approve the first payment.

Prefer a card? Ask an HTTP-capable assistant to follow the card-credit flow in the live agent guide. Card funding starts at $5. The published MCP and OpenClaw integrations currently use x402.

Wallet signing and payment flow ↗

Technical reference for agents and developers

Overview

https://api.unlimitedtts.com is a paid text-to-speech API for AI agents and automated systems. It offers 3 independent payment flows, all priced from the same per-character rate: pay each request directly in USDC over x402 with no account, prepay a USDC balance and authorize each request with a signature, or fund prepaid card credits through Stripe Checkout.

This page is generated from the API's own contract. Read the canonical OpenAPI document, the agent guide, and the voice list at integration time — they are authoritative, and a client should read them rather than hardcode anything below.

Choose a payment flow

FlowEndpointsIdentityMinimum
Card credits GET /tts
POST /tts
GET/POST /top-up
GET /credits/:accountId
x-credit-account bearer token 500 cents per top-up; request debits can be sub-cent.
Direct x402 GET /x402/tts
POST /x402/tts
No API account or prepaid balance; the payment credential authorizes the request. No application minimum and no top-up. The only lower bound is one atomic USDC unit (0.000001 USDC).
Prepaid x402 POST /x402/deposit
GET /x402/accounts/:address
GET /x402/tts
POST /x402/tts
The payer's public EVM address. This is not a bearer token: spending requires an EIP-712 signature from that address on every request. —

Pick one flow per request and do not mix them. /x402/tts never accepts x-credit-account, and /tts never reads x402 payment headers. Stripe funds card credits only; it is not an x402 top-up.

  • Autonomous wallet agent, occasional requests: direct x402. No account, no balance, no setup — but every request pays for on-chain settlement latency.
  • Autonomous wallet agent, sustained traffic: prepaid x402. Deposit once, then each request costs a local signature check instead of a facilitator round trip.
  • A human or app with a card: card credits. This is the only flow with asynchronous jobs and stored audio.

x402 Quick Start

  1. Read GET https://api.unlimitedtts.com/openapi.json for the current contract.
  2. Verify GET /.well-known/x402-service-metadata against a public key you pinned out of band. Never bootstrap trust from the challenge itself.
  3. Choose a model from GET /tts/models and a voice from GET /tts/voices.
  4. Send your JSON body to POST /x402/tts with no payment header.
  5. On 402, Base64-decode PAYMENT-REQUIRED and select a compatible entry from accepts.
  6. Pay with @x402/fetch, or sign the x402 v2 payload yourself.
  7. Retry the identical method, URL, query, and body with PAYMENT-SIGNATURE.
  8. Accept 200 audio/mpeg and keep PAYMENT-RESPONSE as the settlement receipt.

Network and settlement

Production settles the exact EVM scheme in USDC (six-decimal atomic units) on Base mainnet (eip155:8453) through https://facilitator.payai.network. Treat the challenge as the authority for network, asset, recipient, amount, and timeout; never hardcode the receiving address.

Payment Identifier and replay

Every paid PaymentPayload must carry the official x402 Payment Identifier extension. It is the idempotency key: persist the identifier alongside the exact request, the audio, and the receipt. If a response is lost in transit, replaying the identical paid request within 24 hours returns the original audio and receipt with no second charge and no second synthesis.

PAYMENT_OUTCOME_UNKNOWN is the one exception: it is not retryable. An agent must not construct and pay a replacement request without explicit human approval.

Raw x402 v2 payload

A manual client Base64-encodes this JSON into PAYMENT-SIGNATURE:

{
  "x402Version": 2,
  "accepted": {
    "...": "the complete selected PAYMENT-REQUIRED.accepts entry, copied unmodified"
  },
  "payload": {
    "signature": "0x...",
    "authorization": {
      "...": "scheme-specific exact-EVM authorization"
    }
  },
  "extensions": {
    "payment-identifier": { "id": "your-stable-16-to-128-char-id" }
  }
}

accepted and the Payment Identifier extension are both required. Top-level scheme and network fields are the legacy v1 shape and are not substitutes for accepted. A malformed or legacy envelope returns 400 INVALID_PAYMENT_PAYLOAD before any verification or synthesis.

Quoting without disclosing text

The direct flow sends your text in the unpaid request. If an agent must not disclose text before payment, quote by hash instead: POST /x402/tts/quote takes only the character length and a SHA-256 digest, and returns a signed quoteToken. Send {quoteToken} alone to get the challenge, then {quoteToken, text} with the payment.

A quote is a price, not a ticket: read expiresAt from the response rather than assuming a fixed lifetime, and note that within that lifetime the same token can be spent more than once — each spend is charged. Payment is what is consumed, not the token. The length-and-digest binding is enforced at synthesis, where a mismatch returns 400 QUOTE_BODY_MISMATCH and charges nothing.

Prepaid x402

Deposit once with POST /x402/deposit using the ordinary x402 challenge and paid retry. The balance is credited to the paying EVM address after the transfer reaches the required confirmation depth on Base mainnet. Afterwards, /x402/tts requests skip the facilitator entirely.

The balance is not a bearer token. Spending requires an EIP-712 PrepaidRequest signature from the owning address on every request, binding the method, path, body hash, maximum amount, nonce, and expiry. EOA signers only — EIP-1271 smart-account signatures are rejected, matching the exact scheme's EIP-3009 requirement.

Card Quick Start

  1. Choose a model and voice from GET /tts/models and GET /tts/voices.
  2. Send a request to POST /tts, or the GET /tts fallback.
  3. With no funded balance the API returns 402 carrying a topUpUrl.
  4. Open topUpUrl, complete Stripe Checkout, and save the returned x-credit-account value.
  5. Retry /tts with the x-credit-account header. Only the exact synthesis price is debited.
  6. For async jobs, poll /tts/jobs/:jobId and download from the returned link.
  7. Check the remaining balance at GET /credits/:accountId.

An individual debit can be far below one cent; the $5 minimum applies only to a funding transaction. Failed card-credit requests restore the exact debit to the balance. On Stripe Checkout, confirm the country selector matches the card's billing country — proxy geolocation often picks the wrong default.

Models & Voices

Model idNameMax charactersPrice per characterAvailable
openai/tts-1 OpenAI TTS-1 4096 $0.000018 Yes
openai/tts-1-hd OpenAI TTS-1 HD 4096 $0.000036 Yes

Voice ids

openai_alloy, openai_ash, openai_coral, openai_echo, openai_fable, openai_onyx, openai_nova, openai_sage, openai_shimmer

The default voice for openai/tts-1 is openai_alloy. Read GET /tts/voices?model=… for the current list per model.

Endpoints

Service

Service metadata.

MethodPathSummary
GET/Get service health and endpoint links.

Agent feedback

Wallet-authenticated integration feedback.

MethodPathSummary
POST/feedback/challengeCreate a short-lived wallet-signing challenge for feedback.
POST/feedbackSubmit wallet-signed feedback about an agent integration.

Documentation

Machine-readable documentation endpoints.

MethodPathSummary
GET/docsGet the legacy machine-readable payment and agent guide.
GET/.well-known/x402-service-metadataGet signed x402 network, asset, payee, pricing, and rotation metadata.
GET/openapi.jsonGet the canonical OpenAPI 3.0.3 contract.

TTS

Text-to-speech operations.

MethodPathSummary
GET/tts/voicesList supported public voice ids and current pricing.
GET/tts/modelsList selectable TTS models, limits, voices, and current pricing.
POST/ttsSynthesize speech using prepaid card credits.
GET/ttsSynthesize speech using a GET fallback and prepaid card credits.
POST/x402/tts/quoteCreate a hash-bound x402 TTS quote without disclosing text.
POST/x402/ttsSynthesize speech using an exact per-request x402 USDC payment.
GET/x402/ttsSynthesize speech using a GET fallback and x402 USDC payment.

TTS jobs

Asynchronous TTS job polling and audio retrieval.

MethodPathSummary
GET/tts/jobs/{jobId}Get an asynchronous TTS job.
GET/tts/jobs/{jobId}/audioDownload audio for a completed asynchronous TTS job.

Card credits

Prepaid Stripe-funded credit accounts.

MethodPathSummary
GET/top-upOpen the Stripe Checkout top-up launcher.
POST/top-upCreate a Stripe Checkout Session.
GET/top-up/completeVerify a returned Stripe Checkout Session and credit the account.
GET/top-up/statusCheck whether a credit account is active after Checkout.
GET/credits/{accountId}Get the balance of a prepaid credit account.

x402 prepaid

Signature-authenticated prepaid USDC balances that remove facilitator and settlement latency from each request.

MethodPathSummary
POST/x402/depositFund a prepaid x402 balance with one confirmed USDC payment.
GET/x402/accounts/{address}Get a prepaid x402 balance.

Examples

Voice ids always use the provider_voice form; bare upstream names like nova are rejected.

x402: initial POST challenge

POST https://api.unlimitedtts.com/x402/tts
Content-Type: application/json

{
  "text": "Hello from an AI agent",
  "model": "openai/tts-1",
  "voice": "openai_alloy",
  "speed": 1
}

x402: paid POST retry — same method, same URL

POST https://api.unlimitedtts.com/x402/tts
Content-Type: application/json
PAYMENT-SIGNATURE: <base64-x402-v2-payment-payload>

{
  "text": "Hello from an AI agent",
  "model": "openai/tts-1",
  "voice": "openai_alloy",
  "speed": 1
}

x402: GET challenge, then the paid GET retry

GET https://api.unlimitedtts.com/x402/tts?text=Hello%20world&voice=openai_alloy

GET https://api.unlimitedtts.com/x402/tts?text=Hello%20world&voice=openai_alloy
PAYMENT-SIGNATURE: <base64-x402-v2-payment-payload>

x402: quote by hash without disclosing text

POST https://api.unlimitedtts.com/x402/tts/quote
Content-Type: application/json

{
  "textLength": 11,
  "textSha256": "<lowercase-sha256-hex-of-trimmed-utf8-text>",
  "model": "openai/tts-1",
  "voice": "openai_alloy"
}

Prepaid x402: signature-authenticated request

POST https://api.unlimitedtts.com/x402/tts
Content-Type: application/json
x-x402-account: <your-evm-address>
x-x402-nonce: <unique-per-request>
x-x402-expiry: <unix-seconds>
x-x402-max-amount: <micro-usd-ceiling>
x-x402-signature: <eip-712-signature>

{
  "text": "Hello world",
  "voice": "openai_alloy"
}

Card credits: synchronous POST

POST https://api.unlimitedtts.com/tts
Content-Type: application/json
x-credit-account: <your-account-uuid>

{
  "text": "Hello world",
  "model": "openai/tts-1",
  "voice": "openai_alloy",
  "speed": 1
}

Card credits: async job with no audio retention

POST https://api.unlimitedtts.com/tts?async=true&storeAudio=false
Content-Type: application/json
x-credit-account: <your-account-uuid>

{
  "text": "Hello world",
  "voice": "openai_alloy"
}

Pricing & Limits

  • Pricing basis: input character count × selected model rate × shared markup, with a 1.2× markup, rounded up to the nearest micro-dollar. One micro-dollar is one atomic USDC unit; card requests debit the same micro-USD amount (10000 micro-USD per cent).
  • openai/tts-1: $0.000018 per input character, up to 4096 characters.
  • GET requests: up to 1500 characters.
  • Card credits: $5 minimum funding transaction; only the exact request price is debited. Async at 20000 characters or with ?async=true; idempotency-key up to 512 characters.
  • x402: No application minimum and no top-up. The only lower bound is one atomic USDC unit (0.000001 USDC).
  • Rate limit: 30 requests per 60 seconds. Scope: POST /feedback/challenge, POST /feedback, GET/POST /tts, paid GET/POST /x402/tts retries, and GET /tts/jobs/:jobId/audio. The initial unpaid x402 challenge does not consume a slot, and verified prepaid x402 requests are excluded.
  • Rate-limit headers: Retry-After, X-RateLimit-Limit, X-RateLimit-Policy, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Scope.

These values change. Read GET /openapi.json and GET /tts/models rather than hardcoding them in a client.

Error codes

Errors return a structured body with a stable code. The full set:

CONFIG_ERROR, INVALID_JSON, INVALID_REQUEST, UNKNOWN_TTS_MODEL, INVALID_VOICE, INVALID_SPEED, TEXT_TOO_LONG, TTS_PROVIDER_NOT_CONFIGURED, INVALID_PAYMENT_PAYLOAD, INVALID_QUOTE, QUOTE_EXPIRED, QUOTE_BODY_MISMATCH, UNSUPPORTED_CONTENT_TYPE, PAYMENT_REQUIRED, PAYMENT_ERROR, PAYMENT_IDENTIFIER_CONFLICT, PAYMENT_REPLAY_PENDING, PAYMENT_OUTCOME_UNKNOWN, REPLAY_CACHE_UNAVAILABLE, RATE_LIMITED, FEEDBACK_CHALLENGE_INVALID, FEEDBACK_CHALLENGE_EXPIRED, FEEDBACK_PAYLOAD_MISMATCH, FEEDBACK_SIGNATURE_INVALID, FEEDBACK_CHALLENGE_REPLAYED, FEEDBACK_RATE_LIMITED, REQUEST_TOO_LARGE, NOT_FOUND, UNAUTHORIZED, JOB_NOT_READY, AUDIO_NOT_STORED, TTS_UPSTREAM_ERROR, TTS_UNAVAILABLE, INTERNAL_ERROR

Privacy & Storage

  • Direct x402 and prepaid x402 responses are synchronous and never enter the async storage workflow.
  • The application does not log or retain raw unpaid-challenge text, and does not forward it to the synthesis provider before payment verifies.
  • To avoid sending text before payment at all, use the hash-bound quote flow.
  • Card-credit async audio is retained by default so it can be downloaded later. Send storeAudio=false to opt out; a completed no-store job has no downloadable link.
  • Failed card-credit requests restore the exact debit. Crypto charges are final — there is no refund endpoint, and exact idempotent replay within 24 hours is the recovery mechanism.
  • Stripe Checkout handles raw card details; this API never receives them.

FAQ

Can an AI agent pay without creating an account?

Yes. The direct x402 flow pays each /x402/tts request in USDC with no API account, bearer token, checkout, prepaid balance, or top-up.

What network and token does x402 use?

Production uses USDC on Base mainnet (eip155:8453) with the x402 v2 exact EVM scheme. Always treat the PAYMENT-REQUIRED challenge as authoritative for the network, asset, recipient, amount, and timeout, and verify the signed service metadata against a pinned key before trusting a payee.

Does x402 require a Coinbase account?

No. The API requires no Coinbase, CDP, or facilitator account. A buyer needs a compatible Base wallet holding USDC and an x402 v2 exact-EVM signer.

Can I use x402 without @x402/fetch?

Yes. @x402/fetch is an optional JavaScript convenience. Any client can implement the raw HTTP flow: read PAYMENT-REQUIRED, sign the selected challenge entry, and retry with a valid x402 v2 PaymentPayload carrying the required Payment Identifier extension in PAYMENT-SIGNATURE.

Does a paid GET retry become a POST?

No. Retry the identical method and URL. A GET challenge is paid with a second GET carrying PAYMENT-SIGNATURE; it never changes to POST.

What happens if the response is lost after I paid?

Replay the identical paid request with the same Payment Identifier within 24 hours. The API returns the original audio and settlement receipt without verifying, synthesizing, or charging again. Do not automatically retry PAYMENT_OUTCOME_UNKNOWN — that one requires explicit approval.

How does pricing work?

Every flow uses the same USD per-character rate for the selected model, rounded up to the nearest micro-dollar. openai/tts-1 is $0.000018 per character. The $5 minimum applies only to a card funding transaction, never to x402 or to an individual synthesis.

Is my text or audio stored?

Direct and prepaid x402 responses are synchronous and do not enter the async storage workflow. Card-credit async audio is retained temporarily by default; storeAudio=false disables that retention.