You need a Speak AI API key for any setup that isn’t OAuth. Create one at app.speakai.co/developers/apikeys.
How do you get a Speak AI API key?
Speak AI API keys are created and managed at app.speakai.co/developers/apikeys. Use the same key for OAuth’s manual alternative, Bearer token setups, stdio mode’s SPEAK_API_KEY environment variable, and the CLI.
How is the API key passed to the MCP server?
The MCP server accepts the key two ways: automatically, when a client connects with OAuth 2.1 and Dynamic Client Registration, or directly, as a Bearer token in the Authorization header.
- OAuth one-click: paste
https://api.speakai.co/v1/mcpinto your client, click Allow on the consent popup. No key handling required. - Bearer token: send
Authorization: Bearer <your-speak-api-key>on requests tohttps://api.speakai.co/v1/mcp, or setSPEAK_API_KEYas an environment variable for stdio mode and the CLI.
See Connect your AI tool for the exact steps and config per client.
How does REST authentication work if you call the API directly?
Send your API key on every request in the x-speakai-key header. The API authenticates the request from the key alone, so you do not need an access token.
curl https://api.speakai.co/v1/media \
-H "x-speakai-key: YOUR_API_KEY"You can send the key as Authorization: Bearer YOUR_API_KEY instead. The REST API treats it the same as x-speakai-key.
What about access tokens?
Integrations built on the earlier token flow keep working, so you do not need to change one that already exchanges the key for an access token. New integrations can skip these steps.
Step 1, get an access token:
curl -X POST https://api.speakai.co/v1/auth/accessToken \
-H "Content-Type: application/json" \
-H "x-speakai-key: YOUR_API_KEY"{
"data": {
"email": "you@example.com",
"accessToken": "eyJhbG...",
"refreshToken": "eyJhbG..."
}
}Step 2, send the token alongside your key on every subsequent request:
curl https://api.speakai.co/v1/media \
-H "x-speakai-key: YOUR_API_KEY" \
-H "x-access-token: ACCESS_TOKEN_FROM_STEP_1"Step 3, refresh before the access token expires:
curl -X POST https://api.speakai.co/v1/auth/refreshToken \
-H "Content-Type: application/json" \
-H "x-speakai-key: YOUR_API_KEY" \
-H "x-access-token: CURRENT_ACCESS_TOKEN" \
-d '{"refreshToken": "REFRESH_TOKEN_FROM_STEP_1"}'| Token | Expiry | How to renew |
|---|---|---|
| Access token | 80 minutes | Refresh endpoint, or re-authenticate |
| Refresh token | 24 hours | Re-authenticate with your API key |
While a request carries x-access-token, the API checks that token too, so an expired token returns 401 even with a valid key. Refresh it, or drop the header and send the key alone.
What are the rate limits?
Speak AI enforces 5 requests per 60 seconds on both authentication endpoints, /v1/auth/accessToken and /v1/auth/refreshToken.
For everything else, the MCP client automatically retries on 429 with exponential backoff. If you’re calling the REST API directly, implement exponential backoff yourself and respect the Retry-After header.
What does an error look like?
Every Speak AI MCP tool error follows the same structure, so an agent can parse it without special-casing each tool.
{
"content": [{ "type": "text", "text": "Error: HTTP 401: Invalid API key" }],
"isError": true
}| Code | Meaning |
|---|---|
401 |
Invalid or missing API key or access token |
403 |
Insufficient permissions |
404 |
Resource not found |
429 |
Rate limit exceeded |