---
title: 'Custom Rewards API'
description: 'Configure dynamic rewards for tokens using external APIs or CSV files'
---

> **For AI agents:** the complete documentation index is at [llms.txt](https://docs.snagsolutions.io/llms.txt). Append `.md` to any page URL for its markdown version.

## **Overview**

The Custom Rewards API feature allows you to define dynamic rewards for individual tokens instead of using fixed reward amounts. This feature is available for the following loyalty rule types:

- [Token Hold](https://docs.snagsolutions.io/loyalty/rules/token-hold)
- [Token Purchase](https://docs.snagsolutions.io/loyalty/rules/token-purchase) 
- [Token Sale](https://docs.snagsolutions.io/loyalty/rules/token-sale)
- [Token Mint](https://docs.snagsolutions.io/loyalty/rules/token-mint)

You can provide custom rewards through either:
- **API Endpoint**: Real-time data from your external service
- **CSV File**: Static data uploaded to a publicly accessible URL

## **API Configuration**

### **API Endpoint Setup**

When using an API endpoint, you need to provide:

- **Custom Rewards URL**: Your API endpoint URL
- **API Key**: Authentication key for your API

<Warning>
The API endpoint must be accessible from Snag's servers and return data in the specified format. Ensure your API is reliable and has appropriate rate limiting.
</Warning>

### **API Response Format**

Your API must return a paginated response with the following structure:

Snag will make requests like this:

```bash
curl -X GET 'https://your-api.com/rewards' \
  -H 'x-api-key: YOUR_API_KEY'
```

Your API should return a JSON response in this format:

```json
{
  "count": 1000,
  "next": "https://your-api.com/rewards?page=2",
  "previous": null,
  "results": [
    {
      "tokenId": "123",
      "reward": 50,
      "points": 50,
      "bonus": 50
    },
    {
      "tokenId": "456", 
      "reward": 100,
      "points": 100,
      "bonus": 100
    }
  ]
}
```

### **Response Field Requirements**

<ResponseField name="count" type="integer" required>
Total number of reward records available across all pages.
</ResponseField>

<ResponseField name="next" type="string | null">
URL for the next page of results. Set to `null` for the last page.
</ResponseField>

<ResponseField name="previous" type="string | null">
URL for the previous page of results. Set to `null` for the first page.
</ResponseField>

<ResponseField name="results" type="array" required>
Array of reward objects for the current page.

<Expandable title="Reward object properties">
  <ResponseField name="tokenId" type="string" required>
  Unique identifier for the token. Can be any string format (e.g., "123", "0x123", "hape_123").
  </ResponseField>
  
  <ResponseField name="reward" type="number" required>
  Reward amount in points for this token. Must be a positive number.
  </ResponseField>
  
  <ResponseField name="points" type="number">
  Alternative field name for reward amount. Used if `reward` is not present.
  </ResponseField>
  
  <ResponseField name="bonus" type="number">
  Alternative field name for reward amount. Used if neither `reward` nor `points` are present.
  </ResponseField>
</Expandable>
</ResponseField>

### **Pagination Support**

The API supports pagination through the `next` field. Snag will automatically fetch all pages until `next` is `null`.

### **Request Details**

Snag's servers will make the following requests to your API:

**Initial Request:**
```bash
curl -X GET 'https://your-api.com/rewards' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'User-Agent: Snag-Loyalty-System/1.0'
```

**Paginated Request:**
```bash
curl -X GET 'https://your-api.com/rewards?page=2' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'User-Agent: Snag-Loyalty-System/1.0'
```

**Request Headers:**
- `x-api-key`: The API key you provided during configuration
- `User-Agent`: `Snag-Loyalty-System/1.0`

**Request Behavior:**
- Snag will make sequential requests to your API
- Each request has a 15-minute timeout
- Snag will follow the `next` URL from your response until it's `null`
- No query parameters are required for the initial request
- Your API should handle pagination through the `next` field in responses

## **CSV File Configuration**

As an alternative to API endpoints, you can provide custom rewards through a CSV file:

### **CSV Format Requirements**

The CSV file must have the following structure:

<CodeGroup>
```csv Example CSV
tokenId,reward
123,50
456,100
789,25
```

```csv Alternative Format
tokenId,points
0x123,75
0x456,150
0x789,30
```
</CodeGroup>

### **CSV Field Requirements**

<ResponseField name="tokenId" type="string" required>
Unique identifier for the token. Can be any string format.
</ResponseField>

<ResponseField name="reward" type="number" required>
Reward amount in points for this token. Must be a positive number.
</ResponseField>

## **Error Handling**

### **API Errors**

If the API is unavailable or returns an error:

- The loyalty rule will continue to execute with default rewards
- An error will be logged for debugging
- Users will receive rewards based on the rule's standard configuration

### **Data Validation**

Invalid reward data is automatically filtered out:

- Tokens with missing or invalid `tokenId` are skipped
- Rewards with zero or negative values are ignored
- Malformed API responses are logged and skipped

<Warning>
Always test your API endpoint thoroughly before deploying to production. Ensure it returns valid data and handles edge cases properly.
</Warning>

## **Performance Considerations**

### **API Rate Limits**

- Snag will make sequential requests to your API
- Each request includes a 15-minute timeout
- Consider implementing appropriate rate limiting on your API

### **Data Size**

- Large datasets are handled through pagination
- Consider caching frequently accessed data
- Optimize your database queries for better performance

### **Reliability**

- Ensure your API has high uptime
- Implement proper error handling and logging
- Consider using a CDN for CSV files

## **Security Best Practices**

### **API Authentication**

- Use secure API keys with appropriate permissions
- Rotate keys regularly
- Implement IP whitelisting if possible

### **Data Validation**

- Validate all input data on your API
- Sanitize token IDs and reward values
- Implement proper error responses

<Check>
Your custom rewards API is ready when:
- API returns valid JSON with required fields
- Pagination works correctly
- Authentication is properly configured
- Error handling is implemented
</Check>
