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

# Affiliate program API integration

> Integrate your affiliate program using the Partnero REST API for server-side tracking of sign-ups and sales.

This guide walks you through integrating an affiliate program using the Partnero REST API. Use this approach when you want server-side tracking with full control over the data you send.

<Note>
  Before proceeding, you should have a program created on Partnero. If you haven't created one yet, refer to the [Knowledge Base](https://help.partnero.com) for guidance.
</Note>

## How it works

1. A visitor arrives at your site via a partner's referral link (e.g., `yoursite.com?ref=PARTNER_KEY`)
2. PartneroJS stores the partner's key in a `partnero_partner` cookie
3. When the visitor signs up, your backend reads the cookie and sends it to Partnero along with the customer data
4. When the customer makes a purchase, your backend records the transaction
5. Partnero calculates the partner's commission automatically

## Step 1: Install PartneroJS

PartneroJS tracks referral visits by reading the partner key from the URL and storing it in a first-party cookie. This cookie is what your backend reads later during sign-up.

<Steps>
  <Step title="Get your snippet">
    1. Log in to [Partnero](https://app.partnero.com)
    2. Go to **Programs** and select your program
    3. Navigate to **Integration** in the sidebar
    4. Copy the PartneroJS snippet
  </Step>

  <Step title="Install the snippet">
    Paste the snippet into your website's HTML just before the closing `</head>` tag:

    ```html theme={null}
    <!-- PartneroJS -->
    <script>
        (function(p,t,n,e,r,o){ p['__partnerObject']=r;function f(){
        var c={ a:arguments,q:[]};var r=this.push(c);return "number"!=typeof r?r:f.bind(c.q);}
        f.q=f.q||[];p[r]=p[r]||f.bind(f.q);p[r].q=p[r].q||f.q;o=t.createElement(n);
        var _=t.getElementsByTagName(n)[0];o.async=1;o.src=e+'?v'+(~~(new Date().getTime()/1e6));
        _.parentNode.insertBefore(o,_);})(window, document, 'script', 'https://app.partnero.com/js/universal.js', 'po');
        po('settings', 'assets_host', 'https://assets.partnero.com');
        po('program', 'PUBLIC_PROGRAM_ID', 'load');
    </script>
    <!-- End PartneroJS -->
    ```
  </Step>
</Steps>

When a visitor arrives via a referral URL, the script creates a `partnero_partner` cookie containing the partner's unique key. This cookie persists for the duration configured in your program settings (default: 30 days).

## Step 2: Track sign-ups

When a new user signs up, your backend reads the `partnero_partner` cookie from the request and sends it to Partnero to attribute the customer to the referring partner.

```
POST https://api.partnero.com/v1/customers
```

### How to get the partner key

The `partnero_partner` cookie is set by PartneroJS and sent with every request to your domain. Read it on your server:

<Tabs>
  <Tab title="Node.js / Express">
    ```javascript theme={null}
    const partnerKey = req.cookies['partnero_partner'];
    ```
  </Tab>

  <Tab title="PHP / Laravel">
    ```php theme={null}
    $partnerKey = $request->cookie('partnero_partner');
    ```
  </Tab>

  <Tab title="Python / Django">
    ```python theme={null}
    partner_key = request.COOKIES.get('partnero_partner')
    ```
  </Tab>

  <Tab title="Ruby on Rails">
    ```ruby theme={null}
    partner_key = cookies[:partnero_partner]
    ```
  </Tab>
</Tabs>

### Create the customer

Pass the partner key along with the customer data:

```bash theme={null}
curl --location 'https://api.partnero.com/v1/customers' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "partner": {
      "key": "PARTNER_KEY_FROM_COOKIE"
    },
    "key": "customer_123",
    "email": "customer@example.com",
    "name": "John",
    "surname": "Doe"
  }'
```

### Request body

| Parameter              | Type   | Required | Description                                                  |
| ---------------------- | ------ | -------- | ------------------------------------------------------------ |
| `partner.key`          | string | Yes\*    | Partner's referral key from `partnero_partner` cookie        |
| `partner.email`        | string | Yes\*    | Partner's email (alternative to key)                         |
| `partner.id`           | string | Yes\*    | Partner's ID (alternative to key)                            |
| `key`                  | string | Yes      | Unique customer identifier (account ID or email recommended) |
| `email`                | string | No       | Customer's email address                                     |
| `name`                 | string | No       | Customer's first name                                        |
| `surname`              | string | No       | Customer's last name                                         |
| `tags`                 | array  | No       | Tag names to assign to the customer                          |
| `options.referral_url` | string | No       | The URL where the referral occurred                          |

\*Provide at least one of `partner.key`, `partner.email`, or `partner.id`.

<Tip>
  Partnero ignores requests with an invalid partner key. You can send customer data for **every** sign-up without checking the cookie first—only customers with a valid referral will be recorded.
</Tip>

### Response

```json theme={null}
{
  "data": {
    "key": "customer_123",
    "partner": "PARTNER_KEY",
    "name": "John",
    "surname": "Doe",
    "email": "customer@example.com",
    "status": "active",
    "tags": [],
    "created_at": "2025-05-09T17:42:13.000000Z",
    "updated_at": "2025-05-09T17:42:13.000000Z"
  },
  "status": 1
}
```

## Step 3: Track sales

When a customer makes a purchase, record the transaction so Partnero can calculate the partner's commission.

<Tip>
  **Prefer automatic tracking?** If you use Stripe, Paddle, or Chargebee, transactions are tracked automatically through Partnero's integrations—no API call needed. Set up integrations in **Program settings → Integrations**.
</Tip>

```
POST https://api.partnero.com/v1/transactions
```

```bash theme={null}
curl --location 'https://api.partnero.com/v1/transactions' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer": {
      "key": "customer_123"
    },
    "key": "invoice_123",
    "amount": 99.99,
    "action": "sale"
  }'
```

### Request body

| Parameter      | Type   | Required | Description                                                           |
| -------------- | ------ | -------- | --------------------------------------------------------------------- |
| `customer.key` | string | Yes      | The customer identifier used during sign-up                           |
| `key`          | string | Yes      | Unique transaction ID (use your invoice/order ID for refund handling) |
| `amount`       | number | Yes      | Transaction amount                                                    |
| `action`       | string | Yes      | Transaction type (e.g., `sale`)                                       |
| `product_id`   | string | No       | Product identifier (for advanced commission rules)                    |
| `product_type` | string | No       | Product type, e.g., `monthly`, `yearly` (for commission rules)        |

### Multiple transactions

Send multiple transactions for the same customer in a single request:

```bash theme={null}
curl --location 'https://api.partnero.com/v1/transactions' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer": {
      "key": "customer_123"
    },
    "transactions": [
      {
        "key": "invoice_123",
        "amount": 99.99,
        "action": "sale"
      },
      {
        "key": "invoice_456",
        "amount": 199.99,
        "action": "sale"
      }
    ]
  }'
```

<Tip>
  Partnero ignores transactions for customers that don't exist in the system. You can safely send all purchase data without filtering by referred status.
</Tip>

## Complete integration example

Here's the full flow in a Node.js/Express backend:

```javascript theme={null}
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();

app.use(cookieParser());
app.use(express.json());

// After user signs up
app.post('/signup', async (req, res) => {
  const { email, name, password } = req.body;
  
  // 1. Create user in your database
  const user = await createUser({ email, name, password });
  
  // 2. Send to Partnero (safe to call for every sign-up)
  await fetch('https://api.partnero.com/v1/customers', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      partner: { key: req.cookies['partnero_partner'] },
      key: user.id,
      email: user.email,
      name: user.name
    })
  });

  res.json({ success: true });
});

// After a purchase
app.post('/purchase', async (req, res) => {
  const { userId, orderId, amount } = req.body;
  
  // 1. Process the payment
  const order = await processPayment({ userId, orderId, amount });
  
  // 2. Record in Partnero (safe to call for every purchase)
  await fetch('https://api.partnero.com/v1/transactions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      customer: { key: userId },
      key: orderId,
      amount: amount,
      action: 'sale'
    })
  });

  res.json({ success: true });
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Full REST API documentation
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api-reference/webhooks/overview">
    Get real-time notifications for partner events
  </Card>

  <Card title="Mobile apps" icon="mobile" href="/guides/tracking/mobile-app">
    Integrate tracking in iOS and Android apps
  </Card>

  <Card title="JavaScript SDK" icon="js" href="/guides/tracking/javascript-tracking">
    Client-side tracking without a backend
  </Card>
</CardGroup>
