CAPTCHA Result Validation
Here we explain how you call up and evaluate the CAPTCHA result in your backend from our server.
Supported Technologies
Section titled “Supported Technologies”It is possible to retrieve the CAPTCHA verification result from our servers in any programming language using a simple REST API call. To make this process as easy as possible, we provide ready-made integrations for the most popular programming languages and frameworks. The source code for all provided integrations can also be found on Github. The API call is documented in detail here, so that individual integrations are possible.
The Verification Token
Section titled “The Verification Token”When the CAPTCHA widget is completely solved, the CAPTCHA returns a so-called verification token. This is a simple text/string. It is available in a hidden input field called tc-verification-token and is also propagated by the trustcaptcha component with the captchaSolved JavaScript event. You can find out more about this in the CAPTCHA widget overview.
Send this token to your backend. For example, when the form containing the CAPTCHA is submitted, or independently via an API interface. With the help of the verification token, you can now retrieve the CAPTCHA verification result from our servers on the server side. Either via an API interface or with the help of one of our ready-made integrations.
Structure of the token
Section titled “Structure of the token”The verification token returned by the TrustCaptcha widget is encoded in Base64.
eyJ2ZXJpZmljYXRpb25JZCI6IjA3YjAxOTIyLTNmYWEtNDY2Ny1hNGE2LTkxMGE3NmNiOGFiNyIsImV4cGlyZXNBdCI6IjIwMjYtMDUtMDNUMTM6NDU6MDguMjE0WiJ9When you decode the verification token, you get back a JSON object. This contains the verificationId you need to fetch the verification result via the REST-API, plus an expiresAt timestamp telling you when the token (and therefore the result) will no longer be retrievable.
{ "verificationId": "07b01922-3faa-4667-a4a6-910a76cb8ab7", "expiresAt": "2026-05-03T13:45:08.214Z"}Overview of the properties of the token:
| Key | Value | Description |
|---|---|---|
verificationId | UUID | Unique identifier (ID) of the verification. |
expiresAt | Timestamp (UTC) | When the token (and therefore the verification result) will expire and can no longer be retrieved. |
clientFailover | Boolean | Optional. Present and set to true when the widget could not reach our servers and issued a self-built failover token. See the Failover behavior page for handling. |
Verification Result / API-Call
Section titled “Verification Result / API-Call”Below you will be explained how to retrieve the CAPTCHA verification result, what information it contains, and how you can work with it.
Retrieving the Result
Section titled “Retrieving the Result”You can retrieve the verification result from our servers using the following URL.
curl -X GET "https://api.trustcomponent.com/v2/verifications/{verificationId}/results" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {api-key}"Overview of request properties:
| Parameter | Type | Description |
|---|---|---|
verificationId | Path | Unique identifier (ID) of the verification. Can be taken from the verification token. |
api-key | Header | API key of the CAPTCHA, sent as Authorization: Bearer <apiKey>. You can manage your API keys in the CAPTCHA administration. |
Processing the Result
Section titled “Processing the Result”The returned verification result looks like this:
{ "captchaId": "cc2e2d5e-d1ef-4a7f-a7bd-dec5b37df47a", "verificationId": "07b01922-3faa-4667-a4a6-910a76cb8ab7", "verificationPassed": true, "score": 0.3, "decisionType": "STANDARD", "decisionAction": "ALLOW", "gatewayFailoverActive": false, "riskScoringEnabled": true, "minimalDataModeEnabled": false, "origin": "https://www.your-website.com/sub-page", "ipAddress": "2a01:123:33bb:1a1a:0:0:0:1", "countryCode": "DE", "deviceFamily": "Other", "operatingSystem": "Windows 10", "browser": "Chrome 119.0.0", "verificationStartedAt": "2026-05-03T13:30:05.941Z", "verificationFinishedAt": "2026-05-03T13:30:08.214Z", "resultExpiresAt": "2026-05-03T13:45:08.214Z", "resultFirstFetchedAt": "2026-05-03T13:30:09.001Z", "resultLastFetchedAt": "2026-05-03T13:30:09.001Z"}Overview of the result properties:
| Parameter | Value | Description |
|---|---|---|
captchaId | UUID | Unique identifier (ID) of the respective CAPTCHA. |
verificationId | UUID | Unique identifier (ID) of the verification. |
verificationPassed | Boolean | Whether the CAPTCHA was passed (the request can be allowed) or not. |
score | Number | Bot probability score between 0 (likely human) and 1 (likely bot). |
decisionType | Text | How the verification outcome was determined. See the Decision section below. |
decisionAction | Text | The recommended action for this verification. See the Decision section below. |
gatewayFailoverActive | Boolean | true when the gateway synthesized this result during a captcha-service outage. See Failover behavior. |
riskScoringEnabled | Boolean | Whether risk scoring was enabled for the captcha environment that issued this verification. |
minimalDataModeEnabled | Boolean | Whether the captcha environment runs in minimal-data mode. |
origin | Text | The page where the captcha was solved. |
ipAddress | Text | IP address (IPv4 or IPv6) of the client. |
countryCode | Text | Two-letter ISO 3166-1 alpha-2 country code derived from the client IP. Empty string if not resolvable. |
deviceFamily | Text | Name of the device family used by the client. |
operatingSystem | Text | Name and version of the operating system used by the client. |
browser | Text | Name and version of the browser used by the client. |
verificationStartedAt | Timestamp (UTC) | When the verification process (the CAPTCHA) was started by the client. |
verificationFinishedAt | Timestamp (UTC) | When the verification process (the CAPTCHA) was completed by the client. |
resultExpiresAt | Timestamp (UTC) | When the result will expire and can no longer be retrieved. |
resultFirstFetchedAt | Timestamp (UTC) | When the result was first fetched. Equal to resultLastFetchedAt on the first fetch. |
resultLastFetchedAt | Timestamp (UTC) | When the result was most recently fetched (i.e. on this very call). |
Evaluate CAPTCHA result
Section titled “Evaluate CAPTCHA result”The CAPTCHA verification result contains two important pieces of information: verificationPassed and score. Based on this information, you can define your individual rules and determine how to proceed.
verificationPassed: Provides information on whether the CAPTCHA has been completed and passedscore: The bot score indicates how likely a request is to originate from a bot. The value always ranges between 0 and 1, and the higher the value, the higher the bot risk.
Human or not?
Section titled “Human or not?”As a starting point for your individual CAPTCHA validation, we recommend checking whether verificationPassed is true and whether the bot score value is below 0.5.
if (!verificationResult.verificationPassed || verificationResult.score > 0.5) { console.log("Verification failed or bot score > 0.5 – possible automated request.");} else { console.log("Everything looks good - probably a human.");}Advanced check
Section titled “Advanced check”We recommend always checking expressions to see if verificationPassed is true. If you don’t want to check for bot probability but only the dynamic proof-of-work, you can skip the bot score check.
if (!verificationResult.verificationPassed) { console.log("Verification failed");} else { console.log("Verification passed.");}The score threshold of 0.5 is not suitable for everyone. Everyone has different security needs or a higher tolerance for false positives detected as bots or spam messages. So experiment with the threshold value of 0.5 and adjust it to your individual needs. Note: 0 = probably human, 1 = probably bot/automated.
const threshold = 0.75; // allow more false positivesif (!verificationResult.verificationPassed || verificationResult.score > threshold) { console.log("Verification failed or bot score > "+threshold+" – possible automated request.");} else { console.log("Everything looks good - probably a human.");}A multi-stage process is also possible. For example, you could take different approaches based on the score and thus based on individual risk. This means that a user does not have to be excluded immediately or a message blocked; instead, you could simply add an additional security check in the event of an increased risk.
if (!verificationResult.verificationPassed) { console.log("Captcha failed → reject.");} else if (verificationResult.score >= 0.8) { console.log("High bot risk → reject.");} else if (verificationResult.score >= 0.4) { console.log("Elevated risk → e.g. require email verification or 2FA.");} else { console.log("Low risk → allow / proceed.");}The Decision
Section titled “The Decision”In addition to verificationPassed and score, every result carries two fields that explain how the outcome was reached: decisionType describes which mechanism made the call, decisionAction describes what TrustCaptcha would recommend doing with the request.
decisionType — known values:
| Value | Description |
|---|---|
STANDARD | Outcome was calculated by the regular CAPTCHA validation logic (proof-of-work + risk score). |
BYPASS_KEY | The CAPTCHA was solved using a configured bypass key. |
CUSTOM_ACCESS_RULE | A custom access rule (e.g. allow- or block-list) configured for this CAPTCHA matched. |
GLOBAL_IP_ACCESS_RULE | A global TrustCaptcha access rule (e.g. global allow- or block-list) matched. |
FAILOVER | The upstream CAPTCHA service was temporarily unreachable; the gateway returned a tolerant fallback result. |
FAILOVER_TOLERANCE | The upstream returned a soft error (e.g. not yet released / not found) shortly after a recent outage; the gateway still serves a tolerant result within a short grace window. |
decisionAction — known values:
| Value | Description |
|---|---|
ALLOW | The request should be allowed. |
BLOCK | The request should be blocked. |
CUSTOM | A custom rule with a custom action was applied. Inspect your CAPTCHA settings for context. |
Error Handling
Section titled “Error Handling”Errors can occur when retrieving the verification result. Below you will find an overview of the relevant status codes along with a description of what went wrong and what you should consider.
| Status Code | Status Name | Description |
|---|---|---|
403 | Forbidden | The Authorization header is missing/malformed, or the API key is invalid. Please check the request and your API key. |
404 | Not Found | The verification does not exist for the given verificationId. Please check the verification ID. |
410 | Gone | The verification result has expired and can no longer be retrieved. |
412 | Precondition Failed | A client-claimed failover (?clientFailover=true) was rejected because our gateway has no record of a recent outage. See Failover behavior. |
423 | Locked | The verification result has not yet been released. Please wait until the verification is complete. |
429 | Too Many Requests | The verification result has reached its maximum retrieval count and can no longer be retrieved. |
500 | Internal Server Error | An internal server error has occurred. If this happens repeatedly and persists over time, please contact support. |