Afterwords Cloud API
Hosted voice-cloning TTS API. Clone your voice once on a Mac using the local
afterwords tool,
upload it to your account, and synthesize speech from anywhere via REST API.
No Apple Silicon required at call time.
Authentication
All protected endpoints require a Bearer token. Pass your API key (prefix aw_) in every request.
Authorization: Bearer aw_<your-key> Async synthesis
POST /v1/synthesize returns 202 Accepted with a job_id. Poll GET /v1/jobs/{job_id} until status is "ready", then download audio from GET /v1/jobs/{job_id}/audio.
Cache hits return 200 with audio bytes directly — check for X-Cache: HIT.
Rate limits
| Tier | Requests/min | Characters/mo |
|---|---|---|
| Free | 5 | 10,000 |
| Hobby ($5/mo) | 20 | 50,000 |
| Pro ($20/mo) | 60 | Unlimited (metered) |
Error codes
| Status | Code | Description |
|---|---|---|
| 400 | bad_request | Missing or invalid request fields |
| 401 | unauthorized | Missing or invalid API key |
| 404 | not_found | Voice, job, or resource not found |
| 422 | unprocessable | Invalid WAV file or duration out of range (5–60 s) |
| 429 | rate_limited | Request rate exceeded for your tier |
| 500 | internal_error | Inference or server error |
All error responses include a JSON body: {"error": "message"}
SDK
A TypeScript SDK is available for Node.js and browser environments.
npm install afterwords-cloud Local import (monorepo): import { AfterwordsClient } from "../../sdk/src/index.ts"
Status
GET /v1/health Health check
Signup
POST /v1/checkout Create Stripe Checkout session
GET /v1/checkout/success Poll for API key after payment
Voices
POST /v1/voices Upload a cloned voice
GET /v1/voices List voices
GET /v1/voices/{voice_id} Get voice
DELETE /v1/voices/{voice_id} Delete voice
Synthesis
POST /v1/synthesize Submit synthesis job
Enqueue a TTS synthesis job. Returns 202 Accepted with a job_id for async polling. Cache hits return 200 with audio bytes directly (X-Cache: HIT).
Request body (JSON)
| Field | Type | Description |
|---|---|---|
| voice_idrequired | string (uuid) | ID of the voice to synthesize with |
| textrequired | string | Text to synthesize |
| lang | string | BCP-47 language code, default en |
| backend | enum | Override voice's default backend |
curl -X POST https://afterwords-api.adrianwedd.workers.dev/v1/synthesize \
-H "Authorization: Bearer aw_<your-key>" \
-H "Content-Type: application/json" \
-d '{"voice_id":"550e8400-...","text":"Hello, this is my cloned voice."}' // 202 Accepted (cache miss)
{
"job_id": "7c9e6679-...",
"status": "pending"
}
"job_id": "7c9e6679-...",
"status": "pending"
}
202 job accepted 200 cache hit (WAV) 400 missing fields 401 unauthorized 404 voice not found 500 server error
GET /v1/jobs/{job_id} Get job status
GET /v1/jobs/{job_id}/audio Download synthesized audio
Usage & Keys
GET /v1/usage Get usage for current billing period
DELETE /v1/keys/me Revoke current API key
Base URL: https://afterwords-api.adrianwedd.workers.dev
· OpenAPI 3.0.3
· afterwords cloud