Verification API
Base URL: https://api.eu-captcha.eu
The Verification API exposes a single endpoint your server calls after receiving a form submission. It validates the proof-of-work token generated by verify.js on the client and returns whether the submission is legitimate.
Authentication uses the secret field in the request body. No Authorization header is required or accepted.
Never call this endpoint from client-side code
The secret key must remain on your server at all times. Calling /v1/verify from browser JavaScript exposes your secret key to anyone who inspects the request.
See API Authentication for the distinction between this API and the management API.
You can browse the full API specification and send test requests directly in your browser at docs-api.eu-captcha.eu — no additional tooling required.
POST /v1/verify
Validates an EU CAPTCHA token generated by the verify.js widget.
Host: https://api.eu-captcha.eu
POST /v1/verify
Content-Type: application/json
Request body
All five fields are required.
| Field | Type | Description |
|---|---|---|
sitekey |
string | Your public sitekey. Found in the dashboard — click Details/HowTo for your sitekey, then open the Details tab. |
secret |
string | Your secret key paired with the sitekey. Keep this server-side only. |
client_ip |
string | IPv4 or IPv6 address of the visitor. When behind a CDN or load balancer, use X-Forwarded-For or X-Client-IP to obtain the real client address — do not forward the proxy's own address. |
client_token |
string | Value of the eu-captcha-response form field submitted by the visitor. May be an empty string — always submit it regardless. |
client_user_agent |
string | The visitor's User-Agent request header. |
Example:
{
"sitekey": "1c87e240-0000-0000-0000-23ac9f99da68",
"secret": "LqFgQA+ExampleSecretKeyForDocsOnly+wdjvI=",
"client_ip": "5.6.7.8",
"client_token": "XVtHUQExampleTokenUF9ESkQUAxUTChJEXFFVX1ZXURs=",
"client_user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
Always submit
client_tokeneven when it is an empty string. The service uses all attempts — including incomplete ones — to improve detection accuracy.
Responses
200 — Verification result
Always check both success and train.
| Field | Type | Description |
|---|---|---|
success |
boolean | true if the token passed verification; false if it did not. |
train |
boolean | null | false or null — normal operation. true — validation was skipped and success is forced to true. See warning below. |
| Scenario | success |
train |
Meaning |
|---|---|---|---|
| Token valid | true |
false |
Accept the submission |
| Token invalid or already used | false |
false |
Reject the submission |
| Validation bypassed | true |
true |
Reject — see warning below |
train: true means your protection is disabled
When train is true, the API did not perform real validation — all submissions appear successful regardless of token content. This occurs when the sitekey does not exist, the secret does not match the sitekey, or the sitekey's protection is disabled. If you receive train: true in production, check your credentials in the dashboard immediately.
400 — Bad request
The request body is missing required fields or is malformed.
{
"error": "missing_field",
"message": "Required field 'sitekey' is missing."
}
429 — Rate limit exceeded
Too many requests. Back off and retry after the number of seconds given by the Retry-After response header.
Retry-After: 10
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 10 seconds."
}
500 — Internal server error
Unexpected server-side failure.
{
"error": "internal_error",
"message": "An unexpected error occurred. Please try again."
}
Further reading
- Server-Side Verification — code examples in Node.js, PHP, and Python
- Error Codes — full list of error identifiers returned in
4xxresponses - Python Module — official async Python client
- Django Module — official Django integration
- PHP Module — official PHP client
- Ruby Gem — official Ruby client (Rails, Sinatra, Rack)
- Java Client — official Java clients on Maven Central (RestTemplate, WebFlux Boot 2, WebFlux Boot 3)
- OpenAPI Generator — generate a client for any language from the OpenAPI spec
- Additional Secrets — managing the
secretkey used in verification requests - API Authentication — distinction between the verification secret and the management API token
- Interactive API explorer — browse endpoints and test requests in your browser
- OpenAPI spec — machine-readable API definition