# Server Verification

The browser SDK provides signals but cannot be trusted for enforcement. Use server-side verification for security decisions.

## Endpoint

```
POST /v1/shield/sessions/verify
Authorization: Bearer sec_xxx
```

## Request

```json
{
  "session_id": "sess_xxx",
  "event": "signup_attempt"
}
```

## Response

```json
{
  "verified": true,
  "risk_status": "available",
  "risk_score": 87,
  "recommendation": "challenge",
  "challenge_passed": false,
  "challenge_passed_at": null,
  "session": {
    "visitor_id": "vis_xxx",
    "first_seen_at": "2026-09-08T10:00:00.000Z",
    "last_seen_at": "2026-09-08T10:05:00.000Z",
    "event_count": 4,
    "pageview_count": 2,
    "risk_reasons": ["vpn_detected", "payment_attempt"],
    "ip_rotating": true,
    "asn_rotating": false,
    "country_rotating": false,
    "distinct_ips": 2,
    "distinct_asns": 1,
    "distinct_countries": 1,
    "ips": ["203.0.113.7", "203.0.113.9"],
    "countries": ["IL"],
    "last_ip": "203.0.113.9",
    "last_country": "IL",
    "last_country_name": "Israel",
    "last_asn": 1680,
    "last_asn_name": "Partner",
    "last_organization": "Partner Communications",
    "network": {
      "vpn": true, "proxy": false, "tor": false, "relay": false,
      "hosting": false, "datacenter": false, "malicious": false
    }
  }
}
```

`session` is the picture Shield has of the whole session, for your own
records — an order notification, a fraud queue, a CRM note. `risk_reasons`
are the distinct reasons across every event; `ip_rotating`, `asn_rotating`
and `country_rotating` are true when the session was seen from more than one
IP, network or country; `network` flags are true if *any* event of the
session came from that kind of address; `last_*` describe the most recent
event. `ips` holds at most 10 addresses. Identity is not included — your
backend already knows who its customer is.

`challenge_passed` is true once the visitor completed a Cloudflare Turnstile
challenge that Shield verified for this session (see
[In-Page Enforcement](https://www.findip.net/docs/shield/enforcement.md)). A backend that accepts `challenge`
only when `challenge_passed` is true, and rejects `block`, turns the in-page
friction into a decision no client can bypass. `risk_status` is `unknown`
when no event of the session had IP intelligence; treat it as `monitor`,
never as safe.

## Recommended Flow

1. Browser SDK tracks `signup_attempt` and receives initial risk signal
2. Your backend receives the signup request with `session_id`
3. Backend calls `/v1/shield/sessions/verify` with secret API key
4. Backend enforces decision (allow, challenge, block) based on verified response

## Why Server Verification

- Browser payloads can be spoofed
- Secret API keys must never be in client-side code
- Server verification provides authoritative risk decisions

## Integration Example

```js
// Frontend: include session ID in signup request
const { sessionId } = FindIP.getSession();
await fetch('/api/signup', {
  method: 'POST',
  body: JSON.stringify({ email, password, findip_session_id: sessionId }),
});
```

### Plain HTML forms

For a form the browser posts itself, let the SDK add the session ID as a hidden field (SDK 1.11.0 and later):

```js
FindIP.init({ siteKey: 'pub_xxxxxxxxx', sessionField: true });
```

Every form that POSTs to your own origin then carries `findip_session=<session id>`; read it on the server like any other form field. Pass a string to choose another name. This also works for visitors whose browser blocks cookies, where reading the `_fip_sid` cookie on the server finds nothing.

```js
// Backend: verify before creating account
const verify = await fetch('https://shield.findip.net/v1/shield/sessions/verify', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FINDIP_SHIELD_SECRET_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    session_id: req.body.findip_session_id,
    event: 'signup_attempt',
  }),
});
```

---

Canonical page: https://www.findip.net/docs/shield/server-verification · Markdown: https://www.findip.net/docs/shield/server-verification.md · All Shield docs in one file: https://www.findip.net/llms-full.txt
