Errors
Errors come back with an HTTP status and a JSON body with a stable code, a human message and, for some codes, details. Branch on code, not on message.
Error body
{
"call_id": "call_...",
"error": {
"code": "invalid_input",
"message": "Input failed validation",
"details": [{ "path": ["siteUrl"], "message": "Invalid input: expected string, received undefined" }]
}
}Over MCP the same code and message are returned as a tool error.
Codes
| Code | HTTP | What happened | What to do |
|---|---|---|---|
unauthenticated |
401 | The API key is missing, malformed or revoked. | Send Authorization: Bearer oa_… with a current key. |
invalid_json |
400 | The request body isn't JSON. | Send a JSON body with Content-Type: application/json. |
invalid_input |
400 | The body or the endpoint's input failed validation. details lists each issue. |
Fix the fields named in details. The input schema is at GET /v1/providers/:id. |
provider_not_found |
404 | No provider with that id. | Use an id from GET /v1/providers. |
endpoint_not_found |
404 | The provider has no raw endpoint with that id. | Use an id from GET /v1/providers/:id. |
tool_not_found |
404 | The provider has no smart tool with that name. | Use a name from GET /v1/providers/:id. |
connection_not_found |
404 | No active connection for this provider that you can see, or the connection_id doesn't exist or is outside your clients. |
Connect an account, or check GET /v1/connections. |
connection_ambiguous |
400 | Several active connections match. details.connection_ids lists them. |
Pass connection_id. |
connection_inactive |
409 | The connection you named is expired or revoked. | Reconnect it in the dashboard or send a new connect link. |
read_only |
403 | A read-only key or grant tried an endpoint or tool that writes. | Use a read-write key, or approve the agent with read-write access. |
credentials_expired |
401 | The account owner revoked access, or Google expired it. The connection is marked Token expired. | Reconnect the account. For a client, send a new connect link. |
credentials_rejected |
502 | Google refused the stored credentials, for example a service account without access. | Check the account's access to the property, then reconnect. |
upstream_error |
provider's status | The provider answered with an error. details holds its response body. |
Read details; often a wrong property id or a date range with no data. |
upstream_unreachable |
502 | The provider couldn't be reached. | Retry with backoff. |
internal_error |
500 | Something failed on our side. | Retry; if it persists, send us the call_id. |
Every failed call is logged. Look it up by call_id in Call logs or with GET /v1/logs/:call_id.