---
title: Authenticating with the ProsodyAI API
description: API keys, scopes, limits and errors for the ProsodyAI REST API, and how Claude and ChatGPT connect with OAuth.
url: https://prosodyai.ai/auth.md
updated: 2026-10-29
---

# Authenticating with the ProsodyAI API

> How a program calls the ProsodyAI API on a user's behalf: with an API key the user creates, sent as a bearer token. Claude and ChatGPT connect differently, through OAuth sign-in; see "Connecting from Claude or ChatGPT" below.

Base URL: `https://api.prosodyai.ai/api/v1`

## Getting a key

1. The account needs a paid plan, Starter or above (see https://prosodyai.ai/pricing.md). Free accounts cannot create keys.
2. The user signs in at https://prosodyai.ai/auth/login and opens **Developer** (https://prosodyai.ai/developer), then creates a key.
3. The key starts with `sk_` and is shown once. ProsodyAI stores only its hash, so a lost key cannot be recovered; create a new one and revoke the old.

Keys are created and revoked only from a signed-in session. A key cannot create another key.

## Sending it

```
Authorization: Bearer sk_your_api_key
```

Every request carries the header. Example:

```
curl -X POST https://api.prosodyai.ai/api/v1/tts/generate \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello, world!", "language": "en", "style_instructions": "warm, unhurried"}'
```

The response returns a `task_id`; poll `GET /tts/status/{task_id}` until `status` is `completed`, then download `audio_url`. A webhook (`POST /webhooks/`) can be registered instead of polling.

## Scopes

A key carries a list of scopes. The default, `tts:generate`, covers the whole documented surface: speech, voices, Studio, webhooks and reading the account.

| Scope | Opens |
|---|---|
| `tts:generate` | `/tts/*`, single and bulk generation; implies the four below |
| `voices:read` | `/voices/*` |
| `studio:write` | `/studio/*` |
| `webhooks:manage` | `/webhooks/*` |
| `account:read` | `/users/*`, `/quotas/*`, `/costs/*` |

A key created with a narrower list gets exactly that list. A path no scope opens is refused.

Never reachable with a key, whatever its scopes: `/auth/*` (except `GET /auth/me`), `/billing/*` and `/admin/*`. Passwords, payments and keys stay with the signed-in user.

A key can also be pinned to IP addresses and given an expiry date.

## Limits

- 30 requests a minute and 10,000 a day per key (the plan's ceiling; a key may be set lower).
- `/tts/generate` and `/tts/batch` answer with `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) for the minute window.
- Over the limit: `429 Too Many Requests` with `Retry-After`.
- Characters come out of the account's monthly allowance, the same pool as the web and the apps.

## Errors

| Status | Meaning |
|---|---|
| 401 | Missing, wrong, revoked or expired key |
| 403 | The key's scopes or IP pin do not allow this request, or the plan does not include it |
| 429 | Rate limit (with `Retry-After`), or the month's characters are spent (the `detail` says which) |

## Connecting from Claude or ChatGPT

People do not need a key to use ProsodyAI from a chat. Add a connector with the server URL `https://api.prosodyai.ai/mcp`; the client opens ProsodyAI's sign-in and consent page and receives an OAuth token (authorization code with PKCE, discovered from `https://api.prosodyai.ai/.well-known/oauth-protected-resource`). The connection reaches speech, voices, Studio, characters and the account's usage; it cannot touch billing, keys or the account itself. Remove it any time under Account → Connected apps.

## More

- OpenAPI description of every endpoint a key can call: https://api.prosodyai.ai/openapi.json (browsable at https://api.prosodyai.ai/docs)
- API reference with examples: https://prosodyai.ai/developer (after sign-in)
- Overview for language models: https://prosodyai.ai/llms.txt
- Support: hi@prosodyai.ai
