Forter API Reference
Get Forter tokens and replay them on the site’s next request.
The Captcha.fun Forter API accepts kind, url and returns Forter token for the next request. Send the API_KEY header, create a solve with POST /v1/request, then poll GET /v2/response/{id} until ready is true.
What you’ll need
- Your API key
- The URL of the page where the challenge appears
- Optional:
forterSiteId,jsUrl - A proxy, if the result must come from your own IP (
forter_proxy)
Good to Know
The Forter product runs the site's Forter loader live and returns the token the protected flow expects on its next request.
The site id and JS bundle are discovered from the page; forterSiteId and jsUrl are optional annotations for deployments where they are known and not statically discoverable.
CDN-alias deployments whose loader host never appears on the page do not boot without jsUrl - pass it for that class of site.
Send the Challenge
Send the page details with your API key. You get a solve id back right away.
https://api.captcha.fun/v1/requestcurl -X POST https://api.captcha.fun/v1/request \
-H "API_KEY: CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"kind": "forter",
"url": "https://your-domain.example"
}'import requests
response = requests.post(
"https://api.captcha.fun/v1/request",
headers={
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Content-Type": "application/json",
"Accept": "application/json",
},
json={"kind": "forter", "url": "https://your-domain.example"},
)
print(response.status_code, response.json())const response = await fetch("https://api.captcha.fun/v1/request", {
method: "POST",
headers: {
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
"kind": "forter",
"url": "https://your-domain.example"
})
});
console.log(response.status, await response.json());Response
Returns the solve id. Use it to get the result.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"message": "Started Solving"
}{
"message": "invalid kind"
}Request fields6 body fields · 2 required
Wait for the Result
Use the solve id to fetch the result.
https://api.captcha.fun/v2/response/{id}Poll every second until ready is true.
https://api.captcha.fun/v1/response/{id}Long polling: the request stays open until the solve finishes or times out. Send it once and wait.
Example
curl -X GET https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000 \
-H "API_KEY: CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Accept: application/json"import requests
response = requests.get(
"https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000",
headers={
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Accept": "application/json"
}
)
print(response.status_code, response.json())const response = await fetch(
"https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000",
{
method: "GET",
headers: {
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Accept": "application/json"
}
}
);
const data = await response.json();
console.log(response.status, data);package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000", nil)
req.Header.Set("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(resp.StatusCode, result)
}import java.net.http.*;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000"))
.header("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync("https://api.captcha.fun/v2/response/550e8400-e29b-41d4-a716-446655440000");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{(int)response.StatusCode} {result}");Response
{
"ready": true,
"status": "SUCCESS",
"success": true,
"userAgent": "RETURNED_USER_AGENT",
"secUa": "RETURNED_SEC_CH_UA",
"token": "6F7G8H9I0J1K2L3M4N5O6P7Q8..."
}{
"message": "API_KEY Header Missing"
}Example
curl -X GET https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000 \
-H "API_KEY: CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Accept: application/json"import requests
response = requests.get(
"https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000",
headers={
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Accept": "application/json"
}
)
print(response.status_code, response.json())const response = await fetch(
"https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000",
{
method: "GET",
headers: {
"API_KEY": "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Accept": "application/json"
}
}
);
const data = await response.json();
console.log(response.status, data);package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000", nil)
req.Header.Set("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(resp.StatusCode, result)
}import java.net.http.*;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000"))
.header("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("API_KEY", "CAPFUN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync("https://api.captcha.fun/v1/response/550e8400-e29b-41d4-a716-446655440000");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{(int)response.StatusCode} {result}");Response
{
"status": "SUCCESS",
"success": true,
"userAgent": "RETURNED_USER_AGENT",
"secUa": "RETURNED_SEC_CH_UA",
"token": "6F7G8H9I0J1K2L3M4N5O6P7Q8..."
}{
"message": "API_KEY Header Missing"
}Request and response fields7 response fields
Replay the Request
Send the token where the site expects it, with the returned userAgent and from the same IP as the solve. Tokens are short-lived, so use them right away.
When using a successful result, preserve the returned userAgent as User-Agent and secUa as Sec-CH-UA.
Wrong or rejected result? Report the failed solve.