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

# Integrate Your SaaS Backend with the Refairn REST API

> Send customer signup and payment events from your SaaS backend to Refairn via REST API to enable automatic referral attribution and commission tracking.

The Refairn API gives your backend direct, real-time control over referral attribution and commission triggering. Instead of relying on webhook routing from a payment provider, you fire events at exactly the right moment in your own application logic—after signup is confirmed, after a payment succeeds, after a subscription is cancelled. This is the most precise integration method and the recommended approach for production programs where accuracy and auditability matter.

<Warning>
  Your API key grants write access to your Refairn business data, including commission records. Never expose it in client-side code, public repositories, or environment variables that are shipped to the browser. Store it in a server-side secrets manager or environment variable accessible only to your backend.
</Warning>

## Setup

<Steps>
  <Step title="Generate your API key">
    In your Refairn business dashboard, go to **Settings → Integrations**. Click **Generate API Key**. Copy the key immediately—it is only shown once. If you lose it, revoke it and generate a new one.
  </Step>

  <Step title="Store the key securely">
    Add the key to your server-side environment variables. Reference it as `REFAIRN_API_KEY` in your code. Never hard-code the value directly in source files.
  </Step>

  <Step title="Locate your business and product IDs">
    Your `businessId` and `productId` are shown in **Settings → Integrations** alongside your API key. You will include these in every event payload you send.
  </Step>

  <Step title="Instrument your signup flow">
    After a new user successfully creates an account in your SaaS, call the `customer-created` endpoint. Pass the customer's email, name, and the referral code from the cookie set by Refairn's tracking link (if present).
  </Step>

  <Step title="Instrument your payment flow">
    After a payment is confirmed in your billing system, call the `payment-succeeded` endpoint. Pass the customer's email, the payment amount, currency, and date.
  </Step>
</Steps>

***

## Authentication

All API requests must include your API key in the `Authorization` header as a Bearer token.

```http theme={null}
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

Requests without a valid key return `401 Unauthorized`. Requests with a key that does not match the `businessId` in the payload return `403 Forbidden`.

***

## Customer created event

Send this event from your signup handler immediately after a new user account is created in your SaaS. Refairn records the customer, looks up the referring agent from the `referralCode` (or from the tracking cookie if the code was set during the referral link click), and creates a lead record attributed to that agent.

### Request

**`POST /api/events/customer-created`**

<ParamField body="businessId" type="string" required>
  Your Refairn business ID. Found in Settings → Integrations.
</ParamField>

<ParamField body="productId" type="string" required>
  The ID of the specific product this customer signed up for. Found in Settings → Integrations.
</ParamField>

<ParamField body="customerEmail" type="string" required>
  The email address the customer used to register. This is the primary key used for attribution matching.
</ParamField>

<ParamField body="customerName" type="string" required>
  The customer's full name as provided during signup.
</ParamField>

<ParamField body="referralCode" type="string">
  The agent's referral code. Read this from the tracking cookie set when the customer clicked a Refairn referral link (`refairn_code`). Omit this field if the customer did not arrive via a referral link.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  `true` if the event was accepted and processed.
</ResponseField>

<ResponseField name="leadId" type="string">
  The unique ID of the lead record created in Refairn for this customer.
</ResponseField>

<ResponseField name="agentId" type="string">
  The ID of the agent the customer was attributed to. `null` if no attribution was found.
</ResponseField>

<ResponseField name="attribution" type="string">
  The attribution model used. Currently always `first_touch`.
</ResponseField>

<ResponseField name="message" type="string">
  A human-readable confirmation message.
</ResponseField>

### Code examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.refairn.com/api/events/customer-created \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "businessId": "business_123",
      "productId": "product_123",
      "customerEmail": "jane@example.com",
      "customerName": "Jane Smith",
      "referralCode": "AGENT123"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://app.refairn.com/api/events/customer-created",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.REFAIRN_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        businessId: "business_123",
        productId: "product_123",
        customerEmail: "jane@example.com",
        customerName: "Jane Smith",
        referralCode: "AGENT123", // read from cookie: req.cookies.refairn_code
      }),
    }
  );

  const data = await response.json();

  if (!data.success) {
    console.error("Refairn attribution failed:", data);
  }
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      "https://app.refairn.com/api/events/customer-created",
      headers={
          "Authorization": f"Bearer {os.environ['REFAIRN_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "businessId": "business_123",
          "productId": "product_123",
          "customerEmail": "jane@example.com",
          "customerName": "Jane Smith",
          "referralCode": "AGENT123",  # read from session or cookie
      },
  )

  data = response.json()

  if not data.get("success"):
      print("Refairn attribution failed:", data)
  ```
</CodeGroup>

**Example response:**

```json theme={null}
{
  "success": true,
  "leadId": "lead_abc123",
  "agentId": "agent_xyz456",
  "attribution": "first_touch",
  "message": "Customer recorded and attributed to agent."
}
```

***

## Payment succeeded event

Send this event from your billing or payment confirmation handler every time a customer completes a payment—initial subscriptions, monthly renewals, annual renewals, and one-time charges all qualify. Refairn looks up the agent attribution for the customer's email and queues the appropriate commission.

