Skip to content

CAPTCHA Result Validation

Here we explain how you call up and evaluate the CAPTCHA result in your backend from our server.

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.


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.

The verification token returned by the TrustCaptcha widget is encoded in Base64.

Sample Verification Token (encoded)
eyJ2ZXJpZmljYXRpb25JZCI6IjA3YjAxOTIyLTNmYWEtNDY2Ny1hNGE2LTkxMGE3NmNiOGFiNyIsImV4cGlyZXNBdCI6IjIwMjYtMDUtMDNUMTM6NDU6MDguMjE0WiJ9

When 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.

Decoded Sample Token
{
"verificationId": "07b01922-3faa-4667-a4a6-910a76cb8ab7",
"expiresAt": "2026-05-03T13:45:08.214Z"
}

Overview of the properties of the token:

KeyValueDescription
verificationIdUUIDUnique identifier (ID) of the verification.
expiresAtTimestamp (UTC)When the token (and therefore the verification result) will expire and can no longer be retrieved.
clientFailoverBooleanOptional. 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.

Below you will be explained how to retrieve the CAPTCHA verification result, what information it contains, and how you can work with it.

You can retrieve the verification result from our servers using the following URL.

REST API call
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:

ParameterTypeDescription
verificationIdPathUnique identifier (ID) of the verification. Can be taken from the verification token.
api-keyHeaderAPI key of the CAPTCHA, sent as Authorization: Bearer <apiKey>. You can manage your API keys in the CAPTCHA administration.

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:

ParameterValueDescription
captchaIdUUIDUnique identifier (ID) of the respective CAPTCHA.
verificationIdUUIDUnique identifier (ID) of the verification.
verificationPassedBooleanWhether the CAPTCHA was passed (the request can be allowed) or not.
scoreNumberBot probability score between 0 (likely human) and 1 (likely bot).
decisionTypeTextHow the verification outcome was determined. See the Decision section below.
decisionActionTextThe recommended action for this verification. See the Decision section below.
gatewayFailoverActiveBooleantrue when the gateway synthesized this result during a captcha-service outage. See Failover behavior.
riskScoringEnabledBooleanWhether risk scoring was enabled for the captcha environment that issued this verification.
minimalDataModeEnabledBooleanWhether the captcha environment runs in minimal-data mode.
originTextThe page where the captcha was solved.
ipAddressTextIP address (IPv4 or IPv6) of the client.
countryCodeTextTwo-letter ISO 3166-1 alpha-2 country code derived from the client IP. Empty string if not resolvable.
deviceFamilyTextName of the device family used by the client.
operatingSystemTextName and version of the operating system used by the client.
browserTextName and version of the browser used by the client.
verificationStartedAtTimestamp (UTC)When the verification process (the CAPTCHA) was started by the client.
verificationFinishedAtTimestamp (UTC)When the verification process (the CAPTCHA) was completed by the client.
resultExpiresAtTimestamp (UTC)When the result will expire and can no longer be retrieved.
resultFirstFetchedAtTimestamp (UTC)When the result was first fetched. Equal to resultLastFetchedAt on the first fetch.
resultLastFetchedAtTimestamp (UTC)When the result was most recently fetched (i.e. on this very call).

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 passed

  • score: 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.

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.

Simple decision example (typescript)
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.");
}

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.

Simple check without score (typescript)
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.

Individual threshold value (typescript)
const threshold = 0.75; // allow more false positives
if (!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.

Multi level decision (typescript)
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.");
}

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:

ValueDescription
STANDARDOutcome was calculated by the regular CAPTCHA validation logic (proof-of-work + risk score).
BYPASS_KEYThe CAPTCHA was solved using a configured bypass key.
CUSTOM_ACCESS_RULEA custom access rule (e.g. allow- or block-list) configured for this CAPTCHA matched.
GLOBAL_IP_ACCESS_RULEA global TrustCaptcha access rule (e.g. global allow- or block-list) matched.
FAILOVERThe upstream CAPTCHA service was temporarily unreachable; the gateway returned a tolerant fallback result.
FAILOVER_TOLERANCEThe 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:

ValueDescription
ALLOWThe request should be allowed.
BLOCKThe request should be blocked.
CUSTOMA custom rule with a custom action was applied. Inspect your CAPTCHA settings for context.

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 CodeStatus NameDescription
403ForbiddenThe Authorization header is missing/malformed, or the API key is invalid. Please check the request and your API key.
404Not FoundThe verification does not exist for the given verificationId. Please check the verification ID.
410GoneThe verification result has expired and can no longer be retrieved.
412Precondition FailedA client-claimed failover (?clientFailover=true) was rejected because our gateway has no record of a recent outage. See Failover behavior.
423LockedThe verification result has not yet been released. Please wait until the verification is complete.
429Too Many RequestsThe verification result has reached its maximum retrieval count and can no longer be retrieved.
500Internal Server ErrorAn internal server error has occurred. If this happens repeatedly and persists over time, please contact support.