> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Rewards API

> REST endpoints for rewards, endorsements, Flashpoints, and stats

REST API for querying user rewards, configuring reward endorsements, reading Flashpoints data, and checking system stats.

## Base URL

```
https://rewards.flashnet.xyz
```

All endpoints are prefixed with `/v1`.
Swagger docs are available at `/docs`.

***

## Rewards

### Get Rewards Leaderboard

Returns list of users sorted by USDB balance with their rewards info.

```bash theme={null}
GET /v1/rewards/?limit=100&offset=0
```

**Parameters:**

* `limit` - Max results (default 100, max 500)
* `offset` - Pagination offset

**Response:**

```json theme={null}
{
  "rewards": [
    {
      "pubkey": "02abc...def",
      "usdbBalance": {
        "raw": "10000000000",
        "display": "10000"
      },
      "volumeUtcToday": {
        "swapSats": 5000000,
        "swapCount": 12
      },
      "rewardsBracket": 3,
      "rewardsPercent": 5.0,
      "estimatedSatsToday": 1370
    }
  ],
  "meta": {
    "total": 830,
    "limit": 100,
    "offset": 0
  }
}
```

### Get User Summary

Returns current USDB balance, today's volume, rewards bracket, and projected rewards.

```bash theme={null}
GET /v1/rewards/:pubkey
```

**Response:**

```json theme={null}
{
  "pubkey": "02abc...def",
  "usdbBalance": {
    "raw": "10000000000",
    "display": "10000"
  },
  "volumeUtcToday": {
    "swapSats": 5000000,
    "swapCount": 12
  },
  "rewardsBracket": 3,
  "rewardsPercent": 5.0,
  "estimatedSatsToday": 1370
}
```

Excluded addresses (LP pools, burn addresses) return a `400` status with `{ "reason": "This address is excluded and does not earn rewards" }`.

**Rewards Brackets:**

| Bracket | `volumeUtcToday.swapSats` Threshold | Rewards |
| ------- | ----------------------------------- | ------- |
| 0       | `>= 0`                              | 3.5%    |
| 1       | `>= 500000`                         | 4.0%    |
| 2       | `>= 2500000`                        | 4.5%    |
| 3       | `>= 5000000`                        | 5.0%    |
| 4       | `>= 10000000`                       | 5.5%    |
| 5       | `>= 25000000`                       | 6.0%    |

### Get Payout History

Returns paginated list of rewards payouts for a user.

```bash theme={null}
GET /v1/rewards/:pubkey/payouts?limit=30&offset=0
```

**Parameters:**

* `limit` - Max results (default 30)
* `offset` - Pagination offset

**Response:**

```json theme={null}
{
  "pubkey": "02abc...def",
  "payouts": [
    {
      "day": "2026-02-09",
      "usdbBalance": {
        "raw": 10000000000,
        "display": 10000
      },
      "volume": {
        "swapSats": 5000000
      },
      "rewardsBracket": 3,
      "annualRewardsBps": 500,
      "rewardsPayoutSats": 1020,
      "endorsementsPayoutSats": 350,
      "payoutSats": 1370,
      "status": "paid",
      "txId": "abc123...",
      "createdAt": "2026-02-09T00:05:00Z",
      "paidAt": "2026-02-10T00:05:00Z"
    }
  ],
  "pagination": { "total": 45, "limit": 30, "offset": 0 }
}
```

`payoutSats` is the sum of `rewardsPayoutSats` and `endorsementsPayoutSats`.

***

## Endorsements

Endorsements let a pubkey direct part of its future daily rewards payout to one or more recipient pubkeys.

### Canonical YAML Templates (for Signing)

Create and update both use `action: upsert`. The API creates a new record or updates the existing `(endorser, to)` pair.

**Create endorsement template:**

```yaml theme={null}
kind: rewards_endorsement
version: 1
action: upsert
endorser: "<endorser_pubkey_hex_66_chars>"
to: "<recipient_pubkey_hex_66_chars>"
ratioBps: <1_to_10000>
timestampNonce: "<uuidv7>"
```

**Update endorsement template:**

```yaml theme={null}
kind: rewards_endorsement
version: 1
action: upsert
endorser: "<endorser_pubkey_hex_66_chars>"
to: "<existing_recipient_pubkey_hex_66_chars>"
ratioBps: <new_ratio_1_to_10000>
timestampNonce: "<uuidv7>"
```

**Delete endorsement template:**

```yaml theme={null}
kind: rewards_endorsement
version: 1
action: delete
endorser: "<endorser_pubkey_hex_66_chars>"
to: "<recipient_pubkey_hex_66_chars>"
timestampNonce: "<uuidv7>"
```

The client signs the SHA-256 hash of the YAML payload with the endorser private key and sends that signature as hex.

### Get Endorsements

```bash theme={null}
GET /v1/rewards/:pubkey/endorsements
```

**Response:**

```json theme={null}
{
  "endorser": "02abc...def",
  "endorsements": [
    {
      "to": "03fed...cba",
      "ratioBps": 3000
    },
    {
      "to": "02012...999",
      "ratioBps": 2000
    }
  ]
}
```

### Create or Update Endorsement

Creates or updates one endorsement rule for `to` under the endorser.

```bash theme={null}
POST /v1/rewards/:pubkey/endorsements
```

**Request body:**

```json theme={null}
{
  "endorser": "02abc...def",
  "to": "03fed...cba",
  "ratioBps": 3000,
  "timestampNonce": "01958d67-2d1a-7a8a-bf8a-5b0a947f8f11",
  "signature": "30440220..."
}
```

**Signing payload (canonical YAML):**

