Affiliate API Documentation

Complete REST API for managing your affiliate program. Track referrals, manage affiliates, process commissions, and automate payouts.

Base URL

https://affiliate.codhash.com

All API endpoints use the path /api/v1/ prefix.

API Architecture Overview

The API consists of 11 external endpoints organized into two categories:

7 routes

Affiliate Management (JWT Auth)

Endpoints for affiliates to manage their accounts and codes

4 routes

Tracking (API Key Auth)

Endpoints for tracking clicks, signups, conversions, and cancellations

What About Admin Operations?

Admin operations (managing affiliates, approving commissions, processing payouts) are handled through Next.js Server Actions, not API routes. This provides better security, type safety, and performance for internal operations.

Authentication

The API uses TWO different authentication systems depending on the endpoint type:

1. JWT Authentication (Affiliate Endpoints)

Used by affiliates to access their personal dashboard and manage their codes.

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Endpoints using JWT:

  • • GET /api/v1/affiliate/dashboard
  • • POST /api/v1/affiliate/codes
  • • GET /api/v1/affiliate/codes
  • • PATCH /api/v1/affiliate/codes/{id}
  • • DELETE /api/v1/affiliate/codes/{id}

How to get a JWT token:

1. Register affiliate via POST /api/v1/affiliates/register
2. Login via POST /api/v1/affiliates/login
3. Use returned JWT token for affiliate endpoints

2. API Key Authentication (Tracking Endpoints)

Used by your backend to track conversions, clicks, signups, and cancellations.

Authorization: Bearer sk_live_orgslug_abc123xyz789...

Endpoints using API Key:

  • • POST /api/v1/track/click
  • • POST /api/v1/track/signup
  • • POST /api/v1/track/conversion
  • • POST /api/v1/track/cancellation

How to get an API key:

Create via admin dashboard at /settings/api-keys

Important: Which Auth to Use?

  • JWT (Affiliate Auth): For affiliates accessing their own data
  • API Key (Organization Auth): For your backend tracking conversions
  • • Both use the same Authorization: Bearer {token} header format

Click & Conversion Tracking

Track affiliate link clicks, signups, conversions, and cancellations.

Track Click

