Generate speech from text
package main
import ( "fmt" "strings" "net/http" "io")
func main() {
url := "https://api.ai.wpengine.com/v1/audio/speech"
payload := strings.NewReader("{ \"model\": \"google/gemini-2.5-flash-tts\", \"input\": \"example\", \"response_format\": \"pcm\", \"voice\": \"Achernar\" }")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>") req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(res) fmt.Println(string(body))
}const url = 'https://api.ai.wpengine.com/v1/audio/speech';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"model":"google/gemini-2.5-flash-tts","input":"example","response_format":"pcm","voice":"Achernar"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.ai.wpengine.com/v1/audio/speech', [ 'body' => '{ "model": "google/gemini-2.5-flash-tts", "input": "example", "response_format": "pcm", "voice": "Achernar" }', 'headers' => [ 'Authorization' => 'Bearer <token>', 'Content-Type' => 'application/json', ],]);
echo $response->getBody();curl --request POST \ --url https://api.ai.wpengine.com/v1/audio/speech \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "model": "google/gemini-2.5-flash-tts", "input": "example", "response_format": "pcm", "voice": "Achernar" }'Converts text input to audio using a text-to-speech model. Returns binary audio data with the appropriate Content-Type header. Requires a valid WP Engine bearer token; API keys must carry the “speech:write” permission.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Optional model identifier. Defaults to a Gemini TTS model when omitted.
Example
google/gemini-2.5-flash-ttsThe text to convert to speech.
Audio encoding format. “pcm” returns raw 16-bit linear PCM as received from the upstream provider. “wav” wraps the PCM data in a WAV container for direct browser playback. Omit for raw PCM (backward compatible).
Example
wavThe Chirp 3 HD voice to use for speech synthesis. Defaults to “Kore”. All 30 prebuilt voices are supported across 50+ languages.
Responses
Section titled “Responses”Generated audio data
Invalid request body or parameters. On agent create and update, error type “profile_unavailable” means the requested profile is not available to the caller.
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Missing or invalid bearer token
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Headers
Section titled “Headers”Example
Bearer realm="ai-services"The account’s credit balance is exhausted. Grant or top up credits before retrying. Distinct from 429, which is edge rate limiting.
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}The token is valid, but the request is forbidden. Error type “permission_error” means the token’s scope/permission is insufficient or the authenticated user is not authorized for the target account; “entitlement_required” means the account may not use WP Engine AI, with error_code giving why when known (not_eligible, terms_required, not_enabled or suspended) and portal_url where to fix it; “account_required” means no billing account could be resolved; and “billing_account_pending” means billing isn’t set up for the account yet, usually because its setup after AI was turned on hasn’t finished. Retry shortly. On /v1/chat/completions when content moderation is enabled, and on /v1/sessions/{session_id}/events, error type “content_policy_violation” instead means the request content was blocked by content moderation policy; that response never identifies which filter or category matched.
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Request body exceeds the 64 KiB limit
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Rate limit exceeded. The request was throttled at the edge; wait and retry later. The response body is a short HTML page generated by the load balancer, not a structured JSON error — clients should rely on the 429 status code rather than parsing the body.
Upstream provider returned an error
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}A required dependency is temporarily unavailable. Retry after a short delay with exponential back-off. An entitlement lookup failure uses error type “entitlement_unavailable”. A model without complete rate coverage uses error type “model_unpriced”. A credit balance that can’t be read uses error type “balance_unavailable”.
object
object
Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.
Where the customer can resolve the error, set when one is configured on an entitlement_required refusal that has an error_code, and on a 402 insufficient_credits refusal (the credit purchase page).
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}