Speech & embeddings

Beyond chat, the Grove API serves text to speech and text embeddings through the standard OpenAI-compatible endpoints. Same key, same base URL, same prepaid credits.


Text to speech: POST /v1/audio/speech

Model: kokoro-82m (turbo: kokoro-82m-turbo). Returns binary audio.

curl https://api.pgsgrove.com/v1/audio/speech \
  -H "Authorization: Bearer $PGS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kokoro-82m",
    "input": "The grove is quiet tonight.",
    "voice": "af_heart"
  }' --output speech.mp3
resp = client.audio.speech.create(
    model="kokoro-82m",
    input="The grove is quiet tonight.",
    voice="af_heart",
)
resp.write_to_file("speech.mp3")

Parameters:

Field Required Notes
model yes kokoro-82m or kokoro-82m-turbo
input yes Up to 4,096 characters per request
voice yes A Kokoro voice id, e.g. af_heart, af_bella, am_michael. Blend voices by joining ids with commas: "af_heart,af_bella". Full list: the VOICES file on the model's weights page.
response_format no mp3 (default), wav, opus, or flac
speed no 0.25 to 4.0; default 1.0

Billing is per input character, not per token: the model card shows the rate per 1M characters. Turbo carries the same 1.5x priority surcharge as chat models. A 300-character paragraph costs a fraction of a cent.


Embeddings: POST /v1/embeddings

Model: embeddinggemma-300m. Returns 768-dimension vectors in the standard OpenAI shape.

curl https://api.pgsgrove.com/v1/embeddings \
  -H "Authorization: Bearer $PGS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "embeddinggemma-300m",
    "input": ["first text to embed", "second text to embed"]
  }'
resp = client.embeddings.create(
    model="embeddinggemma-300m",
    input="the text to embed",
)
vector = resp.data[0].embedding  # 768 floats

input accepts a single string or an array of strings (one vector per entry). Context window is 2,048 tokens per input. Billed per input token at the rate on the model card; there are no output tokens.


Shared behavior

  • Auth, rate limits, and credits are identical to chat: the same per account request and concurrency limits apply, and both endpoints draw from the same prepaid balance.
  • Sending the wrong model to the wrong endpoint returns a clean 400 telling you which endpoint that model belongs to (chat ids on /v1/audio/speech, kokoro-82m on /v1/chat/completions, and so on).
  • Failed requests are not billed.