Friendly Captcha
Match the widget version before requesting its proof. Find the widget's public site key and identify its SDK version. v1 and v2 use different form response field names.
{
"clientKey": "capzy_YOUR_API_KEY",
"task": {
"type": "FriendlyCaptchaTaskProxyLess",
"websiteURL": "https://example.com/signup",
"websiteKey": "FCMST5VWFSAY7ELV"
}
}Illustrative values. Replace the inputs with values from your current integration.
Check the site key and widget version.
Find the widget's public site key and identify its SDK version. v1 and v2 use different form response field names.
Your API key authenticates Capzy.
Provider keys, challenge IDs, images, and session values belong inside task.
Copy data-sitekey from the existing widget.
- In Elements, locate the Friendly Captcha widget and its data-sitekey attribute.
- Copy the complete public key into websiteKey and the form page URL into websiteURL.
- If you own the widget, compare the key with your Friendly Captcha application configuration.
<div class="frc-captcha" data-sitekey="YOUR_FRIENDLY_PUBLIC_KEY"></div>This illustrates the public attribute; keep the existing integration's markup and configuration.
How Friendly Captcha works
Friendly Captcha is a privacy-first, GDPR-friendly captcha that shows no images or puzzles. Instead of a challenge, the visitor's browser runs a proof-of-work computation (a hash brute-force) in the background and submits a token. Sites verify that token server-side. There are two widget generations: v1 (the friendly-challenge SDK) and v2 (the frcapi.com SDK).
We load the widget and run the same proof-of-work the browser would, then hand back the solution token. Friendly Captcha isn't IP-bound, so no proxy is required — send websiteKey + websiteURL and, if the site uses the newer widget, version: "2".
- Runs the real proof-of-work — the same token a browser would submit
- Supports v1 (friendly-challenge) and v2 (frcapi.com) widgets
- No proxy required — Friendly Captcha isn't IP-bound
- Fast: most solves complete as soon as the PoW finishes
Know what goes in.
Choose a field to see its purpose, where to get it, and its place in the request. Optional values omitted from the example can be added when your flow uses them.
The request below follows your selected task configuration.
Request authentication
Required task inputs
Optional context
websiteURL
stringRequiredThe page URL where the Friendly Captcha widget loads (Friendly verifies the solution against the domain)
Copy the full page URL from the address bar or the document request in Network, including the path where this flow runs.
Open the input guidehttps://example.com/signup{
"clientKey": "capzy_YOUR_API_KEY",
"task": {
"type": "FriendlyCaptchaTaskProxyLess",
"websiteURL": "https://example.com/signup",
"websiteKey": "FCMST5VWFSAY7ELV"
}
}The selected field is highlighted when present. Preserve the declared value type and current challenge context.
Make your first request.
Create the task, keep its taskId, and poll until status is ready. Then read the selected variant's solution.
- Create the task
Send
clientKeyand the selectedtaskto/createTaskfrom your server. Keep the returnedtaskId. - Wait for the solution
Send that same key and ID to
/getTaskResult. While processing, wait two seconds before checking again. Stop on Ready or an error. - Apply the result
Place solution.token into frc-captcha-response for v2 or frc-captcha-solution for v1, then use the matching server verification flow.
import json, os, time
import requests
API = "https://api.capzy.ai"
KEY = os.environ["CAPZY_API_KEY"]
task = json.loads("{\"type\":\"FriendlyCaptchaTaskProxyLess\",\"websiteURL\":\"https://example.com/signup\",\"websiteKey\":\"FCMST5VWFSAY7ELV\"}")
def call(path, payload):
response = requests.post(f"{API}/{path}", json={"clientKey": KEY, **payload}, timeout=30)
response.raise_for_status()
data = response.json()
if data.get("errorId", 0) or data.get("status") == "failed":
raise RuntimeError(data.get("errorDescription") or data.get("errorCode") or "Task failed")
return data
created = call("createTask", {"task": task})
for attempt in range(60):
result = call("getTaskResult", {"taskId": created["taskId"]})
if result.get("status") == "ready":
solution = result["solution"]
print(solution)
break
time.sleep(2)
else:
raise TimeoutError("Task is still processing; keep the taskId to check it later.")
Before runningReplace all illustrative inputs with your captured values. Set CAPZY_API_KEY in your environment. Install requests with pip install requests.
Polling and failuresThe example checks HTTP/API failures, uses 30-second request timeouts, and stops after 60 result checks. Retain taskId if your task is still processing.
Understand what comes back.
Follow this task from creation to completion. Response fields and usage follow your selected request variant.
Friendly Captcha response
Place solution.token into frc-captcha-response for v2 or frc-captcha-solution for v1, then use the matching server verification flow.
- string
- The proof-of-work solution token. Set it as the value of the hidden frc-captcha-response input, then submit the form
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "0.ABCDEfghIJKL1234567890abcdefghij...<friendly PoW solution>..."
}
}Illustrative values. Additional metadata may be returned; only Ready contains a completed solution.
Friendly Captcha v2
v2 uses frc-captcha-response by default. Match the widget version and any custom form-field-name setting.
Execution context result is the parsed Ready response from the polling example. session, when referenced, is your existing requests.Session (or browser-compatible session) with the original cookie jar, headers, and solving proxy configured in session.proxies for both http and https. Keep this client for the complete flow. task is the task object you submitted. For Shape, action_body is the original protected request body as bytes or a string, with its original Content-Type in session.headers. Install curl_cffi when the fragment imports it; match the target's required browser/TLS identity.
token = result["solution"]["token"]
# Keep the original form's action, other fields, and session.
response = session.post("https://target.example.com/submit", data={
"frc-captcha-response": token,
# Add the original application form fields here.
}, timeout=30)When something doesn't work.
Check your captured values, the selected variant, and the response before starting another task.
How do I use the token?
Set the value of the hidden input named frc-captcha-response (or frc-captcha-solution on older widgets) to the token, then submit your form. Your backend verifies it against Friendly's siteverify endpoint with your API key.
v1 or v2 — which do I send?
Look at the script the page loads: the friendly-challenge CDN is v1 (the default); an frcapi.com / api.friendlycaptcha.com script is v2. Set version: "2" for the newer widget so the token format matches.
Connect Friendly Captcha to your workflow.
Get your Capzy API key and use this guide's integration.
FriendlyCaptchaTaskProxyLess · Live configuration