POST/api/v1/track/click
const response = await fetch('https://affiliate.codhash.com/api/v1/track/click', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"referralCode": "AFFILIATE123",

"ip": "192.168.1.1",

"userAgent": "Mozilla/5.0...",

"referer": "https://example.com",

"country": "US",

"city": "San Francisco",

"metadata": {

"campaign": "summer-2024"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Click tracked successfully",
  "data": {
    "clickId": "click_abc123",
    "code": "AFFILIATE123",
    "timestamp": "2024-01-15T10:00:00Z"
  }
}

Track Signup

POST/api/v1/track/signup
const response = await fetch('https://affiliate.codhash.com/api/v1/track/signup', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"referralCode": "AFFILIATE123",

"customerEmail": "user@example.com",

"externalCustomerId": "cus_abc123",

"clickId": "click_abc123",

"metadata": {

"plan": "free"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Signup tracked successfully",
  "data": {
    "referralId": "ref_xyz789",
    "status": "SIGNED_UP",
    "signedUpAt": "2024-01-15T10:00:00Z"
  }
}

Track Conversion

Track when a referred user converts to a paying customer. Supports first payments, renewals, and one-time purchases.

POST/api/v1/track/conversion
const response = await fetch('https://affiliate.codhash.com/api/v1/track/conversion', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"referralCode": "AFFILIATE123",

"customerEmail": "user@example.com",

"externalCustomerId": "cus_abc123",

"amount": 2999,

"currency": "EUR",

"externalPaymentId": "pi_stripe_xyz789",

"subscriptionId": "sub_xyz789",

"subscriptionType": "subscription",

"billingInterval": "month",

"metadata": {

"planName": "Pro Plan"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "First Payment tracked successfully",
  "data": {
    "referralId": "ref_xyz789",
    "commissionId": "comm_abc123",
    "amount": 599,
    "currency": "EUR",
    "paymentType": "first_payment",
    "status": "PENDING"
  }
}

Payment Types

  • first_payment: Initial subscription payment
  • renewal: Recurring subscription payment
  • one_time: Single purchase (set subscriptionType to "one_time")

Optional Fields with Defaults

  • currency: Optional, defaults to "EUR"
  • subscriptionType: Optional, defaults to "subscription"

Track Cancellation

POST/api/v1/track/cancellation
const response = await fetch('https://affiliate.codhash.com/api/v1/track/cancellation', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"externalCustomerId": "cus_abc123",

"cancelReason": "too-expensive",

"subscriptionId": "sub_xyz789",

"metadata": {

"feedback": "Great product but out of budget"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Cancellation processed successfully",
  "data": {
    "referralsProcessed": 1,
    "commissionsCancelled": 2,
    "totalAmountCancelled": 1198,
    "gracePeriodDays": 30,
    "currency": "EUR"
  }
}

Affiliate Dashboard

Get comprehensive dashboard data for an affiliate. Query params: period (7d|30d|90d|all, default: 30d).

🔐 JWT Authentication Required: This endpoint uses affiliate JWT tokens, not organization API keys. The affiliate is identified from the JWT token.

GET/api/v1/affiliate/dashboard?period=30d
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/dashboard?period=30d', {
method: 'GET',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
}
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "data": {
    "profile": {
      "id": "aff_profile_123",
      "status": "ACTIVE",
      "defaultCode": "AFFILIATE123",
      "defaultLink": "https://your-site.com?ref=AFFILIATE123",
      "payoutMethod": "stripe_connect"
    },
    "earnings": {
      "total": 125000,
      "pending": 35000,
      "approved": 45000,
      "paid": 45000
    },
    "commissionRates": {
      "type": "PERCENTAGE",
      "currency": "EUR",
      "defaultRate": 20,
      "firstPaymentRate": 25,
      "renewalRate": 15,
      "oneTimeRate": 30,
      "fixedAmount": null,
      "hasCustomRates": false,
      "conversionWindow": 15,
      "recurringCommissions": true,
      "maxRenewals": 0,
      "recurringDurationMonths": 12
    },
    "stats": {
      "period": "30d",
      "totalReferrals": 42,
      "activeReferrals": 35,
      "cancelledReferrals": 7,
      "totalCommissions": 15,
      "pendingCommissions": 5,
      "approvedCommissions": 7,
      "paidCommissions": 3,
      "periodEarnings": 45000,
      "periodPending": 15000,
      "periodApproved": 20000,
      "periodPaid": 10000,
      "firstPaymentCommissions": 8,
      "renewalCommissions": 7,
      "clickToSignupRate": 12.5,
      "signupToConversionRate": 8.3
    },
    "codes": [
      {
        "id": "code_123",
        "code": "AFFILIATE123",
        "link": "https://your-site.com?ref=AFFILIATE123",
        "clickCount": 1250,
        "referralCount": 156,
        "conversionCount": 42,
        "status": "ACTIVE",
        "metadata": {},
        "createdAt": "2024-01-01T00:00:00Z"
      }
    ],
    "recentCommissions": [
      {
        "id": "comm_abc123",
        "amount": 599,
        "currency": "EUR",
        "status": "PENDING",
        "paymentType": "first_payment",
        "referral": {
          "id": "ref_xyz",
          "customerEmail": "customer@example.com"
        },
        "createdAt": "2024-01-15T10:00:00Z"
      }
    ],
    "referrals": [
      {
        "id": "ref_xyz",
        "customerEmail": "customer@example.com",
        "status": "CONVERTED",
        "clickedAt": "2024-01-14T10:00:00Z",
        "signedUpAt": "2024-01-14T11:00:00Z",
        "convertedAt": "2024-01-15T10:00:00Z",
        "code": {
          "code": "AFFILIATE123"
        }
      }
    ]
  }
}

Affiliate Codes

Manage referral codes for affiliates.

🔐 JWT Authentication Required: All affiliate code endpoints use JWT tokens.

Create Code

POST/api/v1/affiliate/codes
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/codes', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"code": "SUMMER2024",

"baseUrl": "https://your-site.com",

"metadata": {

"campaign": "summer-promo"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Affiliate code created successfully",
  "data": {
    "id": "code_new123",
    "code": "SUMMER2024",
    "link": "https://your-site.com?ref=SUMMER2024",
    "clickCount": 0,
    "referralCount": 0,
    "conversionCount": 0,
    "status": "ACTIVE"
  }
}

Get All Codes

GET/api/v1/affiliate/codes
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/codes', {
method: 'GET',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
}
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "data": {
    "codes": [
      {
        "id": "code_123",
        "code": "AFFILIATE123",
        "link": "https://your-site.com?ref=AFFILIATE123",
        "clickCount": 1250,
        "referralCount": 156,
        "conversionCount": 42,
        "status": "ACTIVE",
        "metadata": {},
        "createdAt": "2024-01-01T00:00:00Z"
      }
    ]
  }
}

