# FraudNet service API

The FraudNet service is the inference container you run on your own infrastructure. It scores a transaction from your `ml_vector` view with a two-stage model: an autoencoder that measures how unusual the transaction is, and an XGBoost classifier that returns the probability of fraud. How to install and configure it is described in [FraudNet Federated Learning](https://developers.payout.tech/guides/fraudnet-fl-client.html).

The base URL is wherever you run the container, for example `http://localhost:4700`. Every response carries an `X-Request-ID` header; quote it when you report a problem.

## Authentication

`POST /api/v1/predict` requires a bearer token:

```http
Authorization: Bearer <token>
```

The token is a JWT that:

- is signed with HS256 using the service's `JWT_SECRET`;
- has a `scope` claim with `fraudnet` among its space-separated values, or a `scopes` claim (a list) containing `fraudnet`;
- has not expired, if it has an `exp` claim.

`GET /health` and `GET /` need no token.

| Status | `detail` | Cause |
| --- | --- | --- |
| `401` | `Not authenticated` | No `Authorization` header |
| `401` | `Token has expired` | `exp` is in the past |
| `401` | `Token verification failed: …` or `Token claims invalid: …` | Wrong signature or secret, malformed token, or an invalid claim |
| `403` | `Token missing required scope: fraudnet` | No `fraudnet` in `scope` or `scopes` |

## Endpoints

### Health check

`GET /health`

Reports whether the models are loaded and the database is reachable. Always returns `200`; check `status`.

```bash
curl http://localhost:4700/health
```

```json
{
  "status": "healthy",
  "models_loaded": true,
  "database_connected": true
}
```

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | `healthy` when the models are loaded and the database is reachable, otherwise `unhealthy` |
| `models_loaded` | boolean | The scaler and both models are loaded |
| `database_connected` | boolean | A test query on the database succeeded |

### Predict fraud

`POST /api/v1/predict`

Scores one transaction. The service reads the transaction and the customer's history of the last `MAX_LOOKBACK_DAYS` days from `ml_vector`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `txn_id` | string | yes | ID of the transaction in `ml_vector` |

```bash
curl -X POST http://localhost:4700/api/v1/predict \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"txn_id": "123456"}'
```

```json
{
  "txn_id": "123456",
  "fraud_probability": 0.8542,
  "reconstruction_error": 2.3456
}
```

| Field | Type | Description |
| --- | --- | --- |
| `txn_id` | string | Transaction ID from the request |
| `fraud_probability` | number | Probability of fraud from the classifier, from 0 to 1 |
| `reconstruction_error` | number | Mean squared reconstruction error of the autoencoder; higher means more unusual |

The response has no fraud label: compare `fraud_probability` with a threshold that fits your risk appetite.

| Status | Body | Cause |
| --- | --- | --- |
| `200` | Prediction | Success |
| `401`, `403` | `{"detail": "…"}` | See [Authentication](#authentication) |
| `404` | `{"detail": "Transaction 123456 not found"}` | No row with this `txn_id` in `ml_vector` |
| `422` | `{"detail": [ … ]}` | The body is not valid JSON, or `txn_id` is missing or not a string; `detail` lists the invalid fields |
| `500` | `{"detail": "Internal server error"}` | Feature engineering, model inference or the database failed; the service log has the details |
