Skip to content

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_token even 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