Update Code

PATCH/api/v1/affiliate/codes/code_123
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/codes/code_123', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"code": "NEWSUMMER2024",

"status": "ACTIVE",

"metadata": {

"campaign": "summer-updated"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Code updated successfully",
  "data": {
    "id": "code_123",
    "code": "NEWSUMMER2024",
    "link": "https://your-site.com?ref=NEWSUMMER2024",
    "status": "ACTIVE",
    "metadata": {
      "campaign": "summer-updated"
    },
    "updatedAt": "2024-01-15T10:00:00Z"
  }
}

Delete Code

Soft deletes an affiliate code. Cannot delete your default code.

DELETE/api/v1/affiliate/codes/code_123
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/codes/code_123', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
}
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Code deleted successfully",
  "data": {
    "id": "code_123",
    "deletedAt": "2024-01-15T10:00:00Z"
  }
}

Affiliate Profile

Manage your affiliate profile and payout information.

🔐 JWT Authentication Required: Profile endpoints use JWT tokens.

Update Profile

Update your payout method and banking details for receiving commission payments.

PATCH/api/v1/affiliate/profile
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/profile', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"payoutMethod": "bank",

"payoutDetails": {

"iban": "FR7630006000011234567890189",

"bic": "BNPAFRPP",

"accountHolder": "John Doe"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Profile updated successfully",
  "data": {
    "payoutMethod": "bank",
    "payoutDetails": {
      "iban": "FR7630006000011234567890189",
      "bic": "BNPAFRPP",
      "accountHolder": "John Doe"
    },
    "updatedAt": "2024-01-15T10:00:00Z"
  }
}

Payout Methods & Details

  • bank: Requires iban, bic, accountHolder
  • paypal: Requires email
  • stripe_connect: Requires accountId
  • wise: Requires email or accountNumber
  • other: Custom JSON structure (e.g., crypto wallet, Venmo, etc.)

Examples:

{ "payoutMethod": "wise", "payoutDetails": { "email": "user@example.com" } }{ "payoutMethod": "other", "payoutDetails": { "type": "crypto", "wallet": "0x..." } }

Stripe Connect Onboarding

Configure Stripe Connect for automatic payouts. Affiliates can set up their bank account details through Stripe's secure onboarding flow.

🔐 JWT Authentication Required: Stripe Connect endpoints use JWT tokens for affiliate identity.

Start Onboarding

Creates a Stripe Connect account (if needed) and returns an onboarding URL for the affiliate to complete KYC and banking details.

POST/api/v1/affiliate/stripe-connect/onboard
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/stripe-connect/onboard', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
}
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "data": {
    "stripeAccountId": "acct_1234567890",
    "onboardingUrl": "https://connect.stripe.com/setup/s/abc123xyz789...",
    "message": "Please complete the onboarding process to receive payouts via Stripe"
  }
}

