Quickstart

Create a program, a partner and a link, then attribute a customer and commission a payment with curl.

Embed
Preview of the card
<a href="https://referalli.com/docs/quickstart"><img src="https://referalli.com/docs/_api/public/orgs/07f432f4-34b9-46a7-aaad-c0e395d2e4f9/spaces/2bf4f614-3630-4fbf-85f9-5ecafa6b7d97/pages/e687ae0a-7084-4bf3-95ae-452d79802c20/social-card.svg?v=3e7ae33eec8b" alt="Quickstart" width="600" height="315"></a>

This walkthrough runs the whole pipeline end to end with plain HTTP calls: program, commission rule, partner, link, click, referral, payment, commission. It takes about ten minutes. Every call uses an API key, so you can paste the commands into a terminal.

Set two shell variables first and reuse them throughout:

export BASE=https://referalli.com
export KEY=rk_your_key_here
  1. Create an API key

    Sign in at https://referalli.com/login with Atlas. On first sign-in you create an organization. Then open Settings, find API keys, leave Access for the next key on Full, and click Create API key. This walkthrough writes data, so a read-only key won't do.

    The full key (rk_…) is shown once. Copy it into KEY. Only org owners and admins can create keys.

  2. Create a program
    curl -s -X POST $BASE/v1/programs \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{"name": "Acme Partners", "slug": "acme-partners"}'

    The response includes the program id (prg_…) with the defaults attributionModel: "last_click", cookieWindowDays: 60 and signupToConversionDays: 365. Save the id:

    export PROGRAM=prg_...
  3. Publish a commission rule

    A program pays nothing until it has a rule. This one pays 20% of every payment, for the customer's lifetime, after a 30-day hold:

    curl -s -X POST $BASE/v1/commission-rules \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{
        "programId": "'"$PROGRAM"'",
        "config": { "base": { "kind": "percent", "bps": 2000 } }
      }'

    bps is basis points: 2000 = 20%. recurring defaults to lifetime and holdDays to 30. See Commission rules for every option.

  4. Create a partner and enroll them
    curl -s -X POST $BASE/v1/partners \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{"email": "dana@example.com", "displayName": "Dana"}'
    
    export PARTNER=ptr_...
    
    curl -s -X POST $BASE/v1/programs/$PROGRAM/enrollments \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{"partnerId": "'"$PARTNER"'"}'

    Enrollments created this way are approved immediately.

  5. Create a tracked link
    curl -s -X POST $BASE/v1/links \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{
        "programId": "'"$PROGRAM"'",
        "partnerId": "'"$PARTNER"'",
        "code": "dana",
        "destinationUrl": "https://example.com/pricing"
      }'

    code is optional (letters, digits and -, stored lowercased and matched in any case); leave it out to get a random one. Now fetch your org's tracking token, which forms the public link URL:

    curl -s $BASE/v1/org -H "Authorization: Bearer $KEY"
    # { "id": "org_...", "trackingToken": "tk_...", ... }
    
    export TOKEN=tk_...

    The partner's link is $BASE/go/$TOKEN/dana.

  6. Click the link
    curl -s -o /dev/null -w '%{redirect_url}\n' \
      -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0)" \
      $BASE/go/$TOKEN/dana
    # https://example.com/pricing?via=dana&ref_click_id=clk_...

    The redirect appends via (the link code) and ref_click_id (the click id). Save the click id:

    export CLICK=clk_...

    Send a browser user agent. Clicks are fraud-scored. curl's default curl/… user agent scores as a bot, which makes the click ineligible for attribution. The -A flag above avoids that.

  7. Attribute the customer at signup

    When the visitor signs up, your server tells Referalli who they are. customerRef must be the id your billing provider uses for this customer (for Stripe, the cus_… id), because that is how payments are matched later.

    curl -s -X POST $BASE/v1/referrals/associate \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{
        "programId": "'"$PROGRAM"'",
        "customerRef": "cus_123",
        "referralToken": "'"$CLICK"'"
      }'

    The response is { "referral": { ... } } with partnerId set to Dana, matchedVia: "deterministic" and status: "active". If nothing matched, referral is null.

  8. Record a payment

    Payments arrive as billing webhooks. For this test, use the generic conversion API. Create a connection:

    curl -s -X POST $BASE/v1/billing/connections \
      -H "Authorization: Bearer $KEY" \
      -H "content-type: application/json" \
      -d '{"provider": "generic", "name": "quickstart"}'
    # { "id": "bcon_...", "provider": "generic",
    #   "webhookSecret": "whsec_...", "webhookUrl": "/webhooks/billing/bcon_..." }
    
    export CONN=bcon_...
    export SECRET=whsec_...

    Then post a signed invoice_paid event for $99.00. The signature is the hex HMAC-SHA256 of the exact body bytes:

    NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    BODY='{"events":[{"providerEventId":"evt_001","type":"invoice_paid","customerRef":"cus_123","invoiceRef":"in_001","amountGross":9900,"currency":"usd","occurredAt":"'"$NOW"'"}]}'
    SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')
    
    curl -s -X POST $BASE/webhooks/billing/$CONN \
      -H "content-type: application/json" \
      -H "x-webhook-signature: $SIG" \
      -d "$BODY"
    # { "received": 1, "results": [ { "duplicate": false, "conversions": 1, "linesCreated": 1, ... } ] }

    occurredAt must not be earlier than the referral (a 5-minute clock-skew allowance applies), so this uses the current time. Sending the same providerEventId again returns duplicate: true and changes nothing.

  9. Check the commission
    curl -s "$BASE/v1/commissions?partnerId=$PARTNER" -H "Authorization: Bearer $KEY"
    curl -s $BASE/v1/partners/$PARTNER/balances -H "Authorization: Bearer $KEY"
    # [ { "currency": "usd", "pending": 1980, "approved": 0, "paid": 0, "reversed": 0 } ]

    20% of 9900 is 1980 minor units ($19.80), held as pending for 30 days. After the hold, POST /v1/commissions/approve-due moves it to approved, and a payout run pays it. See Payouts.

What you built

  • A program with a commission rule, a partner, and a link at /go/{token}/dana.

  • A fraud-scored click, a referral that ties cus_123 to the partner, a payment conversion and an earned commission line.

Next steps

Updated