> For the complete documentation index, see [llms.txt](https://docs.coinlocally.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coinlocally.com/affiliate.md).

# Affiliate

### 1. Overview

The Coinlocally Affiliate API allows affiliates to retrieve referral information for their referred users.

To use the API, each affiliate must first obtain an **API Key** and **Secret Key**. These credentials are used to authenticate all requests by generating a secure **HMAC SHA256 signature**.

### 2. Authentication

#### Required Headers

Every request must include the following headers:

| Header        | Description                                  |
| ------------- | -------------------------------------------- |
| `x-api-key`   | Affiliate’s API key                          |
| `x-signature` | HMAC SHA256 signature of payload + timestamp |
| `x-timestamp` | Current timestamp in milliseconds            |

#### Signature Generation

```js
signature = HmacSHA256(payload, secretKey).toString(crypto.enc.Hex)
```

Where:

* **payload** = `JSON.stringify(requestBody) + timestamp`
* **secretKey** = Your affiliate secret key

### 3. API Endpoint

**URL**:

```
https://official.coinlocally.com/v1/affiliates/referredInfo
```

**Method**:

```
POST
```

### 4. Request

#### Body Parameters

| Field    | Type   | Required | Description                      |
| -------- | ------ | -------- | -------------------------------- |
| `userId` | number | ✅        | The unique ID of the user        |
| `email`  | string | ❌        | The email of the user (optional) |

#### Example Request Body

```json
{
  "userId": 12345
}
```

OR (with email):

```json
{
  "userId": 12345,
  "email": "user@example.com"
}
```

### 5. Response

#### Example Response

```json
{
  "error": false,
  "message": null,
  "result": {
    "isDirectReferral": true,
    "totalTradeVolumes": "0.0",
    "totalDeposits": "0.0",
    "SpotBalanceInUsdt": "0.0",
    "futuresBalanceInUsdt": "0.0"
  }
}
```

***

### 6. Postman Pre-Request Script

```js
const apiKey = pm.environment.get("api-key")
const secretKey = pm.environment.get("api-secret")
const timestamp = Date.now().toString();

let body = '';
if (pm.request.body && pm.request.body.raw) {
    body = JSON.parse(pm.request.body.raw);
}
const payload = JSON.stringify(body) + timestamp;

const crypto = require('crypto-js');
const signature = crypto.HmacSHA256(payload, secretKey).toString(crypto.enc.Hex);

pm.request.headers.upsert({ key: 'x-api-key', value: apiKey });
pm.request.headers.upsert({ key: 'x-signature', value: signature });
pm.request.headers.upsert({ key: 'x-timestamp', value: timestamp });
```

***

### 7. Python Implementation Example

```python
import time, json, hmac, hashlib, requests

class CoinlocallyAffiliate:
    def __init__(self, api_key, secret_key, logger_error=print):
        self.api_key = api_key
        self.secret_key = secret_key
        self.logger_error = logger_error

    def get_info_coinlocally(self, uid, email):
        url = 'https://official.coinlocally.com/v1/affiliates/referredInfo'

        # Request body
        body = {
            "userId": uid,
            "email": email,
        }

        # Timestamp
        timestamp = str(int(time.time() * 1000))

        # Payload = body + timestamp
        payload = json.dumps(body, separators=(',', ':')) + timestamp

        # Signature
        signature = hmac.new(
            self.secret_key.encode(),
            payload.encode(),
            hashlib.sha256
        ).hexdigest()

        # Headers
        headers = {
            'x-api-key': self.api_key,
            'x-signature': signature,
            'x-timestamp': timestamp,
            'Content-Type': 'application/json'
        }

        try:
            response = requests.post(url, headers=headers, json=body, verify=False)
            if response.status_code == 201:
                return response.json()
            else:
                return {
                    "error": True,
                    "status_code": response.status_code,
                    "message": response.text
                }
        except Exception as e:
            self.logger_error(f"Error in response API: {e}")
            return {"error": True, "message": str(e)}
```

✅ Now affiliates can securely connect and retrieve referral information using the provided API Key and Secret Key.