How it works

  1. Frontend calls this endpoint with affiliate JWT
  2. Backend creates Stripe Connect account (Standard type)
  3. Returns onboarding URL
  4. Frontend redirects affiliate to Stripe
  5. Affiliate completes KYC + bank details on Stripe
  6. Stripe redirects to /affiliate/onboarding-complete

Check Onboarding Status

Verify if the affiliate has completed Stripe Connect onboarding and is ready to receive payouts.

GET/api/v1/affiliate/stripe-connect/status?affiliateId=aff_profile_123
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliate/stripe-connect/status?affiliateId=aff_profile_123', {
method: 'GET',
headers: {
'Authorization': 'Bearer your_jwt_token_here',
'Content-Type': 'application/json'
}
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "data": {
    "connected": true,
    "onboardingComplete": true,
    "accountStatus": {
      "chargesEnabled": true,
      "detailsSubmitted": true,
      "payoutsEnabled": true,
      "country": "FR"
    }
  }
}

Status Fields

  • connected: Stripe account exists
  • onboardingComplete: KYC and banking details submitted
  • chargesEnabled: Can receive charges
  • detailsSubmitted: All required info provided
  • payoutsEnabled: Ready to receive payouts ✅

🎯 Integration Guide

For complete frontend integration examples, see /docs/STRIPE_CONNECT_SETUP.md

What you'll find:

  • React components for onboarding button
  • Status display component
  • Success/error page examples
  • Complete integration workflow

Affiliate Registration

Register a new affiliate in your program.

POST/api/v1/affiliates/register
const response = await fetch('https://affiliate.codhash.com/api/v1/affiliates/register', {
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"externalUserId": "user123",

"email": "affiliate@example.com",

"firstName": "John",

"lastName": "Doe",

"customCode": "MYAFFILIATE",

"baseUrl": "https://your-site.com",

"payoutMethod": "stripe_connect",

"payoutDetails": {

"stripeAccountId": "acct_xyz"

},

"customCommissionType": "PERCENTAGE",

"customCommissionRate": 25,

"customFixedAmount": 500,

"currency": "EUR",

"metadata": {

"company": "Marketing Pro"

}

}
)
});

const data = await response.json();
console.log(data);
Response
{
  "success": true,
  "message": "Affiliate registered successfully",
  "data": {
    "affiliateId": "aff_profile_new123",
    "userId": "user_abc123",
    "code": "MYAFFILIATE",
    "link": "https://your-site.com?ref=MYAFFILIATE",
    "status": "ACTIVE"
  }
}

Field Options

  • payoutMethod: "bank" | "paypal" | "stripe_connect" | "wise" | "other"
  • customCommissionType: "PERCENTAGE" | "FIXED" | "TIERED"
  • customCommissionRate: For PERCENTAGE type (0-100)
  • customFixedAmount: For FIXED type (in cents)

💡 Advanced: Payment Type Specific Rates

You can also set customFirstPaymentRate, customRenewalRate, and customOneTimeRate for different commission rates per payment type.

Error Codes

Standard HTTP status codes used by the API.

200
OK
Request successful
400
Bad Request
Invalid parameters
401
Unauthorized
Invalid or missing API key
403
Forbidden
Insufficient permissions
404
Not Found
Resource not found
429
Too Many Requests
Rate limit exceeded
500
Internal Server Error
Server error

Rate Limits

API endpoints have different rate limits to ensure system stability.

Click Tracking
1000 requests/hour
Signup Tracking
500 requests/hour
Conversion Tracking
100 requests/hour
Cancellation Tracking
200 requests/hour
Dashboard & Codes (GET)
200 requests/hour
Affiliate Registration
100 requests/hour
Code Creation
50 requests/hour

Rate Limit Headers

All API responses include rate limit information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1642262400