> For the complete documentation index, see [llms.txt](https://docs.apexsolutions.lol/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apexsolutions.lol/friendlycaptcha/workflow.md).

# Integration Workflow

The end-to-end FriendlyCaptcha integration: identify the site key, solve, and validate the token.

The step-by-step implementation of the FriendlyCaptcha flow. Each step describes what to do and why, with the actual requests against Apex. The full request and response reference lives in the **API reference**.

## Step 1: Identify the site key

Find the FriendlyCaptcha site key on the protected page. It appears in the widget configuration or the page source as a public key starting with `FCMU`:

```
FCMU08117KKFLBRL
```

The site key is tied to the site it was issued for, so use the one from the page you are solving — a key from another site will not work.

## Step 2: Build the solve

Call Apex with the site key and your proxy (required — the solver always runs through yours, never from Apex's servers):

{% tabs %}
{% tab title="Go" %}

```go
package main

import (
	"bytes"
	"encoding/json"
	"net/http"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"params": map[string]any{
			"sitekey": "FCMU08117KKFLBRL",
		},
		"proxy": "http://user:pass@host:port",
	})

	req, _ := http.NewRequest("POST", "https://fc.apexsolutions.lol/payload", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer your-api-key")
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
}
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

resp = requests.post(
    "https://fc.apexsolutions.lol/payload",
    headers={"Authorization": "Bearer your-api-key"},
    json={
        "params": {
            "sitekey": "FCMU08117KKFLBRL",
        },
        "proxy": "http://user:pass@host:port",
    },
)

print(resp.status_code, resp.json())
```

{% endtab %}

{% tab title="JS/TS" %}

```jsts
const resp = await fetch("https://fc.apexsolutions.lol/payload", {
  method: "POST",
  headers: {
    "Authorization": "Bearer your-api-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    params: {
      sitekey: "FCMU08117KKFLBRL",
    },
    proxy: "http://user:pass@host:port",
  }),
});

const data = await resp.json();
console.log(data);
```

{% endtab %}
{% endtabs %}

The response gives you the `token` under `result`.

## Step 3: Validate the token on the backend

Your client submits the token to the site's own API that guards the action (signup, login, etc.). The site backend validates it with FriendlyCaptcha via siteverify:

```python
import requests

# Send the token to the site's API, not to FriendlyCaptcha directly.
resp = requests.post(
    "https://{target}/api/signup",
    json={"frc-captcha-solution": token},
)
print(resp.status_code, resp.json())
```

The site's backend performs the siteverify call — you do not need the organization API key; the site keeps it server-side.

## Important Notes

{% hint style="info" %}
**Tokens are single-use and short-lived.** If a solve is rejected, the token was probably already consumed or expired — solve again. The `sitekey` must belong to the page you are solving, and the token must be submitted to the site that owns that key.
{% endhint %}
