Authentication and errors
Authenticate once. Retry without charging twice.
VowelMarks API keys are server-side secrets. This guide covers Bearer authentication, organization-wide limits, idempotent retries, response headers, and the error envelope shared by every v1 endpoint.
Updated September 24, 2026 · API version 1
Send a server-side Bearer key
Test keys begin with vm_test_ and live keys begin with vm_live_. Send the complete key in the Authorization header. Never embed either key in browser JavaScript, a mobile application bundle, a public repository, logs, analytics, or a URL.
Authorization: Bearer vm_test_…
Content-Type: application/jsonDeveloper generation routes do not allow browser CORS. Call the API from infrastructure you control, then return only the result your client needs.
Use idempotency for safe retries
Synchronous POST endpoints accept an optional Idempotency-Key containing 8–128 printable ASCII characters. Production asynchronous Basic POST /v1/speech/jobs requires one; asynchronous Premium remains limited to development and staging. Keep the same key only when retrying the exact same endpoint and JSON payload. VowelMarks retains the completed result or job identity for 24 hours.
- Same key and payload: replay the successful result without a second usage charge.
- Same key with a different payload:
409 idempotency_conflict. - A duplicate while the first request is still running: retryable
409 request_in_progress. - A failed validation or generation does not consume usage.
Read the rate-limit headers
Successful authenticated JSON responses include RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset. The published limit is shared by every key in the same organization and environment, so adding keys does not multiply capacity. Authenticated malformed requests, idempotent replays, and job create/read/stream/cancel requests still count toward requests per minute. This request limit is an API admission ceiling; Premium Speech also depends on the speech provider's separate capacity.
X-Request-Id: 95b…
RateLimit-Limit: 20
RateLimit-Remaining: 18
RateLimit-Reset: 41Handle the structured error envelope
Every API error has a request ID plus a stable machine-readable code. Branch on error.code and error.retryable rather than comparing message text. Include X-Request-Id when contacting VowelMarks.
{
"request_id": "95b…",
"error": {
"code": "service_unavailable",
"message": "The request could not be completed.",
"category": "service",
"action": "Retry the request later.",
"retryable": true
}
}Set a complete-response deadline
Some processing origins sleep while idle, so the first request after an idle period can take several extra seconds while the service wakes. Warm latency is usually lower. Input length, the selected capability, upstream provider time, and capacity can add more variation. API v1 does not publish a latency or availability SLA.
Configure both a connection timeout and a deadline that remains active until the complete JSON response body has been read. A practical starting point is 120 seconds for text generation. The synchronous speech route may need several minutes for long passages; allow up to 15 minutes for a maximum-size request or split it into smaller sections. Tune these budgets from your own measurements.
If your deadline expires after the request was sent, treat the outcome as unknown. Do not create a new idempotency key. Wait briefly, then retry the same endpoint, body, and key so a completed result can replay safely or an in-progress request can report its state.
Retry policy
- Retry only when
retryableis true. - Honor
Retry-Afterand add random jitter before the next attempt. - Reuse the original
Idempotency-Keyand exact payload. - Do not retry validation, authentication, authorization, or quota errors until the stated action has been taken.
- Keep the deadline active while reading the complete response body, not only until response headers arrive.
- A network error or client timeout has an unknown outcome. Retry with the original key and exact payload.