This guide walks through the shortest path from zero to a recorded conversion: create an account, configure a campaign, generate an API key, send a `POST /api/v1/conversions/postback` request.

If you already have an account and an API key, skip to [Send a conversion](#send-a-conversion).

## 1. Create a merchant account

Sign up at [app.refcampaign.com](https://app.refcampaign.com). You'll receive a verification email; once confirmed, the dashboard prompts you to create your first campaign.

A campaign is the unit affiliates join. Each campaign has its own commission rate, attribution window, and tracking URL. For testing, the defaults are fine.

## 2. Generate an API key

In the dashboard:

1. Open **Settings → API keys**.
2. Click **Create API key**, give it a name (e.g. `local-dev`).
3. Copy the token. You'll only see it once — store it in a secret manager or a local `.env`.

<Callout type="warning" title="Store the token before closing the dialog">
  We don't keep the plaintext token. If you lose it, you have to revoke the key and create a new one.
</Callout>

The token is a Bearer JWT signed by RefCampaign. You'll send it on every API request as:

```http
Authorization: Bearer <YOUR_TOKEN>
```

## 3. Find a click to attribute to

A conversion is always tied to a previous click. In normal traffic, the SDK or tracking URL captures clicks automatically. For this quickstart we'll create a synthetic click first.

```bash
curl -X POST https://app.refcampaign.com/api/v1/track/click \
  -H "Content-Type: application/json" \
  -d '{
    "tracking_url": "https://yourshop.com/?ref=affiliate-1",
    "session_id": "test-session-001"
  }'
```

The response includes the click id; we won't need it directly but the `session_id` we passed (`test-session-001`) is what links the future conversion to this click.

## 4. Send a conversion

Now record a conversion against that session.

```bash
curl -X POST https://app.refcampaign.com/api/v1/conversions/postback \
  -H "Authorization: Bearer $REFCAMPAIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "ord_001",
    "conversionType": "SALE",
    "sessionId": "test-session-001",
    "amount": 4990,
    "currency": "EUR"
  }'
```

A successful response returns `200` with the conversion and commission details:

```json
{
  "success": true,
  "data": {
    "success": true,
    "conversionId": "cnv_01HABCDEFG...",
    "commissionId": "cmm_01HABCDEFG...",
    "commissionAmount": 499
  },
  "meta": {
    "timestamp": "2026-05-03T10:23:11.000Z"
  }
}
```

The conversion lands in `PENDING` status. The merchant approves it (or sets up auto-approval rules), at which point a commission is generated for the affiliate.

## 5. What's next

* **Use the SDK instead of curl**: the [`@refcampaign/sdk`](/docs/api/integration/sdk) package handles click + identify automatically from a JS frontend.
* **Server-to-server postback**: if you already capture conversions in your own backend (webhooks from Stripe, PayPal, etc.), see [postback integration](/docs/api/integration/postback).
* **Browse the full API**: every endpoint, request schema, and response shape is in the [API reference](/docs/api/reference). Try requests live with the playground.

## Common pitfalls

* **`401 Unauthorized`** — the `Authorization` header is missing or malformed. Confirm `Bearer ` (with the trailing space) and the full token.
* **`400 VALIDATION_FAILED` on `currency`** — currency must be a 3-letter ISO 4217 code (`EUR`, `USD`, `GBP`). Lowercase works; symbols and full names don't.
* **Conversion not attributed** — either `sessionId` doesn't match a recent click, or the click is older than the campaign's attribution window. Pass `customerEmailHash` (SHA-256 hex of lowercased email) as a fallback.