```yaml theme={null}
kind: rewards_endorsement
version: 1
action: upsert
endorser: "02abc...def"
to: "03fed...cba"
ratioBps: 3000
timestampNonce: "01958d67-2d1a-7a8a-bf8a-5b0a947f8f11"
```

The API verifies the signature against the endorser pubkey using secp256k1 over the SHA-256 hash of this YAML payload.

**Response:**

```json theme={null}
{
  "endorser": "02abc...def",
  "endorsements": [
    {
      "to": "03fed...cba",
      "ratioBps": 3000
    }
  ]
}
```

### Delete Endorsement

Deletes one endorsement mapping for the endorser.

```bash theme={null}
DELETE /v1/rewards/:pubkey/endorsements/:toPubkey
```

**Request body:**

```json theme={null}
{
  "timestampNonce": "01958d67-41c1-7dd4-8aa3-ef3575a84ab5",
  "signature": "30450221..."
}
```

**Signing payload (canonical YAML):**

```yaml theme={null}
kind: rewards_endorsement
version: 1
action: delete
endorser: "02abc...def"
to: "03fed...cba"
timestampNonce: "01958d67-41c1-7dd4-8aa3-ef3575a84ab5"
```

**Response:**

```json theme={null}
{
  "ok": true
}
```

### Endorsement Rules and Validation

* `pubkey`, `endorser`, and `to` must be 66-char compressed pubkey hex strings.
* `endorser` in body must match `:pubkey` in the route.
* `ratioBps` must be between `1` and `10000`.
* Sum of all active endorsement ratios for an endorser cannot exceed `10000`.
* Endorser cannot endorse to the same pubkey.
* `timestampNonce` must be UUIDv7 and within a 5-minute window.
* Each nonce can only be used once (replay protected).

Common `400` errors:

* `{ "error": "Body endorser must match route pubkey" }`
* `{ "error": "Cannot endorse to the same pubkey. Use rewards payee reassignment instead." }`
* `{ "error": "Total endorsement ratio cannot exceed 10000 bps" }`
* `{ "error": "Nonce has already been used" }`
* `{ "error": "Signature verification failed" }`

***

## Flashpoints

### Get Points Leaderboard

Returns list of users sorted by current Flashpoints with their point balances and volume.

```bash theme={null}
GET /v1/points/?limit=100&offset=0
```

**Parameters:**

* `limit` - Max results (default 100, max 500)
* `offset` - Pagination offset

**Response:**

```json theme={null}
{
  "points": [
    {
      "pubkey": "02abc...def",
      "currentPoints": 1250000,
      "lifetimePoints": 1500000,
      "rank": 1,
      "projectedDailyPoints": 1236,
      "volumeUtcToday": {
        "swapSats": 5000000,
        "liquiditySats": 0
      }
    }
  ],
  "meta": {
    "total": 830,
    "limit": 100,
    "offset": 0
  }
}
```

### Get User Points

Returns Flashpoints balance, rank, and projected daily earnings.

```bash theme={null}
GET /v1/points/:pubkey
```

**Response:**

```json theme={null}
{
  "pubkey": "02abc...def",
  "currentPoints": 1250000,
  "lifetimePoints": 1500000,
  "rank": 42,
  "projectedDailyPoints": 1236,
  "volumeUtcToday": {
    "swapSats": 5000000,
    "liquiditySats": 0
  }
}
```

### Get Points History

Returns paginated list of point earning events.

```bash theme={null}
GET /v1/points/:pubkey/history?limit=30&offset=0
```

**Parameters:**

* `limit` - Max results (default 30)
* `offset` - Pagination offset

**Response:**

```json theme={null}
{
  "pubkey": "02abc...def",
  "events": [
    {
      "type": "daily_award",
      "points": 1236,
      "day": "2026-02-09",
      "metadata": {},
      "createdAt": "2026-02-10T00:05:00Z"
    }
  ],
  "pagination": { "total": 45, "limit": 30, "offset": 0 }
}
```

***

## Stats

### Get Global Stats

Returns system-wide statistics.

```bash theme={null}
GET /v1/stats
```

**Response:**

```json theme={null}
{
  "usdb": {
    "totalHolders": 830,
    "totalBalanceRaw": 2500000000000,
    "totalBalanceUsdb": 2500000.00
  },
  "volume24h": {
    "activeTraders": 145,
    "totalVolumeSats": 850000000,
    "totalSwaps": 2340
  },
  "payouts": {
    "pendingCount": 12,
    "pendingSats": 140000,
    "totalPaidSats": 5000000
  },
  "processor": {
    "lastPointsDay": "2026-02-09",
    "lastPayoutDay": "2026-02-09"
  },
  "updatedAt": "2026-02-10T12:34:56Z"
}
```

### Health Check

```bash theme={null}
GET /v1/stats/health
```

**Response:**

```json theme={null}
{
  "status": "healthy",
  "lastPayoutDay": "2026-02-09",
  "lastPointsDay": "2026-02-09"
}
```

Returns `"status": "degraded"` if either payout or points processing is behind.

***

## Error Handling

Validation errors usually return:

```json theme={null}
{
  "error": "Invalid pubkey format. Expected 66 character hex string."
}
```

Excluded pubkeys on `GET /v1/rewards/:pubkey` return:

```json theme={null}
{
  "reason": "This address is excluded and does not earn rewards"
}
```

Server-side errors may return:

```json theme={null}
{
  "error": "INTERNAL_SERVER_ERROR",
  "message": "..."
}
```

Common status codes:

* `400` - Bad request (validation errors, excluded addresses)
* `404` - Not found
* `500` - Internal server error
