Integrate with a server over HTTPS
Use native HTTPS calls to invoke the CAPTCHA verification API from your server. This approach requires manually constructing the request, including the URL, headers, body, and signature. If you don't have specific requirements for raw HTTP control, use a software development kit (SDK) instead — see Server-side integration.
How it works
The server-side verification flow has five steps:
Client completes the CAPTCHA challenge. The CAPTCHA widget runs in the user's browser or app and generates a
CaptchaVerifyParamtoken on success.Client sends the token to your server. Pass the raw
CaptchaVerifyParamvalue as-is — do not modify it.Your server calls the verification API. Submit
CaptchaVerifyParam(and optionallySceneId) tohttps://captcha.ap-southeast-1.aliyuncs.comvia a signed POST request.Alibaba Cloud returns the verification result. The response includes
VerifyResult(trueorfalse) and aVerifyCodethat explains the outcome.Your server acts on the result. Allow or block the request based on
VerifyResult.
Server-side verification is mandatory. The client-side widget alone provides no protection — tokens can be replayed or forged if your server doesn't validate them.
Prerequisites
Before you begin, make sure you have:
An activated CAPTCHA service and at least one configured scenario
An Alibaba Cloud AccessKey pair. To create one, see Create an AccessKey pair. Store your AccessKey secret securely — never hard-code it in source code.
(If using RAM users) The
AliyunYundunAFSFullAccesspermission granted to the RAM user. See Grant permissions to a RAM role.(If using STS) A valid Security Token Service (STS) token via the AssumeRole operation.
Call the verification API
Endpoint and method
| Property | Value |
|---|---|
| Endpoint | https://captcha.ap-southeast-1.aliyuncs.com |
| Method | POST |
| Protocol | HTTPS |
| Request body format | application/x-www-form-urlencoded |
Quick example
The following curl command shows the minimum required structure. Replace the placeholder values before running.
curl -X POST https://captcha.ap-southeast-1.aliyuncs.com \
-H "x-acs-action: VerifyIntelligentCaptcha" \
-H "x-acs-version: 2023-03-05" \
-H "x-acs-date: 2023-10-26T09:01:01Z" \
-H "x-acs-signature-nonce: <unique-random-string>" \
-H "x-acs-content-sha256: <sha256-of-request-body>" \
-H "host: captcha.ap-southeast-1.aliyuncs.com" \
-H "Authorization: ACS3-HMAC-SHA256 Credential=<your-access-key-id>,SignedHeaders=host;x-acs-action;x-acs-content-sha256;x-acs-date;x-acs-signature-nonce;x-acs-version,Signature=<computed-signature>" \
-d "CaptchaVerifyParam=<token-from-client>&SceneId=<your-scene-id>"Replace the following placeholders:
| Placeholder | Description |
|---|---|
<unique-random-string> | A new UUID or random string for each request, to prevent replay attacks |
<sha256-of-request-body> | Base16-encoded SHA-256 hash of the request body |
<your-access-key-id> | Your AccessKey ID, available in the Resource Access Management (RAM) console |
<computed-signature> | Signature computed using the ACS3-HMAC-SHA256 algorithm — see Signature mechanism |
<token-from-client> | The raw CaptchaVerifyParam value passed from the client |
<your-scene-id> | The scenario ID from your Captcha 2.0 console configuration |
Request headers
Submit all common parameters as HTTP request headers.
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
x-acs-action | String | Yes | API operation name. Set to VerifyIntelligentCaptcha. | VerifyIntelligentCaptcha |
x-acs-version | String | Yes | API version in YYYY-MM-DD format. Set to 2023-03-05. | 2023-03-05 |
Authorization | String | Yes (non-anonymous) | Authentication string. Format: ACS3-HMAC-SHA256 Credential=<AccessKeyId>,SignedHeaders=<signed-headers>,Signature=<signature>. See Signature mechanism. | ACS3-HMAC-SHA256 Credential=YourAccessKeyId,SignedHeaders=host;x-acs-action;x-acs-content-sha256;x-acs-date;x-acs-signature-nonce;x-acs-version,Signature=e521358f... |
x-acs-signature-nonce | String | Yes | Unique random string per request. Prevents replay attacks. | d410180a5abf7fe235dd9b74aca91fc0 |
x-acs-date | String | Yes | Request timestamp in UTC, ISO 8601 format (yyyy-MM-ddTHH:mm:ssZ). Must be within 15 minutes of the actual send time. | 2023-10-26T09:01:01Z |
host | String | Yes | API endpoint hostname. See HTTP request syntax. | captcha.ap-southeast-1.aliyuncs.com |
x-acs-content-sha256 | String | Yes | Base16-encoded SHA-256 hash of the request body. Equal to the HashedRequestPayload value. | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
x-acs-security-token | String | Required if using STS | STS token. Set to the SecurityToken value from the AssumeRole response. | — |
Request body parameters
Submit operation-specific parameters in the request body using application/x-www-form-urlencoded encoding.
| Parameter | Type | Required | Description |
|---|---|---|---|
CaptchaVerifyParam | String | Yes | The verification token generated by the CAPTCHA client. Pass it exactly as received — do not modify it. V2 architecture example: {"sceneId":"xxxxxx","certifyId":"xxxxxx","deviceToken":"xxxxxxx==","data":"xxxxxx=="}. V3 architecture example: eyJjZXxxxxxxxxxxxxxxnVlfQ==. |
SceneId | String | No (recommended) | The scenario ID for this verification request. Specify it to prevent requests from different scenarios from being mixed up. |
Do not modify CaptchaVerifyParam. Any modification causes a service error.
Signature mechanism
CAPTCHA authenticates each request using symmetric encryption with your AccessKey pair. The AccessKey ID identifies you, and the AccessKey secret is used to compute and verify the signature. Keep your AccessKey secret strictly confidential.
The signature algorithm is ACS3-HMAC-SHA256. For the full computation steps, see V3 signature mechanism.
Response
Response structure
A successful call returns HTTP 200 with this JSON body:
{
"RequestId": "3F290236-C***B-54F31BD999FF",
"Code": "Success",
"Message": "success",
"Success": true,
"Result": {
"VerifyResult": true,
"VerifyCode": "T001"
}
}Check Success first to confirm the API call itself succeeded. Then check Result.VerifyResult to determine whether the user passed the CAPTCHA challenge.
VerifyCode values
| Code | Outcome | What to do |
|---|---|---|
T001 | Verification passed | Allow the request |
T005 | Test mode active — configuration verified | Check the policy status in the Captcha 2.0 console. See Access guide |
F001 | Possible attack — risk policy check failed | Block the request. Submit a ticket if false positives are frequent |
F002 | CaptchaVerifyParam is empty | Check your client integration — the frontend should populate this automatically. See Server-side integration |
F003 | CaptchaVerifyParam format is invalid | Make sure the server passes the token unchanged. See Server-side integration |
F004 | Test mode active — verification skipped | Review the policy configuration in the Captcha 2.0 console. See Scenario management |
F005 | sceneId in CaptchaVerifyParam is invalid | Make sure the server passes the token unchanged. See Server-side integration |
F006 | sceneId does not belong to your account | Verify the scenario ID in the Captcha 2.0 console |
F008 | Verification token already used | Each token is single-use. Ask the user to complete the CAPTCHA again |
F009 | Virtual device detected | Block or flag the request. To allow virtual devices, disable this check in the Captcha 2.0 console under custom policy. See Configure custom policies |
F010 | IP request rate exceeded | Rate limit enforcement. To adjust the threshold, configure a custom policy. See Configure custom policies |
F011 | Device request rate exceeded | Rate limit enforcement. To adjust the threshold, configure a custom policy. See Configure custom policies |
F012 | Server SceneId does not match the frontend sceneId | Make sure the SceneId in your server request matches the scenario ID configured on the frontend |
F013 | CaptchaVerifyParam is missing required fields | Check your frontend integration. See Initiate an authentication request |
F014 | No initialization record found | Two possible causes: (1) more than 20 minutes elapsed between initialization and verification — reinitiate the client; (2) no initialization request was sent — this may indicate an attack |
F015 | CAPTCHA challenge not completed | The user did not finish the interaction (for example, the puzzle was not moved to the correct position). Ask the user to retry |
F016 | URL verification policy blocked the request | Adjust the URL verification rules in the Captcha 2.0 console. See Configure custom policies |
F017 | Possible attack — abnormal protocols or parameters | Block the request |
F018 | CaptchaVerifyParam reused (V3 only) | Each token is single-use. Ask the user to complete the CAPTCHA again |
F019 | Timeout or missing behavior verification (V3 only) | The business signature verification was initiated more than 90 seconds after behavior verification, or without a preceding behavior verification request. Restart the flow |
F020 | CaptchaVerifyParam does not match the scenario ID or user (V3 only) | Make sure tokens are not shared across users or scenarios |
HTTP status codes
| HTTP status | Code | Message |
|---|---|---|
| 200 | Success | Success. |
| 400 | MissingParameter | One or more required parameters are not specified. |
| 401 | InvalidParameter | The parameter is invalid. |
| 403 | Forbidden.AccountAccessDenied | You do not have the required permissions. The service may not be activated, or your account may have overdue payments. |
| 403 | Forbidden.RAMUserAccessDenied | The RAM user does not have the required permissions. Grant AliyunYundunAFSFullAccess to the RAM user. See Grant permissions to a RAM role. |
| 500 | InternalError | An internal error has occurred. Try again later. If the error persists, submit a ticket. |
Best practices
Security
Store your AccessKey secret in environment variables or a secrets manager — never hard-code it.
Validate every verification request on your server. Client-side results alone are not trustworthy.
Use STS temporary credentials for short-lived access rather than long-lived AccessKey pairs.
Error handling
If the verification API call fails due to a network error or an HTTP 5xx response, log the error and treat the verification as passed by default. This preserves your service availability. Investigate and resolve the underlying cause as soon as possible.
Do not expose internal error codes or messages to end users.
What's next
Server-side integration — SDK-based server integration (recommended for most use cases)
Scenario management — create and manage CAPTCHA scenarios
Configure custom policies — adjust rate limits, device detection, and URL verification rules