# PromoteKit Documentation (Full)
This file contains the complete PromoteKit documentation for AI/LLM consumption.
It includes both product documentation and API reference.
---
# Product Documentation
---
---
# Quick Start
URL: /docs
Description: Getting Started with PromoteKit
# Introduction
PromoteKit is a platform for running affiliate programs on top of Stripe. We've focused on creating **the most seamless possible integration with Stripe** so you can integrate quickly and get back to focusing on your business.
- [Affiliate Promo Codes](/docs/affiliate-promo-codes): Assign unique promo codes to affiliates and track referrals through Stripe
Checkout
- [Affiliate Links](/docs/affiliate-links): Give affiliates unique tracking links to refer customers to your site
- [Integrations](/docs/integrations): Connect with Memberstack, Outseta, MemberSpace, and more
- [Payouts](/docs/payouts): Pay affiliates via Stripe, PayPal, Wise, or manual methods
- [API Reference](/docs/api-reference): Build custom integrations with the PromoteKit REST API
- [Webhooks](/docs/webhooks): Receive real-time event notifications for your affiliate program
> **Note:** Need help? Contact us at hello@promotekit.com
---
# Affiliate Links Setup
URL: /docs/affiliate-links
Description: Track affiliate referrals using unique tracking links
# Overview
PromoteKit provides each affiliate with a unique tracking link. When a visitor clicks an affiliate's link and makes a purchase, the referral is automatically tracked.
## How It Works
1. Affiliate shares their unique link (e.g., `yoursite.com?via=abc123`)
2. Visitor clicks the link and lands on your site
3. PromoteKit script stores the referral ID in a cookie
4. When the visitor purchases, the referral ID is sent to Stripe
5. PromoteKit attributes the sale to the affiliate
## Setup Methods
- [Stripe API](/docs/affiliate-links/stripe-api): Pass referral IDs through the Stripe API for custom checkout flows
- [Stripe Payment Links](/docs/affiliate-links/stripe-payment-links): Use with Stripe Payment Links for a no-code solution
> **Note:** Affiliate link tracking requires adding the PromoteKit script to your website.
[Promo code tracking](/docs/affiliate-promo-codes) does not require any
script.
---
# Stripe API Integration
URL: /docs/affiliate-links/stripe-api
Description: Pass referral IDs through the Stripe API for affiliate tracking
# Overview
For custom checkout flows, you can pass the referral ID directly through the Stripe API.
## Implementation Steps
### 1. Add the PromoteKit Script
Add the PromoteKit script to your website. It should be on both your landing page (where referrals arrive) and your checkout page.
The script works across subdomains, so you can use it on both `yoursite.com` and `app.yoursite.com`.
### 2. Retrieve the Referral ID
After the script loads, you can access the referral ID:
**JavaScript/TypeScript:** Use `window.promotekit_referral`
**PHP:** Use `$_COOKIE['promotekit_referral']`
### 3. Pass to Stripe
Include the referral ID in the metadata when creating a checkout session or subscription:
```javascript
const session = await stripe.checkout.sessions.create({
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
metadata: {
promotekit_referral: req.body.referral,
},
line_items: [{ price: 'price_1OBQlV2eZvKYlo2CDL02DbMx', quantity: 1 }],
mode: 'subscription',
});
```
## Manual Signup Tracking
For tracking users who sign up before they pay, use the `refer` function:
`window.promotekit.refer(email, stripe_customer_id)`
| Parameter | Required | Description |
| -------------------- | -------- | --------------------------------- |
| `email` | Yes | Customer's email address |
| `stripe_customer_id` | No | Stripe customer ID (if available) |
This allows you to attribute the referral before payment occurs.
---
# Stripe Payment Links
URL: /docs/affiliate-links/stripe-payment-links
Description: Use PromoteKit with Stripe Payment Links for no-code affiliate tracking
# Stripe Payment Links Integration
If you use [Stripe Payment Links](https://stripe.com/payments/payment-links) or [Stripe Pricing Tables](https://docs.stripe.com/payments/checkout/pricing-table), PromoteKit provides a simple script-based solution that requires no custom API integration.
## Setup Steps
1. ### Get the Script
1. Go to your PromoteKit dashboard
2. Navigate to **Setup → Step 4 (PromoteKit Integration)**
3. Click **OPTION 2: Stripe Payment Links**
4. Copy the provided script
2. ### Add to Your Website
Paste the script into your website's custom code section. You can add it to either the `
` or `` section.
3. ### Publish and Confirm
1. Publish your website
2. Return to PromoteKit and click **Ok, I've completed this**
## Adding Custom Code on Different Platforms
- [Webflow](https://university.webflow.com/lesson/custom-code-in-the-head-and-body-tags): Adding custom code to head and body tags
- [Framer](https://www.framer.com/help/articles/how-to-add-custom-code/): Custom code implementation in Framer
- [WordPress](https://www.wpbeginner.com/plugins/how-to-easily-add-custom-code-in-wordpress-without-breaking-your-site/): Adding custom code safely in WordPress
> **Note:** This integration works with both [Stripe Payment Links](https://stripe.com/payments/payment-links) and [Stripe Pricing Tables](https://docs.stripe.com/payments/checkout/pricing-table).
---
# Affiliate Promo Codes Setup
URL: /docs/affiliate-promo-codes
Description: Track affiliate referrals using unique promo codes in Stripe
# Overview
PromoteKit assigns unique promo codes to each affiliate. When a customer uses an affiliate's promo code at checkout, the referral is automatically tracked and the affiliate earns their commission.
## How It Works
1. You create a coupon in Stripe with a discount (e.g., 10% off)
2. PromoteKit automatically generates unique promo codes for each affiliate based on that coupon
3. Affiliates share their promo codes with potential customers
4. When customers use the code at checkout, PromoteKit tracks the referral
## Setup Methods
- [Stripe Checkout](/docs/affiliate-promo-codes/stripe-checkout): Enable promo codes on Stripe Checkout with a single parameter
- [Stripe API](/docs/affiliate-promo-codes/stripe-api): Use the Stripe API directly for custom checkout flows
- [Default Coupon Code](/docs/affiliate-promo-codes/default-coupon-code): Configure your default coupon for affiliate promo codes
> **Note:** No website script is required for promo code tracking. It works entirely through Stripe.
---
# Setting a Default Coupon Code
URL: /docs/affiliate-promo-codes/default-coupon-code
Description: Configure your default coupon for generating affiliate promo codes
# Setup
Before PromoteKit can generate promo codes for your affiliates, you need to create a coupon in Stripe and set it as your default.
## Understanding Coupons vs Promo Codes
- **Coupon**: Holds the discount details (e.g., 10% off, $5 off)
- **Promo Code**: A unique code linked to a coupon that customers enter at checkout
PromoteKit uses one coupon to generate unlimited unique promo codes for each affiliate automatically.
## Setup Steps
1. ### Create a Coupon in Stripe
Go to your [Stripe Dashboard](https://dashboard.stripe.com/coupons) and create a new coupon with your desired discount.
2. ### Configure in PromoteKit
1. Go to the **Setup** tab in your PromoteKit dashboard
2. Navigate to **Step 4 (PromoteKit Integration)**
3. Select **OPTION 3: Coupon Codes**
4. Choose your default coupon from the dropdown
5. Click **Ok, I've completed this**
3. ### Test the Setup
Sign up as a test affiliate through your affiliate portal. Upon successful registration, you should receive a unique Stripe promo code based on your default coupon.
> **Note:** Make sure to test in Stripe **live mode**. Promo codes created in test mode
won't work in production.
---
# Stripe API Integration
URL: /docs/affiliate-promo-codes/stripe-api
Description: Use the Stripe API directly for promo code tracking
# Overview
For custom checkout flows or mobile apps, you can use the Stripe API directly to apply affiliate promo codes.
This approach is particularly useful for mobile apps where traditional affiliate link tracking may be restricted by app stores.
## Implementation Steps
### 1. Retrieve the Promo Code ID
When a user enters a promo code on your checkout screen, call the [Stripe Promotion Codes API](https://stripe.com/docs/api/promotion_codes/list) to get the promo code ID. Use `stripe.promotionCodes.list` with the code parameter set to the entered code.
### 2. Apply to Subscription
When [creating a subscription](https://docs.stripe.com/api/subscriptions/create), include the `promotion_code` parameter with the promo code ID you retrieved:
```javascript
const subscription = await stripe.subscriptions.create({
customer: 'cus_Na6dX7aXxi11N4',
items: [
{
price: 'price_1MowQULkdIwHu7ixraBm864M',
},
],
promotion_code: 'promo_1MiM6KLkdIwHu7ixrIaX4wgn',
});
```
## Alternative: Update Existing Subscription
You can also apply promo codes to existing subscriptions using the [subscription update API](https://docs.stripe.com/api/subscriptions/update) with the `promotion_code` parameter.
Referral attribution works identically whether you apply the code at creation or update time.
---
# Stripe Checkout Integration
URL: /docs/affiliate-promo-codes/stripe-checkout
Description: Enable promo codes in Stripe Checkout for affiliate tracking
# Overview
Promo code tracking with Stripe Checkout requires almost no setup. No website script is required.
## Implementation Methods
### Via Stripe API
When creating a checkout session via the Stripe API, include `allow_promotion_codes: true` in your checkout session creation call:
```javascript
const session = await stripe.checkout.sessions.create({
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
allow_promotion_codes: true,
line_items: [
{ price: 'price_1OBQlV2eZvKYlo2CDL02DbMx', quantity: 1 },
],
mode: 'subscription',
});
```
### Via Stripe Payment Links
For Stripe Payment Links, enable promo codes through the Stripe Dashboard:
1. Go to your Stripe Dashboard and find your Payment Link
2. Click **Edit** on the Payment Link
3. Expand the **Advanced options** section
4. Check the **Allow promotion codes** checkbox
5. Save your changes
## Next Steps
Once promo codes are enabled, you need to configure your default coupon in PromoteKit. See the [Default Coupon Code documentation](/docs/affiliate-promo-codes/default-coupon-code) for details.
---
# Integrations Overview
URL: /docs/integrations
Description: Connect PromoteKit with popular membership and payment platforms
# Overview
PromoteKit integrates with popular membership platforms to automatically track affiliate referrals when new members sign up.
## Available Integrations
- [Memberstack](/docs/integrations/memberstack): Membership sites with Webflow and Stripe
- [Outseta](/docs/integrations/outseta): All-in-one membership platform
- [MemberSpace](/docs/integrations/memberspace): Turn any website into a membership site
## How Integrations Work
Each integration follows a similar pattern:
1. Add the PromoteKit tracking script to your site
2. Add a platform-specific script to capture signup events
3. When a member signs up, their email and Stripe customer ID are sent to PromoteKit
4. PromoteKit attributes the referral to the correct affiliate
> **Note:** Our [promo codes integration](/docs/affiliate-promo-codes) works with all
these platforms with no special setup required.
---
# MemberSpace Integration
URL: /docs/integrations/memberspace
Description: Track affiliate referrals with MemberSpace membership sites
# Setup
MemberSpace lets you turn any website into a membership site. PromoteKit integrates with MemberSpace to track affiliate referrals when members sign up.
## Setup Steps
### 1. Add the PromoteKit Script
1. Go to your PromoteKit dashboard
2. Navigate to **Setup - Step 4 (PromoteKit Integration)**
3. Select **MemberSpace**
4. Copy and add the PromoteKit script to your site
### 2. Add the Signup Tracking Script
Add the following script to your member signup page. This listens for MemberSpace signup events and passes the member's email to PromoteKit:
```html
```
### 3. Publish and Confirm
1. Publish your site
2. Return to PromoteKit and click **Ok, I've completed this**
**Note:** Referrals will only be tracked in Stripe **live mode** during testing.
---
# Memberstack Integration
URL: /docs/integrations/memberstack
Description: Track affiliate referrals with Memberstack membership sites
# Setup
Memberstack is an easy way to set up a membership site with Webflow and Stripe. PromoteKit integrates seamlessly with Memberstack to track affiliate referrals.
> **Note:** Both affiliate links and promo codes work with Memberstack. Promo codes
require no special setup.
## Setup Steps
1. ### Get the PromoteKit Script
1. Go to your PromoteKit dashboard
2. Navigate to **Setup → Step 4 (PromoteKit Integration)**
3. Select **Memberstack**
4. Copy the provided script
2. ### Add to Your Site
Paste the script into your Memberstack site's `` section.
3. ### Publish and Confirm
1. Publish your site
2. Return to PromoteKit and click **Ok, I've completed this**
> **Note:** Referrals will only be tracked in Stripe **live mode**. Test mode referrals
won't appear in your dashboard.
## Promo Codes
Our [promo codes integration](/docs/affiliate-promo-codes) also works with Memberstack with no special setup steps required. Just make sure you have promo codes enabled in your Stripe Checkout configuration.
---
# Outseta Integration
URL: /docs/integrations/outseta
Description: Track affiliate referrals with Outseta membership platform
# Setup
Outseta is an all-in-one membership platform that includes CRM, subscription billing, and authentication. PromoteKit integrates with Outseta to track affiliate referrals.
## Setup Steps
### 1. Add the PromoteKit Script
1. Go to your PromoteKit dashboard
2. Navigate to **Setup - Step 4 (PromoteKit Integration)**
3. Select **Outseta**
4. Copy and add the PromoteKit script to your site
### 2. Add the Signup Tracking Script
Add the following script to your member signup page. This listens for Outseta signup events and passes the customer's email and Stripe token to PromoteKit:
```html
```
### 3. Publish and Confirm
1. Publish your website
2. Return to PromoteKit and click **Ok, I've completed this**
**Note:** Referrals will only be tracked in Stripe **live mode** during testing.
---
# Payouts Overview
URL: /docs/payouts
Description: Process affiliate commission payments
# Overview
PromoteKit makes it easy to pay your affiliates their earned commissions. You can pay affiliates directly to their bank accounts with [Stripe Connect Payouts](/docs/payouts/stripe-payouts), export batch payment files for PayPal or Wise, or pay through any other method and record the payout manually.
Choose your method under **Settings → Affiliate Program → Affiliate Payout Method**.
## Payout Timing
By default, PromoteKit uses **NET-15** payout terms. This means commissions are due 15 days after the start of the month. For example, commissions earned in December would be due for payout on or after January 15.
To change your payout terms:
1. Go to **Campaign Settings** in your PromoteKit dashboard
2. Click your default campaign
3. Expand **Advanced Campaign Settings**
4. Select your preferred payout term
## Payment Methods
- [Stripe Connect Payouts](/docs/payouts/stripe-payouts): Pay every affiliate at once, directly to their bank accounts in 119
countries through Stripe
- [PayPal Mass Payments](/docs/payouts/paypal-mass-payments): Pay up to 5,000 affiliates at once via PayPal
- [Wise Batch Payments](/docs/payouts/wise-batch-payments): Pay up to 1,000 affiliates at once via Wise
## Manual Payouts
You don't have to use Stripe, PayPal or Wise. You can pay affiliates through any method you prefer (bank transfer, check, crypto, etc.) and then record the payment in PromoteKit:
1. Pay the affiliate through your preferred method
2. Go to **Generate Payouts** in PromoteKit
3. Mark the payment as complete
> **Note:** Regardless of payment method, always mark payouts as complete in PromoteKit so
your records stay accurate.
---
# PayPal Mass Payments
URL: /docs/payouts/paypal-mass-payments
Description: Pay affiliates in bulk using PayPal Mass Payments
# Overview
PayPal Mass Payments allows you to pay up to 5,000 affiliates simultaneously. PromoteKit generates a CSV file formatted specifically for PayPal's Mass Payments system.
## Prerequisites
You need a PayPal Business account with Mass Payments enabled.
1. ### Create a PayPal Business Account
If you don't have one, [create a PayPal Business account](https://www.paypal.com/business).
2. ### Request Mass Payments Access
1. Log into PayPal
2. Click **Pay & Get Paid** in the top menu
3. Under **Make Payments**, click **Payouts**
4. Answer the required questions
5. Submit your request
PayPal will review and approve your request within a few business days.
## Processing Payouts
1. ### Download the CSV
When your payout cycle arrives:
1. Go to the **Generate Payouts** tab in PromoteKit
2. Click **Download Payouts** to get your CSV file
2. ### Upload to PayPal
1. Log into your PayPal Business account
2. Navigate to Mass Payments
3. Upload the CSV file from PromoteKit
4. Review the payments
5. Click **Send Payout**
3. ### Mark as Paid in PromoteKit
After PayPal processes the payments:
1. Return to the **Generate Payouts** tab in PromoteKit
2. Click **Mark all as Paid**
> **Note:** For detailed PayPal instructions, see the [PayPal Mass Payments documentation](https://www.paypal.com/us/cshelp/article/how-do-i-send-a-payouts-mass-payment-help252).
---
# Stripe Connect Payouts
URL: /docs/payouts/stripe-payouts
Description: One-click global payouts
# Stripe Connect Payouts
With Stripe Connect payouts, you can send payouts directly to your affiliates' bank accounts, with no CSV exports or third-party tools required. You fund payouts from your business bank account or a card, select the commissions you want to pay, and PromoteKit sends each affiliate their money using Stripe Connect. Affiliates in [119 countries](#supported-countries) can receive payouts in their local currency.
> **Note:** Stripe Connect Payouts are available on paid plans (including trials) for organizations using USD. If your organization uses another currency, you can convert it to USD once from your settings (see [Requirements](#requirements)).
## Requirements
- **An active PromoteKit subscription** (paid plan or trial).
- **USD as your display currency.** Stripe Connect Payouts are sent in USD. If your organization uses another currency, select **USD** as your display currency under **Settings → Affiliate**. If you already have commissions recorded, PromoteKit converts your existing commission, payout and fixed campaign amounts to USD at the current exchange rate. This conversion is one-way and can't be undone.
- **A funding method:** a US business bank account or a credit or debit card.
- **An Owner or Admin role** to set up funding and send payouts (see [Who Can Manage Payouts](#who-can-manage-payouts)).
## Getting Started
1. ### Choose Stripe Connect as your payout method
Go to **Settings → Affiliate** in your PromoteKit dashboard and select **Stripe Connect** as your **Affiliate Payout Method**. This adds a **Payouts** tab to your settings.
2. ### Add a funding method
Go to **Settings → Payouts** and connect a US business bank account, or add a credit or debit card. You accept the [Payout Terms](https://www.promotekit.com/payout-terms) when you save a funding method.
3. ### Affiliates connect using Stripe Express
Your affiliates connect a Stripe Express account from the **Settings** page of their affiliate portal (see [For Affiliates](#for-affiliates-connecting-stripe-express)). Stripe securely collects their identity details, bank account and tax information.
4. ### Pay affiliates from Generate Payouts
On the **Generate Payouts** page, select the commissions you want to pay and click **Pay with Stripe**. You'll see the exact total, including the processing fee, before confirming with a one-time code sent to your email.
5. ### Affiliates get paid automatically
Your funding method is charged for the payout total plus the processing fee. Once the payment settles and the holding period has passed, PromoteKit transfers each affiliate their commission and Stripe deposits it into their bank account.
## Fees
| Funding method | Processing fee |
| -------------- | -------------- |
| Business bank account (ACH) | 5% |
| Credit or debit card | 8% |
The fee is added on top of the payout total and shown before you confirm. It is never deducted from your affiliates' commissions. Lower processing fees are available for enterprise accounts.
## Minimum Payout
Each affiliate must be owed at least **$20** to be paid through Stripe Connect. If your campaign's minimum payout is higher, that minimum applies instead. Affiliates below the minimum don't appear on the **Generate Payouts** page yet. Their commissions keep accumulating until they reach it.
## Funding with a Bank Account
You can fund payouts from a **US business bank account** via ACH:
- **Business accounts only.** Personal (consumer) bank accounts aren't accepted. If your business account is incorrectly shown as personal, contact support.
- **Instant verification.** You connect your account by logging in to your bank through Stripe. Entering routing and account numbers manually isn't supported.
- **Settlement time.** ACH payments usually take a few business days to settle.
## Funding with a Card
You can fund payouts with a credit or debit card:
- **Credit and debit cards only.** Prepaid cards aren't accepted, and the card's security code (CVC) must verify.
- **Card payout limit.** Card-funded payout amounts are limited for new accounts. For larger payouts, use a business bank account, or contact support to request a higher card limit.
- **You authorize each payout.** Before a card is charged you confirm the amount with a one-time code emailed to you and tick an authorization checkbox. The charge appears on your statement as **PROMOTEKIT\* PAYOUTS**.
- **Payments are final once affiliates are paid.** If you need to cancel a payout, contact us before transfers are sent. Please contact us before disputing a charge with your card issuer (see the [Payout Terms](https://www.promotekit.com/payout-terms)).
## Confirming a Payout
Every Stripe Connect payout must be confirmed with a **one-time code emailed to the admin** sending it. After you review the total and click **Confirm and Pay**, enter the 6-digit code from your inbox. Codes expire after 10 minutes and can only be used once. This protects your funds even if someone gains access to your PromoteKit session.
## Payout Timing
1. **Funding.** Your funding method is charged when you confirm. Card payments settle immediately. ACH payments usually take a few business days.
2. **Holding period.** After your payment settles, there is a **2-business-day holding period** before transfers are sent.
3. **Transfers.** PromoteKit then transfers each affiliate their commission automatically. Stripe deposits the funds into the affiliate's bank account according to their Stripe Express payout schedule.
## Who Can Manage Payouts
Stripe Connect Payouts move real money, so only organization **Owners and Admins** can:
- Link or remove funding methods
- Send payouts and retry failed transfers
- Send payout setup reminders to affiliates
**Members** can't link payout methods or send payouts. You can change a team member's role under **Settings → Members**.
## Emails and Invoices
All Owners and Admins in your organization receive an email when:
- A payout is **initiated**, with a breakdown of every affiliate being paid and the fee
- Your **funding payment succeeds** and transfers are scheduled
- Your **funding payment fails**, with the reason (the commissions are released so you can pay them again)
Affiliates receive an email when their payout is sent, and if a deposit to their bank fails.
Every settled payout gets an **invoice** with a unique invoice number. You can download invoice PDFs under **Settings → Payouts → Payout Invoices**.
## Payout Statuses
Each Stripe Connect payout batch moves through these statuses:
| Status | Meaning |
| ------ | ------- |
| Pending | The payout was created and your payment hasn't been processed yet |
| Processing Payment | Your funding payment is being processed |
| Payment Settled | Funds have settled and transfers are queued (sent after the holding period) |
| Sending Transfers | Transfers to affiliates are being created |
| Completed | All affiliates in the batch have been paid |
| Needs Attention | One or more transfers failed (you can retry them) |
| Payment Failed | Your funding payment failed. The commissions were released and can be paid again |
| Disputed | The funding payment was disputed with your bank or card issuer |
## Failed Transfers
If a transfer to an affiliate fails (for example, their Stripe Express account became restricted), the batch shows **Needs Attention** and the affected payout gets a **Retry** button. The funds stay safely in the payout balance until the transfer succeeds.
If an affiliate's bank deposit fails after the transfer (for example, outdated bank details), Stripe automatically retries once they update their bank account in their Stripe Express dashboard. The affiliate is notified by email.
## For Affiliates: Connecting Stripe Express
Affiliates set up payouts from the **Settings** page of your affiliate portal:
1. Select your country and click **Connect with Stripe**.
2. Complete Stripe Express onboarding: identity details, the bank account you want to be paid to and, for US affiliates, tax information (SSN or EIN).
3. Once Stripe verifies your account, the card shows that you're ready to receive payouts.
Payouts are sent in USD, and Stripe converts them to your local currency and deposits them in your local bank account. Use **Manage Payouts on Stripe** to view your payout history, update your bank details and access tax forms. By connecting a payout method, you agree to the [Payout Terms](https://www.promotekit.com/payout-terms).
On the **Generate Payouts** page, affiliates who haven't connected Stripe Express yet are marked **Not connected** and can't be selected. You can send them a reminder email from the banner or the row's menu.
## Supported Countries
Affiliates can receive Stripe Connect Payouts in the following **119 countries**:
🇦🇱 Albania
🇩🇪 Germany
🇲🇰 North Macedonia
🇩🇿 Algeria
🇬🇭 Ghana
🇳🇴 Norway
🇦🇴 Angola
🇬🇷 Greece
🇴🇲 Oman
🇦🇬 Antigua and Barbuda
🇬🇹 Guatemala
🇵🇰 Pakistan
🇦🇷 Argentina
🇬🇾 Guyana
🇵🇦 Panama
🇦🇲 Armenia
🇭🇰 Hong Kong
🇵🇾 Paraguay
🇦🇺 Australia
🇭🇺 Hungary
🇵🇪 Peru
🇦🇹 Austria
🇮🇸 Iceland
🇵🇭 Philippines
🇦🇿 Azerbaijan
🇮🇳 India
🇵🇱 Poland
🇧🇸 Bahamas
🇮🇩 Indonesia
🇵🇹 Portugal
🇧🇭 Bahrain
🇮🇪 Ireland
🇶🇦 Qatar
🇧🇩 Bangladesh
🇮🇱 Israel
🇷🇴 Romania
🇧🇪 Belgium
🇮🇹 Italy
🇷🇼 Rwanda
🇧🇯 Benin
🇯🇲 Jamaica
🇱🇨 Saint Lucia
🇧🇹 Bhutan
🇯🇵 Japan
🇸🇲 San Marino
🇧🇴 Bolivia
🇯🇴 Jordan
🇸🇦 Saudi Arabia
🇧🇦 Bosnia and Herzegovina
🇰🇿 Kazakhstan
🇸🇳 Senegal
🇧🇼 Botswana
🇰🇪 Kenya
🇷🇸 Serbia
🇧🇳 Brunei
🇰🇼 Kuwait
🇸🇬 Singapore
🇧🇬 Bulgaria
🇱🇦 Laos
🇸🇰 Slovakia
🇰🇭 Cambodia
🇱🇻 Latvia
🇸🇮 Slovenia
🇨🇦 Canada
🇱🇮 Liechtenstein
🇿🇦 South Africa
🇨🇱 Chile
🇱🇹 Lithuania
🇰🇷 South Korea
🇨🇴 Colombia
🇱🇺 Luxembourg
🇪🇸 Spain
🇨🇷 Costa Rica
🇲🇴 Macao
🇱🇰 Sri Lanka
🇨🇮 Côte d'Ivoire
🇲🇬 Madagascar
🇸🇪 Sweden
🇭🇷 Croatia
🇲🇾 Malaysia
🇨🇭 Switzerland
🇨🇾 Cyprus
🇲🇹 Malta
🇹🇼 Taiwan
🇨🇿 Czechia
🇲🇺 Mauritius
🇹🇿 Tanzania
🇩🇰 Denmark
🇲🇽 Mexico
🇹🇭 Thailand
🇩🇴 Dominican Republic
🇲🇩 Moldova
🇹🇹 Trinidad and Tobago
🇪🇨 Ecuador
🇲🇨 Monaco
🇹🇳 Tunisia
🇪🇬 Egypt
🇲🇳 Mongolia
🇹🇷 Türkiye
🇸🇻 El Salvador
🇲🇦 Morocco
🇦🇪 United Arab Emirates
🇪🇪 Estonia
🇲🇿 Mozambique
🇬🇧 United Kingdom
🇪🇹 Ethiopia
🇳🇦 Namibia
🇺🇸 United States
🇫🇮 Finland
🇳🇱 Netherlands
🇺🇾 Uruguay
🇫🇷 France
🇳🇿 New Zealand
🇺🇿 Uzbekistan
🇬🇦 Gabon
🇳🇪 Niger
🇻🇳 Vietnam
🇬🇲 Gambia
🇳🇬 Nigeria
Affiliates in other countries can't receive Stripe Connect payouts. You can still pay them another way (for example with [PayPal](/docs/payouts/paypal-mass-payments) or [Wise](/docs/payouts/wise-batch-payments)) and use **Mark as paid** in the row's menu on the **Generate Payouts** page to record the payout.
## Tax Forms
Affiliates provide identity and tax details (such as SSN or EIN for US affiliates) during Stripe Express onboarding. PromoteKit handles 1099 reporting for eligible US affiliates paid through Stripe Connect Payouts, issuing 1099 forms through Stripe after the end of each tax year. Affiliates can access their tax forms from their Stripe Express dashboard.
## Terms
Stripe Connect Payouts are governed by the [Payout Terms](https://www.promotekit.com/payout-terms), which supplement the PromoteKit Terms of Service and Affiliate Terms.
---
# Wise Batch Payments
URL: /docs/payouts/wise-batch-payments
Description: Pay affiliates in bulk using Wise Batch Payments
# Overview
Wise Batch Payments allows you to pay up to 1,000 affiliates at a time with low international transfer fees. PromoteKit generates a CSV file formatted specifically for Wise.
## Prerequisites
You need a Wise Business account.
1. ### Create a Wise Business Account
[Create a free Wise Business account](https://wise.com/register?profileType=BUSINESS#/email) if you don't have one.
## Processing Payouts
1. ### Download the CSV
When your payout cycle arrives:
1. Go to the **Generate Payouts** tab in PromoteKit
2. Click **Download Payouts** to get your CSV file
2. ### Upload to Wise
1. Log into your Wise Business account
2. Navigate to Batch Payments
3. Upload the CSV file from PromoteKit
4. Review the payments
5. Initiate the payout
3. ### Mark as Paid in PromoteKit
After Wise processes the payments:
1. Return to the **Generate Payouts** tab in PromoteKit
2. Click **Mark all as Paid**
> **Note:** For detailed Wise instructions, see the [Wise Batch Payments documentation](https://wise.com/help/articles/2827506/how-do-i-send-a-batch-payment).
---
# Webhooks Overview
URL: /docs/webhooks
Description: Receive real-time event notifications from PromoteKit
# Webhooks
PromoteKit sends webhook events to notify your application in real-time when things happen in your affiliate program. You can use webhooks to trigger automations, sync data to external systems, or build custom workflows.
## Setting Up Webhooks
1. Go to **Settings > Webhooks** in your PromoteKit dashboard
2. Click **Add Endpoint** to create a new webhook endpoint
3. Enter your endpoint URL (must be HTTPS)
4. Select which event types you want to receive
5. Save the endpoint
You can manage your endpoints, view delivery logs, and retry failed deliveries from the Webhooks settings page.
## Event Types
PromoteKit sends the following webhook events:
| Event | Description |
| -------------------- | -------------------------------------------------------------------------------- |
| `affiliate.created` | A new affiliate is created (from the dashboard, API, or affiliate portal signup) |
| `affiliate.approved` | An affiliate is approved (individually or via bulk approval) |
| `referral.created` | A new referral is tracked (from Stripe, the dashboard, API, or tracking script) |
| `referral.converted` | A referral receives their first commission (first paid conversion) |
| `commission.created` | A new commission is generated (from Stripe payments, the dashboard, or API) |
| `payout.sent` | A Stripe Connect payout transfer was sent to an affiliate's connected account |
## Payload Format
All webhook events are sent as HTTP POST requests with a JSON body. The payload has the following structure:
```json
{
"type": "affiliate.created",
"data": {
// The resource object in the same format as the API
}
}
```
The `data` field contains the resource object in the **same format as the corresponding API endpoint**. For example, an `affiliate.created` event contains the same affiliate object you would get from the [GET /affiliates/:id](/docs/api-reference/affiliates/get-affiliate) API endpoint.
### affiliate.created / affiliate.approved
```json
{
"type": "affiliate.created",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "affiliate@example.com",
"first_name": "Jane",
"last_name": "Doe",
"payout_email": "jane@example.com",
"links": [
{
"url": "https://yoursite.com?via=jane",
"code": "jane"
}
],
"promo_codes": [
{
"code": "JANE20",
"external_id": "promo_abc123"
}
],
"clicks": 0,
"approved": true,
"banned": false,
"details": null,
"custom_fields": [
{
"id": "8c1f0c2e-3b6d-4f0a-9c1e-2a7d5e9b1f44",
"label": "How did you hear about us?",
"value": "Twitter"
}
],
"new_paid_referral_notifications": true,
"created_at": "2025-01-15T10:30:00Z",
"campaign": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Default Campaign",
"commission_type": "percentage",
"commission_amount": 20
}
}
}
```
The `custom_fields` array contains the affiliate's answers to any custom signup form fields configured for the campaign (Campaign Settings → Custom Signup Form Fields). Each entry has the field `id`, the question `label` as it was shown at signup, and the affiliate's `value`. Optional fields the affiliate skipped have an empty `value`. The array is empty when the campaign has no custom fields or the affiliate was created from the dashboard or API.
### referral.created / referral.converted
```json
{
"type": "referral.created",
"data": {
"id": "770e8400-e29b-41d4-a716-446655440002",
"email": "customer@example.com",
"subscription_status": "signed_up",
"signup_date": "2025-01-20T14:00:00Z",
"stripe_customer_id": "cus_abc123",
"created_at": "2025-01-20T14:00:00Z",
"affiliate": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "affiliate@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}
}
```
### commission.created
```json
{
"type": "commission.created",
"data": {
"id": "880e8400-e29b-41d4-a716-446655440003",
"revenue_amount": 99.0,
"currency": "USD",
"commission_amount": 19.8,
"payout_status": "not_paid",
"referral_date": "2025-01-20T14:00:00Z",
"created_at": "2025-01-20T14:00:00Z",
"stripe_payment_id": "pi_abc123",
"affiliate": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "affiliate@example.com",
"first_name": "Jane",
"last_name": "Doe"
},
"referral": {
"id": "770e8400-e29b-41d4-a716-446655440002",
"email": "customer@example.com",
"subscription_status": "active",
"signup_date": "2025-01-20T14:00:00Z",
"stripe_customer_id": "cus_abc123",
"created_at": "2025-01-20T14:00:00Z"
},
"payout": null
}
}
```
### payout.sent
Sent when a [Stripe Connect payout](/docs/payouts/stripe-payouts) transfer is created for an affiliate (the money is on its way to their bank account).
```json
{
"type": "payout.sent",
"data": {
"id": "990e8400-e29b-41d4-a716-446655440004",
"affiliate_name": "Jane Doe",
"payout_email": "jane@example.com",
"amount": 250.0,
"currency": "USD",
"period": "2025-02-01T00:00:00Z",
"payment_count": 5,
"status": "completed",
"method": "stripe",
"created_at": "2025-02-01T10:30:00Z",
"affiliate": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "affiliate@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}
}
```
## Verifying Webhook Signatures
PromoteKit signs all webhook payloads so you can verify they are authentic. Each webhook request includes the following headers:
| Header | Description |
| ---------------- | ---------------------------------------------- |
| `svix-id` | Unique message identifier |
| `svix-timestamp` | Unix timestamp of when the message was created |
| `svix-signature` | The signature(s) for the payload |
### Finding Your Signing Secret
1. Go to **Settings > Webhooks** in your dashboard
2. Click on your endpoint
3. Click **Signing Secret** to reveal your endpoint's secret
The secret starts with `whsec_`.
### Verifying with the Svix Library (Recommended)
Install the Svix library for your language:
```bash
npm install svix
```
```bash
pip install svix
```
Then verify the webhook:
```javascript
const secret = "whsec_your_secret_here";
const wh = new Webhook(secret);
// In your webhook handler:
app.post("/webhook", (req, res) => {
const headers = req.headers;
const payload = req.body; // Must be the raw request body string
try {
const event = wh.verify(payload, headers);
// Process the verified event
console.log("Event type:", event.type);
console.log("Event data:", event.data);
} catch (err) {
console.error("Webhook verification failed:", err);
return res.status(400).send("Invalid signature");
}
res.status(200).send("OK");
});
```
```python
from svix.webhooks import Webhook
secret = "whsec_your_secret_here"
wh = Webhook(secret)
# In your webhook handler:
headers = request.headers
payload = request.body # Must be the raw request body
try:
event = wh.verify(payload, headers)
# Process the verified event
print("Event type:", event["type"])
except Exception as e:
print("Webhook verification failed:", e)
return Response(status=400)
```
> **Warning:** You must use the **raw request body** when verifying webhooks. If your
framework automatically parses JSON, you need to capture the raw body before
parsing.
### Manual Verification
If you prefer to verify manually, the signature is computed as an HMAC-SHA256 of the message ID, timestamp, and body:
```
signed_content = "${svix_id}.${svix_timestamp}.${body}"
signature = base64(hmac_sha256(base64_decode(secret), signed_content))
```
Compare your computed signature against the one in the `svix-signature` header (after the `v1,` prefix).
## Retry Behavior
If your endpoint returns a non-2xx status code, PromoteKit will retry the delivery with exponential backoff. You can view delivery attempts and manually retry failed deliveries from the **Settings > Webhooks** page in your dashboard.
## Best Practices
- **Respond quickly**: Return a 2xx status code within 15 seconds. Process the event asynchronously if needed.
- **Handle duplicates**: Webhook deliveries may be retried. Use the `svix-id` header to deduplicate.
- **Verify signatures**: Always verify the webhook signature before processing events.
- **Use HTTPS**: Webhook endpoints must use HTTPS.
---
---
---
---
# API Reference
---
---
Base URL: https://www.promotekit.com/api/v1
---
Authentication: Bearer token in the Authorization header.
---
---
# Introduction
URL: /docs/api-reference
Description: Welcome to the PromoteKit API documentation
# Overview
The PromoteKit API enables you to programmatically manage your affiliate program, including affiliates, campaigns, referrals, commissions, and payouts. The API follows RESTful principles and uses standard HTTP methods. All requests and responses use JSON format.
## Base URL
All API requests should be made to:
```
https://www.promotekit.com/api/v1
```
## Authentication
All API endpoints require authentication using Bearer token authentication. Include your API key in the Authorization header:
```
Authorization: Bearer
```
You can create API keys in [Dashboard Settings → API Keys](https://promotekit.com/dashboard).
> **Note:** API access requires an active or trialing PromoteKit subscription. If your
subscription lapses, requests made with your API keys will fail with a `403`
response and the error type `subscription_error` until the subscription is
reactivated. Your keys are kept and start working again as soon as the
subscription is active.
## Response Format
All responses are returned in JSON format and include a `success` boolean indicating if the request was successful.
### Success Response
```json
{
"success": true,
"data": { ... }
}
```
### Error Response
```json
{
"success": false,
"error": {
"message": "Error description",
"type": "error_type"
}
}
```
## Rate Limiting
API requests are limited to **200 requests per minute** per API key. If you exceed this limit, you'll receive a `429 Too Many Requests` response.
## Pagination
List endpoints support pagination using `limit` and `page` parameters:
- `limit` - Number of records to return (default: 10, max: 100)
- `page` - Page number, 1-indexed (default: 1)
Paginated responses include:
```json
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 10,
"total_count": 45,
"total_pages": 5,
"has_more": true
}
}
```
---
# Create affiliate
URL: /docs/api-reference/affiliates/create-affiliate
Description: Creates a new affiliate in your organization.
**POST** `https://www.promotekit.com/api/v1/affiliates`
Creates a new affiliate in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Request Body
- `email`: string (email) **(required)** - Affiliate email (required)
- `first_name`: string **(required)** - First name
- `last_name`: string **(required)** - Last name
- `payout_email`: string (email) - Payout email address
- `ref_code`: string - Unique code that goes at the end of the affiliate link
- `promo_code`: string - Stripe promo code (will be generated if it doesn't already exist in Stripe)
- `campaign_id`: string (uuid) - Campaign UUID (uses default if not provided)
- `approved`: boolean - Whether to approve the affiliate to start promoting immediately
- `details`: string - Additional details
- `new_paid_referral_notifications`: boolean - Whether the affiliate receives email alerts when they make a new paid referral
## Responses
### 200 - Affiliate created
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Get affiliate
URL: /docs/api-reference/affiliates/get-affiliate
Description: Retrieves a single affiliate by UUID.
**GET** `https://www.promotekit.com/api/v1/affiliates/{id}`
Retrieves a single affiliate by UUID.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# List affiliates
URL: /docs/api-reference/affiliates/list-affiliates
Description: Returns a paginated list of affiliates in your organization.
**GET** `https://www.promotekit.com/api/v1/affiliates`
Returns a paginated list of affiliates in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `campaign_id` (query): string (uuid) - Filter by campaign UUID
- `email` (query): string (email) - Filter by affiliate email. Returns 0 or 1 results.
- `ref_code` (query): string - Filter by affiliate link referral code (unique code at the end of the affiliate's link).
- `promo_code` (query): string - Filter by affiliate promo code.
- `limit` (query): integer (default: 10) - Number of records to return (default: 10, max: 100)
- `page` (query): integer (default: 1) - Page number (1-indexed)
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: array **(required)**
- `pagination`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Update affiliate
URL: /docs/api-reference/affiliates/update-affiliate
Description: Updates an existing affiliate.
**PUT** `https://www.promotekit.com/api/v1/affiliates/{id}`
Updates an existing affiliate.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Request Body
- `email`: string (email) - Affiliate email
- `first_name`: string - First name
- `last_name`: string - Last name
- `payout_email`: string (email) - Payout email address
- `ref_code`: string - Unique code that goes at the end of the affiliate link
- `promo_code`: string - Stripe promo code (will be generated if it doesn't already exist in Stripe)
- `campaign_id`: string (uuid) - Campaign UUID to assign the affiliate to
- `approved`: boolean - Whether the affiliate has been approved to start promoting
- `banned`: boolean - Whether the affiliate is banned. Banned affiliates are not eligible for future commissions and payouts.
- `details`: string - Additional details
- `new_paid_referral_notifications`: boolean - Whether the affiliate receives email alerts when they make a new paid referral
## Responses
### 200 - Affiliate updated
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Create campaign
URL: /docs/api-reference/campaigns/create-campaign
Description: Creates a new campaign in your organization.
**POST** `https://www.promotekit.com/api/v1/campaigns`
Creates a new campaign in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Request Body
- `name`: string **(required)** - Campaign name (for internal use, affiliates do not see this name)
- `commission_type`: string: `percentage`, `fixed` **(required)** - Whether the campaign gives percentage based or fixed amount commissions
- `commission_amount`: number **(required)** - Percentage or fixed amount commission rate (e.g. 20 would mean 20% or $20)
- `code_mode`: string: `link`, `coupon`, `both` **(required)** - Referral code type. "link" creates affiliate links, "coupon" creates promo codes, "both" creates both.
- `website_url`: string - Campaign website URL. Required when code_mode is "link" or "both".
- `reference_coupon`: string - Stripe coupon ID that's used to create affiliate promo codes. Required when code_mode is "coupon" or "both".
- `is_default`: boolean
## Responses
### 200 - Campaign created
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Get campaign
URL: /docs/api-reference/campaigns/get-campaign
Description: Retrieves a single campaign by UUID.
**GET** `https://www.promotekit.com/api/v1/campaigns/{id}`
Retrieves a single campaign by UUID.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# List campaigns
URL: /docs/api-reference/campaigns/list-campaigns
Description: Returns a paginated list of campaigns in your organization.
**GET** `https://www.promotekit.com/api/v1/campaigns`
Returns a paginated list of campaigns in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `limit` (query): integer (default: 10) - Number of records to return (default: 10, max: 100)
- `page` (query): integer (default: 1) - Page number (1-indexed)
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: array **(required)**
- `pagination`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Update campaign
URL: /docs/api-reference/campaigns/update-campaign
Description: Updates an existing campaign.
**PUT** `https://www.promotekit.com/api/v1/campaigns/{id}`
Updates an existing campaign.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Request Body
- `name`: string
- `commission_type`: string: `percentage`, `fixed`
- `commission_amount`: number
- `code_mode`: string: `link`, `coupon`, `both` - Referral code mode. "link" creates affiliate links, "coupon" creates promo codes, "both" creates both.
- `website_url`: string - Campaign website URL. Required when code_mode is "link" or "both".
- `reference_coupon`: string - Stripe coupon ID for the campaign. Required when code_mode is "coupon" or "both".
- `is_default`: boolean
## Responses
### 200 - Campaign updated
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Create commission
URL: /docs/api-reference/commissions/create-commission
Description: Manually creates a commission for a referral.
**POST** `https://www.promotekit.com/api/v1/commissions`
Manually creates a commission for a referral.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Request Body
- `referral_id`: string (uuid) **(required)** - UUID of the referral this commission is for (required)
- `revenue_amount`: number **(required)** - Transaction/revenue amount (required, must be greater than 0)
- `commission_amount`: number **(required)** - Commission earned (required, must be greater than 0)
- `referral_date`: string (date-time) - Date of the referral (defaults to now)
- `stripe_payment_id`: string - Stripe payment ID reference
## Responses
### 200 - Commission created
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Get commission
URL: /docs/api-reference/commissions/get-commission
Description: Retrieves a single commission by UUID.
**GET** `https://www.promotekit.com/api/v1/commissions/{id}`
Retrieves a single commission by UUID.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# List commissions
URL: /docs/api-reference/commissions/list-commissions
Description: Returns a paginated list of commission records in your organization.
**GET** `https://www.promotekit.com/api/v1/commissions`
Returns a paginated list of commission records in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `affiliate_id` (query): string (uuid) - Filter by affiliate UUID
- `payout_status` (query): string - one of: `not_paid`, `paid` - Filter by payout status
- `payout_id` (query): string (uuid) - Filter by payout UUID. Returns only commissions included in the specified payout.
- `limit` (query): integer (default: 10) - Number of records to return (default: 10, max: 100)
- `page` (query): integer (default: 1) - Page number (1-indexed)
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: array **(required)**
- `pagination`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Update commission
URL: /docs/api-reference/commissions/update-commission
Description: Updates the commission amount of an unpaid commission.
**PUT** `https://www.promotekit.com/api/v1/commissions/{id}`
Updates the commission amount of an existing commission. Only `commission_amount` can be updated.
Only commissions with `payout_status` of `not_paid` that are not linked to any payout can be edited. Commissions that have been paid out or are processing in a payout are locked and return `409 conflict_error`.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Request Body
- `commission_amount`: number **(required)** - New commission amount in the organization's currency (must be greater than 0)
## Responses
### 200 - Commission updated
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 409 - The resource is in a state that does not allow this operation
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Get payout
URL: /docs/api-reference/payouts/get-payout
Description: Retrieves a single payout by UUID.
**GET** `https://www.promotekit.com/api/v1/payouts/{id}`
Retrieves a single payout by UUID.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# List payouts
URL: /docs/api-reference/payouts/list-payouts
Description: Returns a paginated list of payouts in your organization.
**GET** `https://www.promotekit.com/api/v1/payouts`
Returns a paginated list of payouts in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `affiliate_id` (query): string (uuid) - Filter by affiliate UUID
- `limit` (query): integer (default: 10) - Number of records to return (default: 10, max: 100)
- `page` (query): integer (default: 1) - Page number (1-indexed)
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: array **(required)**
- `pagination`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Create referral
URL: /docs/api-reference/referrals/create-referral
Description: Creates a new referral for an affiliate in your organization.
**POST** `https://www.promotekit.com/api/v1/referrals`
Creates a new referral for an affiliate in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Request Body
- `affiliate_id`: string (uuid) **(required)** - UUID of the affiliate this referral belongs to
- `email`: string (email) **(required)** - Email address of the referred customer
- `stripe_customer_id`: string - Stripe customer ID of the referred customer
- `subscription_status`: string: `active`, `signed_up`, `trialing`, `canceled`, `past_due` - Subscription status of the referred customer
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# List referrals
URL: /docs/api-reference/referrals/list-referrals
Description: Returns a paginated list of referred customers.
**GET** `https://www.promotekit.com/api/v1/referrals`
Returns a paginated list of referrals (referred users) in your organization.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `affiliate_id` (query): string (uuid) - Filter by affiliate UUID
- `email` (query): string (email) - Filter by referred customer email (exact match)
- `stripe_customer_id` (query): string - Filter by Stripe customer ID
- `subscription_status` (query): string - Filter by subscription status. Possible values: `signed_up`, `active`, `trialing`, `canceled`, `past_due`. Pass a comma-separated list to filter by multiple statuses (e.g. `?subscription_status=active,trialing`).
- `limit` (query): integer (default: 10) - Number of records to return (default: 10, max: 100)
- `page` (query): integer (default: 1) - Page number (1-indexed)
## Responses
### 200 - Successful response
- `success`: boolean **(required)**
- `data`: array **(required)**
- `pagination`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**
---
# Update referral
URL: /docs/api-reference/referrals/update-referral
Description: Updates an existing referral's Stripe customer ID or subscription status.
**PUT** `https://www.promotekit.com/api/v1/referrals/{id}`
Updates an existing referral. Only `stripe_customer_id` and `subscription_status` can be updated. At least one field must be provided.
## Authentication
Requires a Bearer token in the `Authorization` header.
## Parameters
- `id` (path): string (uuid) **(required)** - Resource UUID
## Request Body
- `stripe_customer_id`: string, nullable - Stripe customer ID of the referred customer. Pass `null` to clear it.
- `subscription_status`: string: `active`, `signed_up`, `trialing`, `canceled`, `past_due` - Subscription status of the referred customer
## Responses
### 200 - Referral updated
- `success`: boolean **(required)**
- `data`: object **(required)**
### 400 - Invalid request
- `success`: boolean **(required)**
- `error`: object **(required)**
### 401 - Authentication failed
- `success`: boolean **(required)**
- `error`: object **(required)**
### 403 - The organization that owns the API key does not have an active or trialing subscription
- `success`: boolean **(required)**
- `error`: object **(required)**
### 404 - Resource not found
- `success`: boolean **(required)**
- `error`: object **(required)**
### 429 - Rate limit exceeded
- `success`: boolean **(required)**
- `error`: object **(required)**