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

# Custom Rewards API

> Configure dynamic rewards for tokens using external APIs or CSV files

<head>
  <script type="application/ld+json">
    {JSON.stringify({
            "@context": "https://schema.org",
            "@type": "BreadcrumbList",
            "itemListElement": [
              {"@type": "ListItem", "position": 1, "name": "Home", "item": "https://docs.snagsolutions.io/welcome"},
              {"@type": "ListItem", "position": 2, "name": "Loyalty", "item": "https://docs.snagsolutions.io/loyalty/loyalty-overview"},
              {"@type": "ListItem", "position": 3, "name": "Advanced workflows", "item": "https://docs.snagsolutions.io/loyalty/managing-user-accounts"},
              {"@type": "ListItem", "position": 4, "name": "Custom rewards API"}
            ]
          })}
  </script>
</head>

## **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](/loyalty/rules/token-hold)
* [Token Purchase](/loyalty/rules/token-purchase)
* [Token Sale](/loyalty/rules/token-sale)
* [Token Mint](/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 theme={null}
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 theme={null}
{
  "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 theme={null}
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 theme={null}
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 theme={null}
  tokenId,reward
  123,50
  456,100
  789,25
  ```

  ```csv Alternative Format theme={null}
  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>
