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

# Rewards

> GET /rewards — Available and claimed rewards, with optional per-wallet breakdown.

Query the rewards available in a point system, with optional per-wallet breakdown of eligibility and claim status.

***

## GET /rewards

### Request

```bash theme={null}
GET https://api.rewards.so/rewards?pointSystemId=your-uuid[&address=0xabc123...]
Authorization: Bearer rw_your_api_key
```

### Query parameters

| Parameter       | Type     | Required | Description                               |
| --------------- | -------- | -------- | ----------------------------------------- |
| `pointSystemId` | `string` | Yes      | UUID of the point system                  |
| `address`       | `string` | No       | If provided, returns per-wallet breakdown |

***

## Without `address` — all rewards

Returns every reward for the point system regardless of wallet.

### Response `200`

```json theme={null}
{
  "rewards": [
    {
      "id": "1ebeaa49-736a-43c8-97fb-69a406fbf892",
      "campaignId": "CMP-2WB39F",
      "campaignName": "Season 1 Airdrop",
      "tokenType": "ethereum",
      "tokenAddress": null,
      "chainId": 50312,
      "totalAmount": 0.5,
      "minPoints": 100,
      "maxPoints": 2600,
      "allocationType": "proportional",
      "status": "active",
      "claimDeadline": "2026-04-11T10:00:00.000Z",
      "createdAt": "2026-04-09T00:54:34.051Z"
    }
  ]
}
```

### Reward fields

