CAPTCHA Handling

Discord employs CAPTCHAs to prevent abuse when performing high-risk actions such as logging in, accepting invites, and sending friend requests. Some endpoints will always return a CAPTCHA, while others will only return one if the user is sending suspicious requests or has performed a large number of high-risk actions in a short period of time.

Test Endpoint

Test CAPTCHA Decider

POST/captcha/decider

Tests a CAPTCHA decider with the provided options.

JSON Params
FieldTypeDescription
deciderstringThe CAPTCHA decider to test
optionsCAPTCHA test options objectOptions for the CAPTCHA test
CAPTCHA Decider
ValueDescription
hCaptchaRqdataTests an hCaptcha challenge with request data
SmiteRqdataTests a Smite challenge with request data
RecaptchaTests a reCAPTCHA challenge
RecaptchaEnterpriseTests a reCAPTCHA Enterprise challenge
CAPTCHA Test Options Structure
FieldTypeDescription
difficulty?integerThe hCaptcha difficulty
should_serve_invisible?booleanWhether the CAPTCHA challenge should be invisible
hCaptcha Difficulty
ValueNameDescription
1EASYEasy
2MODERATEModerate
3DIFFICULTDifficult
4VERY_DIFFICULTVery difficult
Example Request
{
"decider": "hCaptchaRqdata",
"options": {
"difficulty": 3,
"should_serve_invisible": false
}
}

Identifying CAPTCHAs

When a request is challenged, the endpoint will return a 400 bad request with a response body looking similar to a legacy error response:

CAPTCHA Response Structure
FieldTypeDescription
captcha_keyarray[string]The CAPTCHA service errors
captcha_servicestringThe CAPTCHA service to use
captcha_sitekey 1?stringThe CAPTCHA site key (used by hCaptcha)
captcha_session_id?stringThe CAPTCHA session ID (used by hCaptcha)
captcha_rqdata? 2stringCustom data to be sent on challenge requests (used by hCaptcha Enterprise)
captcha_rqtoken?stringThe CAPTCHA challenge request token (used by hCaptcha Enterprise)
should_serve_invisible?booleanWhether the CAPTCHA challenge should be invisible

1 For hCaptcha, the site key is dynamic and should not be hard-coded.

2 If this field is present, it must be used in the challenge request or the challenge will fail.

CAPTCHA Service
ValueDescriptionSite Key
hcaptchahCaptchaDynamic
recaptcha 1reCAPTCHA6Lef5iQTAAAAAKeIvIY-DeexoO3gj7ryl9rLMEnn
recaptcha_enterprisereCAPTCHA Enterprise6LeYqFcqAAAAAD6iZesmNgVulsO4PkpBdr6NVG6M

1 reCAPTCHA is not currently used by Discord, but may be used again in the future.

Example CAPTCHA Response
{
"captcha_key": ["invalid-input-response", "response-already-used-error"],
"captcha_sitekey": "f5561ba9-8f1e-40ca-9b5b-a0b3f719ef34",
"captcha_service": "hcaptcha"
}

Solving CAPTCHAs

When a CAPTCHA is returned, the client must display a CAPTCHA challenge to the user. How this is done depends on the CAPTCHA service used. See the hCaptcha and reCAPTCHA documentation for more information.

After the user has solved the CAPTCHA, the request should be retried with the CAPTCHA solution inserted into the X-Captcha-Key header. Additionally, if the captcha_session_id field is present, it must be inserted into the X-Captcha-Session-Id header. If the captcha_rqtoken field is present, it must be inserted into the X-Captcha-Rqtoken header.

If the solution is not accepted, the endpoint will return a 400 bad request with a response body similar to the original CAPTCHA response. Note that an otherwise valid solution may be rejected if the solution's bot score is too high or the captcha_rqdata/captcha_rqtoken fields are not properly handled.