1. Define the request and output contract
Write down which text lengths, voices, languages, formats, and settings the application accepts. Reject unsupported combinations before sending work to the provider, and return an error that tells the caller how to correct it.
Give every generation a stable local identifier. The client can then poll or subscribe to the same job instead of guessing whether a second click created a duplicate file.
2. Keep credentials and ownership on the server
Never ship a provider credential in browser JavaScript or a public repository. The server should resolve the authenticated owner, check the account’s entitlement, and store only the minimum metadata needed to reconcile the output.
Separate browser session management from machine credentials. A user-facing API key should be scoped, revocable, rate limited, and shown only once when it is created.
3. Make retries safe and observable
Network timeouts do not prove that a provider failed to create audio. Use an idempotency key for retriable work, keep an ambiguous job open until it can be reconciled, and show the user whether the system is still checking or needs a new request.
Log a correlation ID, local status transition, provider reference, duration, and error class. Do not log raw script text or secrets by default, especially when the voice feature handles private drafts.
4. Test the unhappy paths before launch
- Duplicate clicks return the existing job instead of charging or generating twice.
- A timeout after remote creation can be reconciled without losing the output.
- A revoked or expired key fails closed and does not expose provider details.
- Downloads require the same owner check as generation and status polling.
- Metrics and logs identify slow work without inventing customer-facing claims.