### Request

**`POST /api/events/payment-succeeded`**

<ParamField body="businessId" type="string" required>
  Your Refairn business ID.
</ParamField>

<ParamField body="productId" type="string" required>
  The ID of the product the payment is for.
</ParamField>

<ParamField body="customerEmail" type="string" required>
  The customer's email address. Must match the email used when the lead was created.
</ParamField>

<ParamField body="amount" type="number" required>
  The payment amount as a number in the currency's standard unit. For example, `100` for USD $100.00 or `29.99` for a $29.99 charge.
</ParamField>

<ParamField body="currency" type="string" required>
  ISO 4217 currency code. For example, `"USD"`, `"NGN"`, `"GBP"`.
</ParamField>

<ParamField body="subscriptionStatus" type="string" required>
  The subscription state after this payment. One of: `active`, `trialing`, `past_due`, `cancelled`.
</ParamField>

<ParamField body="paymentDate" type="string" required>
  The date the payment was confirmed, in `YYYY-MM-DD` format.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  `true` if the event was accepted and a commission record was created or updated.
</ResponseField>

<ResponseField name="commissionId" type="string">
  The unique ID of the commission record created for this payment.
</ResponseField>

<ResponseField name="agentId" type="string">
  The agent who will receive the commission.
</ResponseField>

<ResponseField name="commissionAmount" type="number">
  The calculated commission amount in the same currency as the payment.
</ResponseField>

<ResponseField name="commissionStatus" type="string">
  The initial status of the commission. Always `pending` on creation—commissions move to `approved` after the hold period passes with no refund or dispute.
</ResponseField>

<ResponseField name="holdUntil" type="string">
  The date after which the commission is eligible for approval, in `YYYY-MM-DD` format. Based on your program's hold period setting.
</ResponseField>

### Code examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.refairn.com/api/events/payment-succeeded \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "businessId": "business_123",
      "productId": "product_123",
      "customerEmail": "jane@example.com",
      "amount": 100,
      "currency": "USD",
      "subscriptionStatus": "active",
      "paymentDate": "2026-06-14"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://app.refairn.com/api/events/payment-succeeded",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.REFAIRN_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        businessId: "business_123",
        productId: "product_123",
        customerEmail: "jane@example.com",
        amount: 100,
        currency: "USD",
        subscriptionStatus: "active",
        paymentDate: "2026-06-14",
      }),
    }
  );

  const data = await response.json();

  if (data.success) {
    console.log(
      `Commission ${data.commissionId} queued for agent ${data.agentId}:`,
      `${data.commissionAmount} ${data.commissionStatus} until ${data.holdUntil}`
    );
  }
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      "https://app.refairn.com/api/events/payment-succeeded",
      headers={
          "Authorization": f"Bearer {os.environ['REFAIRN_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "businessId": "business_123",
          "productId": "product_123",
          "customerEmail": "jane@example.com",
          "amount": 100,
          "currency": "USD",
          "subscriptionStatus": "active",
          "paymentDate": "2026-06-14",
      },
  )

  data = response.json()

  if data.get("success"):
      print(
          f"Commission {data['commissionId']} queued for "
          f"agent {data['agentId']}: "
          f"{data['commissionAmount']} {data['commissionStatus']} "
          f"until {data['holdUntil']}"
      )
  ```
</CodeGroup>

**Example response:**

```json theme={null}
{
  "success": true,
  "commissionId": "comm_abc123",
  "agentId": "agent_xyz456",
  "commissionAmount": 20.00,
  "commissionStatus": "pending",
  "holdUntil": "2026-06-28"
}
```

***

## Error handling

| Status code        | Cause                                                  | What to do                                                                            |
| ------------------ | ------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| `400 Bad Request`  | Missing or invalid fields in your payload              | Check required fields; inspect the `message` field in the response body for specifics |
| `401 Unauthorized` | Missing or invalid API key                             | Verify `Authorization: Bearer YOUR_API_KEY` header is present and the key is valid    |
| `403 Forbidden`    | API key does not match the `businessId` in the payload | Confirm the key was generated for this business account                               |
| `404 Not Found`    | Unknown `businessId` or `productId`                    | Check Settings → Integrations for your correct IDs                                    |
| `409 Conflict`     | Duplicate event already processed                      | Safe to ignore—Refairn has already recorded this event                                |
| `5xx Server Error` | Transient server issue                                 | Retry with exponential backoff (wait 1s, 2s, 4s between attempts)                     |

Refairn events are idempotent for the same `customerEmail` + `paymentDate` combination on payment events, and the same `customerEmail` on customer-created events. Retrying a successfully processed event returns a `409` and will not create duplicates.

***

## Testing

Use your live API key against the production endpoint during development—Refairn does not currently offer a separate sandbox environment. To avoid creating real commission records during testing, use a dedicated test product created in your dashboard with a `$0.00` commission rate. Delete test customer and commission records from the **Customers** section of the dashboard after each test run.

<Tip>
  Create a separate Refairn product called "Test Product" with all commission rates set to zero. Point your local development environment at that `productId`. Real agent commission records will not be generated, but you can still validate that events are being received and attributed correctly.
</Tip>
