Reference
challenge_failed
The bot-protection challenge on the public chat endpoint did not verify.
What it means
The bot-protection challenge on the public chat endpoint did not verify.
Retry after fixing
Retrying unchanged will not help. Correct the cause, then send it again.
What causes it
- The Turnstile token was missing, already spent, or had expired — tokens are single-use and short-lived.
- The token was minted for a different site key.
- A server-side integration called the public endpoint without solving a challenge at all.
How to fix it
- Render the challenge with the site key returned in `details.site_key` and send a fresh token.
- Solve a new challenge per request; do not cache the token.
- Server-to-server integrations should use the authenticated API with a key rather than the public widget endpoint.
The details object
This code carries a details object with more than the message can say:
What the response looks like
{
"error": {
"code": "challenge_failed",
"message": "The bot-protection challenge on the public chat endpoint did not verify",
"details": { ... },
"request_id": "7cb7f7862a82425d8e4c3fb8a497dfe6"
},
"type": "https://integrable.cloud/docs/errors/challenge_failed",
"title": "Challenge Failed",
"status": 422,
"detail": "The bot-protection challenge on the public chat endpoint did not verify",
"instance": "/api/bots/01a0652b-3713-7ea1-a6c9-2e895389ec34"
}Branch on error.code, not on the message — the code is stable, the sentence is not. Log request_id either way.
Still stuck
Quote the request_id from the response — hello@integrable.cloud. It is what lets us find the exact request. The full list of codes is at Error codes, and the conventions every endpoint shares are in Retries, versioning and limits.
Something here wrong or missing? Tell us — the documentation and the API are maintained by the same person, so a correction is a fix rather than a ticket.