Turn text into natural-sounding speech across 31 languages — entire documents, articles, and books. Submit a job, get notified, download one stitched audio file.
# Submit a narration job — one call, any length curl -X POST https://api.narrateai.mossforge.dev/v1/tts/async \ -H "Authorization: Bearer nai_your_key" \ -H "Content-Type: application/json" \ -d '{ "text": "Bonjour, comment puis-je vous aider?", "lang": "fr", "voice": "michael" }' # → job ID back immediately { "job_id": "888d45c5-...", "status": "processing", "estimated_minutes": 0.5 } # Poll for completion curl https://api.narrateai.mossforge.dev/v1/tts/async/888d45c5-... \ -H "Authorization: Bearer nai_your_key" # → ready-to-play audio URL when done { "status": "complete", "url": "https://..." }
Why NarrateAI
01
English, French, Japanese, Arabic, Hindi, and 26 more — all at the same price. No language surcharges, no separate models. One API, one key, everywhere.
02
10 natural voice styles with inline expression tags. Add a <laugh>, <sigh>, or <breath> directly in your text for human-sounding output without post-processing.
03
Synthesise entire documents, articles, and books — not just short snippets. Submit a job, get notified when it's ready, download one stitched audio file. No babysitting required.
04
Pay per character, not per minute. Track exactly how much you've used at any time. Monthly quotas enforced per key — you'll never wake up to an unexpected charge.
05
Two endpoints. Bearer token auth. JSON in, audio URL out. No SDKs to install, no webhooks to configure for basic usage. Works with any HTTP client in any language.
06
125,000 characters on signup — roughly 1.5 hours of audio — then 10,000 characters every month, free forever. Enough to build something real before spending a penny.
Pricing
Dev
$0
10k chars / month
+ 125k bonus on signup
Hobby
$19/mo
760k chars / month
Creator
$49/mo
2.45M chars / month
Studio
$99/mo
6.6M chars / month
Pro
$149/mo
14.9M chars / month
Credit top-up packs — buy extra chars any time
| Plan | Top-ups allowed | 250k pack | 500k pack | Rate / 1k chars |
|---|---|---|---|---|
| Dev | 1 / month | $7.50 | $15.00 | $0.030 |
| Hobby | 2 / month | $6.75 | $13.50 | $0.027 |
| Creator | Unlimited | $5.50 | $11.00 | $0.022 |
| Studio | Unlimited | $4.25 | $8.50 | $0.017 |
| Pro | Unlimited | $3.00 | $6.00 | $0.012 |
Top-up credits never expire. All plans: credit packs are always more expensive per character than your subscription rate — upgrading your plan is always the better value for consistent usage.
Need more? Get in touch for volume pricing.
Get started
No credit card. No lengthy signup. Enter your name and email and your key arrives immediately.
Free tier: 125,000 characters on signup, then 10,000/month forever. No spam — your email is only used to deliver your key and essential account notices.
API Reference
Submit text for async processing. Text is split into parallel chunks and stitched into one WAV file. Returns immediately with a job ID — poll /v1/tts/async/{job_id} for status. Max 100,000 characters per job.
Request body
| Parameter | Type | Description |
|---|---|---|
| text | string required | Text to narrate. Max 100,000 characters. |
| lang | string optional | ISO 639-1 language code. Default: en. See supported languages below. |
| voice | string optional | Voice name or ID (e.g. michael or m1). Default: michael. |
| speed | float optional | Speech speed. Default: 1.05. |
| steps | integer optional | Inference steps. Default: 8. |
Response 202 Accepted
{
"job_id": "888d45c5-1234-...",
"status": "processing",
"total_chunks": 4,
"total_chars": 1240,
"estimated_seconds": 15,
"poll_url": "/v1/tts/async/888d45c5-1234-..."
}
Check the status of a narration job. Only the account that created the job may poll it. When status is complete, a presigned S3 URL is included (valid 1 hour). Audio files are purged after 7 days.
Response — processing
{
"job_id": "888d45c5-...",
"status": "processing",
"total_chunks": 4,
"completed_chunks": 2,
"failed_chunks": 0,
"total_chars": 1240,
"created_at": 1748000000,
"progress_percent": 50.0
}
Response — complete
{
"job_id": "888d45c5-...",
"status": "complete",
"total_chunks": 4,
"completed_chunks": 4,
"failed_chunks": 0,
"total_chars": 1240,
"created_at": 1748000000,
"progress_percent": 100.0,
"url": "https://s3.amazonaws.com/...",
"duration_seconds": 184.3
}
Response — failed
{
"job_id": "888d45c5-...",
"status": "failed",
"progress_percent": 75.0,
"error": "Job failed"
}
Create a new account. No authentication required. Your API key is emailed immediately. The free_email tier starts with 0 credits — add a payment method via /v1/billing/activate to unlock 125,000 bonus characters.
Request body
| Parameter | Type | Description |
|---|---|---|
| name | string required | Your name. Max 100 characters. |
| string required | Your email address. Used only to deliver your key and essential account notices. |
Response
{ "message": "Check your email for your API key." }
Monthly usage summary — characters used, quota remaining, daily breakdown, language breakdown. Append ?month=YYYY-MM to query a previous month. Requires authentication.
Create a Stripe Checkout session to subscribe to a plan or add a card. Requires authentication. Redirect the user to the returned url. On success, Stripe redirects to /billing/return?session_id=….
Request body
| Parameter | Type | Description |
|---|---|---|
| plan | string required | free_card (setup only, no charge) · hobby · creator · studio · pro |
Response
{ "sessionId": "cs_live_...", "url": "https://checkout.stripe.com/..." }
Create a one-time Stripe Checkout session to buy additional characters. Requires authentication and an existing billing account (complete a checkout first). Top-up credits never expire.
Request body
| Parameter | Type | Description |
|---|---|---|
| tier | string required | Your current plan tier: dev · hobby · creator · studio · pro |
| pack | string required | Pack size: 250k · 500k |
Response
{ "sessionId": "cs_live_...", "url": "https://checkout.stripe.com/..." }
Create a Stripe Customer Portal session for managing subscriptions, payment methods, and invoices. Requires authentication and an existing billing account. Returns to /account on exit.
Response
{ "url": "https://billing.stripe.com/..." }
Look up a Stripe Checkout session after redirect — use this on your return page to confirm payment status. Requires authentication.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| session_id | string required | The session_id from the Stripe redirect query string. |
Response
{
"id": "cs_live_...",
"status": "complete",
"paymentStatus": "paid",
"customerEmail": "ada@example.com"
}
Linked from the welcome email for free_email accounts. Redirects to a Stripe Checkout setup session to add a payment method and unlock 125,000 bonus characters (no charge). No authentication required — verified by the token in the link.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| token | string required | 64-character activation token from the welcome email link. |
Response
# 302 redirect → Stripe Checkout setup session URL
| Code | Language | Code | Language | Code | Language |
|---|---|---|---|---|---|
| en | English | fr | French | de | German |
| es | Spanish | pt | Portuguese | it | Italian |
| ja | Japanese | ko | Korean | ar | Arabic |
| hi | Hindi | ru | Russian | nl | Dutch |
| pl | Polish | sv | Swedish | tr | Turkish |
| uk | Ukrainian | vi | Vietnamese | id | Indonesian |
| da | Danish | fi | Finnish | bg | Bulgarian |
| cs | Czech | el | Greek | et | Estonian |
| hr | Croatian | hu | Hungarian | lt | Lithuanian |
| lv | Latvian | ro | Romanian | sk | Slovak |
| sl | Slovenian |
Pass either the name or the ID — both are accepted.
| Name | ID | Character |
|---|---|---|
| michael | m1 | Male, natural — default |
| jake | m2 | Male, natural |
| christian | m3 | Male, warm |
| alex | m4 | Male, expressive |
| richard | m5 | Male, British accent |
| emily | f1 | Female, natural |
| hannah | f2 | Female, warm |
| jessica | f3 | Female, expressive |
| alexis | f4 | Female, assertive |
| cassandra | f5 | Female, British accent |
| Status | Meaning |
|---|---|
| 400 | Missing or invalid parameters |
| 401 | Missing or invalid API key |
| 402 | No credits remaining, or account suspended — top up, upgrade, or update payment method |
| 403 | Forbidden — job belongs to a different account |
| 404 | Job not found |
| 429 | Per-minute rate limit exceeded for your tier |
| 500 | Internal error — retry with exponential backoff |
Rate limits by tier
| Tier | Requests / minute |
|---|---|
| dev | 10 |
| hobby | 20 |
| creator | 60 |
| studio | 100 |
| pro | 120 |