| Field            | Type             | Description                                                                                                                                                                                                                             |
| ---------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`             | `string`         | Reward UUID                                                                                                                                                                                                                             |
| `campaignId`     | `string`         | Short human-readable campaign ID (e.g. `CMP-2WB39F`)                                                                                                                                                                                    |
| `campaignName`   | `string`         | Display name                                                                                                                                                                                                                            |
| `tokenType`      | `string`         | One of `ethereum`, `solana`, `bitcoin`, `usdc`, `usdt`, `custom`. A native chain coin is `ethereum` (e.g. SOMI on Somnia, ETH on Base). ERC-20 tokens use `custom` with a `tokenAddress`, or `usdc` / `usdt`. There is no `erc20` value |
| `tokenAddress`   | `string \| null` | ERC-20 contract address (set when `tokenType` is `custom`), null for native coins                                                                                                                                                       |
| `chainId`        | `number \| null` | EVM chain ID. See [Supported chains](#supported-chains) below                                                                                                                                                                           |
| `totalAmount`    | `number`         | Total token amount allocated to this reward                                                                                                                                                                                             |
| `minPoints`      | `number`         | Minimum points required to be eligible                                                                                                                                                                                                  |
| `maxPoints`      | `number \| null` | Points cap used in proportional distribution                                                                                                                                                                                            |
| `allocationType` | `string`         | `proportional` — allocation scales with points                                                                                                                                                                                          |
| `status`         | `string`         | `active` or `distributed`. Drafts and cancelled campaigns are never returned by this endpoint                                                                                                                                           |
| `claimDeadline`  | `string \| null` | ISO 8601 deadline, or null if open-ended                                                                                                                                                                                                |
| `createdAt`      | `string`         | ISO 8601 creation date                                                                                                                                                                                                                  |

### Supported chains

Reward campaigns are deployed on Somnia and Base only. The `chainId` returned above is always one of:

| Chain          | `chainId` | Native symbol |
| -------------- | --------- | ------------- |
| Somnia Mainnet | `5031`    | SOMI          |
| Somnia Testnet | `50312`   | STT           |
| Base Mainnet   | `8453`    | ETH           |
| Base Sepolia   | `84532`   | ETH           |

Ethereum L1 is not supported. (The [reputation score](/api-reference/score) is computed from a different, larger set of chains. Those are not chains where rewards can be deployed.)

***

## With `address` — per-wallet breakdown

Returns the same rewards split into three buckets based on the wallet's eligibility and claim history.

### Response `200`

```json theme={null}
{
  "address": "0x3d73d19f3daf0cd6ea798c49939336b00adff988",
  "totalPoints": 2610,
  "rewards": {
    "eligible": [
      {
        "id": "...",
        "campaignName": "Season 1 Airdrop",
        "totalAmount": 0.5,
        "allocatedAmount": 0.35,
        "status": "active",
        "claimDeadline": "2026-04-11T10:00:00.000Z"
      }
    ],
    "claimed": [
      {
        "id": "...",
        "campaignName": "Early Access Drop",
        "claimedAmount": 1.2,
        "claimedAt": "2026-04-08T14:00:00.000Z",
        "claimTxHash": "0xabc..."
      }
    ],
    "unavailable": [
      {
        "id": "...",
        "campaignName": "VIP Reward",
        "minPoints": 5000,
        "pointsNeeded": 2390
      }
    ]
  }
}
```

### Buckets

| Bucket        | Condition                                                  |
| ------------- | ---------------------------------------------------------- |
| `eligible`    | Wallet has a distribution allocated but hasn't claimed yet |
| `claimed`     | Wallet has already claimed this reward                     |
| `unavailable` | Wallet doesn't meet the minimum points requirement         |

### Extra fields in per-wallet mode

| Field             | Bucket        | Description                                                         |
| ----------------- | ------------- | ------------------------------------------------------------------- |
| `allocatedAmount` | `eligible`    | Token amount allocated to this wallet (null if not yet distributed) |
| `claimedAmount`   | `claimed`     | Token amount that was claimed                                       |
| `claimedAt`       | `claimed`     | ISO 8601 claim timestamp                                            |
| `claimTxHash`     | `claimed`     | On-chain transaction hash                                           |
| `pointsNeeded`    | `unavailable` | How many more points needed to reach `minPoints`                    |

***

## Claiming on-chain

Token rewards are distributed as a merkle airdrop: each eligible wallet claims its own allocation on-chain by submitting a merkle proof to the campaign contract. Two public helper endpoints support the claim flow. Both are **public** (no API key is required, since a proof is useless without the wallet's private key) and are rate-limited to 60 requests per minute per IP.

### GET /rewards/proof

Returns the merkle proof a wallet needs to claim its allocation for a specific airdrop.

#### Query parameters

| Parameter   | Type     | Required | Description                      |
| ----------- | -------- | -------- | -------------------------------- |
| `onchainId` | `number` | Yes      | The airdrop's on-chain id        |
| `chainId`   | `number` | Yes      | Chain the airdrop is deployed on |
| `address`   | `string` | Yes      | Wallet `0x` address claiming     |

Only `active` airdrops are matched.

#### Response `200`

```json theme={null}
{
  "distributionId": "b1f0c9a2-...",
  "amount": "350000000000000000",
  "merkleProof": ["0x2f...", "0x9c..."],
  "claimedAt": null
}
```

| Field            | Type             | Description                                                                                      |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------ |
| `distributionId` | `string`         | UUID of this wallet's distribution                                                               |
| `amount`         | `string`         | Allocation in base units (wei), using the token's real decimals. Pass this to the claim contract |
| `merkleProof`    | `string[]`       | Sibling hashes to submit with the claim                                                          |
| `claimedAt`      | `string \| null` | ISO timestamp if already claimed, else null                                                      |

#### Errors

| Status | Message                                  | Cause                                                   |
| ------ | ---------------------------------------- | ------------------------------------------------------- |
| `400`  | `Missing onchainId, chainId, or address` | A required query parameter is absent                    |
| `404`  | `Airdrop not found`                      | No active airdrop for that `onchainId` + `chainId`      |
| `404`  | `Address not eligible for this airdrop`  | Wallet has no allocation in this airdrop                |
| `404`  | `Merkle proof not yet generated`         | Distribution exists but its proof hasn't been built yet |
| `429`  | `Too many requests`                      | More than 60 requests/min from this IP                  |

### GET /rewards/claim-status

Returns every claimable reward for a wallet in a point system (active token airdrops and gift-card rewards) so a claim UI can list them in one call.

#### Query parameters

| Parameter       | Type     | Required | Description              |
| --------------- | -------- | -------- | ------------------------ |
| `address`       | `string` | Yes      | Wallet `0x` address      |
| `pointSystemId` | `string` | Yes      | UUID of the point system |

#### Response `200`

```json theme={null}
{
  "distributions": [
    {
      "kind": "token",
      "distributionId": "b1f0c9a2-...",
      "rewardId": "1ebeaa49-736a-43c8-97fb-69a406fbf892",
      "campaignName": "Season 1 Airdrop",
      "chainId": 50312,
      "contractAddress": "0x...",
      "onchainId": "1",
      "tokenAddress": null,
      "tokenDecimals": 18,
      "tokenSymbol": "STT",
      "claimDeadline": "2026-04-11T10:00:00.000Z",
      "amountWei": "350000000000000000",
      "claimedAt": null,
      "claimTxHash": null,
      "hasProof": true,
      "distributedAt": "2026-04-09T00:54:34.051Z"
    },
    {
      "kind": "giftcard",
      "distributionId": "c2a1d8b3-...",
      "rewardId": "7fd2...",
      "campaignName": "Holiday Gift Cards",
      "tierLabel": "$25",
      "revealed": false,
      "claimedAt": null,
      "distributedAt": "2026-04-09T00:54:34.051Z"
    }
  ]
}
```

Token entries (`kind: "token"`) carry the on-chain details needed to claim (`onchainId`, `chainId`, `contractAddress`, `amountWei`, and `hasProof`); fetch the matching proof from `/rewards/proof`. Gift-card entries (`kind: "giftcard"`) expose only the tier label and whether the code has been revealed, never the code itself.

***

## Code examples

<CodeGroup>
  ```ts Display eligible rewards theme={null}
  type RewardsForWallet = {
    address: string;
    totalPoints: number;
    rewards: {
      eligible: object[];
      claimed: object[];
      unavailable: object[];
    };
  };

  async function getWalletRewards(
    pointSystemId: string,
    address: string
  ): Promise<RewardsForWallet> {
    const url = new URL("https://api.rewards.so/rewards");
    url.searchParams.set("pointSystemId", pointSystemId);
    url.searchParams.set("address", address);

    const res = await fetch(url.toString(), {
      headers: { Authorization: `Bearer ${process.env.REWARDS_API_KEY}` },
    });

    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  }

  // Usage
  const data = await getWalletRewards(POINT_SYSTEM_ID, userAddress);
  console.log(`${data.rewards.eligible.length} rewards available to claim`);
  console.log(`${data.rewards.claimed.length} already claimed`);
  ```

  ```ts Check deadline theme={null}
  const eligible = data.rewards.eligible.filter((r: any) => {
    if (!r.claimDeadline) return true;
    return new Date(r.claimDeadline) > new Date();
  });
  ```
</CodeGroup>
