:::endpoint GET /v1/admin/fraud/detection

The Detectors screen of the website: whether fraud detection runs, how
sensitive the scores are, who hears about a flag, when a score alone suspends
somebody, what Restrict takes away, and every detector with its level and
thresholds and how much it caught.

The detectors are the platform's, the same 24 for every firm and always in
this order. A firm chooses only their levels and thresholds. One detector with
its open flags and exceptions is [a detector](/docs/api/admin/fraud-detector),
and a change is [a save](/docs/api/admin/fraud-detection-update).

Needs a firm. Our own staff name one with the `Propper-Workspace` header.

## Request

```bash
curl "https://api.proppertrading.com/v1/admin/fraud/detection" \
  -H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f" \
  -H "Propper-Workspace: acme"
```

## Response

Shortened to two of the 24 detectors:

{
    "data": {
        "object": "fraud_detection",
        "global": {
            "enabled": true,
            "sensitivity": "balanced",
            "notify_admins": true,
            "escalation_enabled": true,
            "escalation_score": 80
        },
        "restrict": {
            "block_new_orders": true,
            "hold_payouts": true,
            "block_purchases": false,
            "hold_affiliate_payouts": false
        },
        "standing": {
            "restricted": 6,
            "suspended": 1
        },
        "detectors": [
            {
                "object": "fraud_detector",
                "key": "vpn",
                "name": "VPN",
                "description": "A connection through a known commercial VPN exit.",
                "category": "ip",
                "default_level": "flag",
                "access": true,
                "group": false,
                "level": "flag",
                "params": {},
                "overrides": 1,
                "flags_30d": 11,
                "open_flags": 12,
                "exposure": {
                    "traders": 0
                },
                "fields": []
            },
            {
                "object": "fraud_detector",
                "key": "max_countries",
                "name": "Too many countries",
                "description": "One account logging in from more countries than one person plausibly visits.",
                "category": "geo",
                "default_level": "flag",
                "access": false,
                "group": false,
                "level": "flag",
                "params": {
                    "max_countries": 3,
                    "window_days": 30
                },
                "overrides": 1,
                "flags_30d": 1,
                "open_flags": 1,
                "exposure": {
                    "by_country_count": {
                        "1": 11
                    }
                },
                "fields": [
                    {
                        "key": "max_countries",
                        "type": "integer",
                        "default": 3,
                        "min": 1,
                        "max": 50,
                        "unit": "",
                        "options": [],
                        "overridable": true,
                        "label": "Countries allowed",
                        "hint": "Distinct countries an account may log in from inside the window."
                    },
                    {
                        "key": "window_days",
                        "type": "integer",
                        "default": 30,
                        "min": 1,
                        "max": 90,
                        "unit": "d",
                        "options": [],
                        "overridable": true,
                        "label": "Window",
                        "hint": "The rolling period the countries are counted over."
                    }
                ]
            }
        ]
    },
    "meta": {
        "request_id": "req_01m50zcm1n6trjh6w07q0fp3mm"
    }
}

| Field       | Description |
| ----------- | ----------- |
| `global`    | `enabled`, the master switch: off, no detector runs and nothing is enforced. `sensitivity` is `lenient`, `balanced`, `strict` or `lockdown`, a multiplier on every score (0.85, 1, 1.15 and 1.3). `notify_admins` sends admins a notice when a flag needs a decision. `escalation_enabled` and `escalation_score` (30 to 100) suspend an account whose flag scores that high, whatever the detector's level |
| `restrict`  | What a restriction takes away: `block_new_orders`, `hold_payouts`, `block_purchases`, `hold_affiliate_payouts` |
| `standing`  | Traders `restricted` right now, and flags that `suspended` somebody |
| `detectors` | Every detector, see below |

| Detector field  | Description |
| --------------- | ----------- |
| `key`           | Stored on every flag it raises, and never changes |
| `name`, `description` | In the admin's language |
| `category`      | `ip`, `geo`, `device`, `linking` or `affiliate` |
| `default_level` | The level of a firm that never chose one |
| `access`        | Decides who may connect at all. At `block` it refuses the session instead of suspending the account |
| `group`         | One flag names several accounts at once |
| `level`         | `off`, `monitor`, `flag`, `restrict` or `block` |
| `params`        | The thresholds as the firm set them, by key. `{}` for a detector without any |
| `fields`        | What each threshold is: `type` (`integer`, `choice` or `countries`), `min` and `max`, `unit` (`min`, `s`, `d`, `km`, `km/h`, `%` or empty), the `options` of a choice, the `default`, `overridable` when an override may change it for one trader, and a `label` and `hint` in words |
| `overrides`     | Overrides in force on this detector |
| `flags_30d`     | Flags it raised in the last 30 days |
| `open_flags`    | Its flags that are still active, Monitor ones included |
| `exposure`      | Who it would catch, for six detectors only, over the last 30 days. The four anonymiser detectors give `traders` on such an address. The country policy gives `by_country`, traders per country code, to count what a policy would catch. Too many countries gives `by_country_count`, traders by how many countries they used. Null for the rest |

## Errors

| Status | Code                      | Meaning                                                                         |
| ------ | ------------------------- | ------------------------------------------------------------------------------- |
| 400    | `workspace_required`      | Asked by our own staff without naming a firm                                    |
| 401    | `invalid_token`           | Not a token, or the secret does not match                                       |
| 401    | `revoked_token`           | Signed out here or from another device                                          |
| 401    | `expired_token`           | Ninety days without use, or a set expiry passed                                 |
| 403    | `admin_access_required`   | This account no longer helps run the environment                                |
| 403    | `insufficient_scope`      | This device does not hold `admin:read`                                          |
| 403    | `workspace_not_permitted` | The `Propper-Workspace` header names an environment this account cannot act in  |
| 403    | `forbidden`               | Without `view_fraud`                                                            |