openapi: 3.0.1
info:
title: FirstPromoter Admin Commissions Track API
version: '2.0'
description: REST API for managing affiliate programs, promoters, campaigns, referrals, rewards, and payouts in FirstPromoter. Supports pagination, filtering, and full CRUD operations across all affiliate program resources.
contact:
url: https://docs.firstpromoter.com
license:
name: Proprietary
url: https://firstpromoter.com/terms
servers:
- url: https://api.firstpromoter.com/api/v2
description: Production server
security:
- BearerAuth: []
tags:
- name: Track
paths:
/track/signup:
post:
description: Capture a lead when they sign-up or fill an optin form. This endpoint is used to track leads and sign-ups. It's not for tracking the actual sales and commissions.
Sign-ups are tracked as leads in FirstPromoter so when a person referred by the promoter/affiliate signs up, a new referral should be added inside FirstPromoter **(you can see them inside the `Referrals` section as `Leads`)**.
The recommended way to do this is to grab the `_fprom_tid` **(_fprom_track for accounts created prior to April 2021)** cookie value(which keeps the tracking id and referral identification) on your server and send it along with the sign-up data through the tid parameter.
**Alternative:** In some special cases, you can refer sign ups directly to a promoter, by passing the referral id through ref_id parameter. Be careful when using this because the referral id can be modified by the promoter by default, however you can disable that from the campaign configuration page.**HTTP Request**
`POST https://api.firstpromoter.com/api/v2/track/signup`
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: Email of the lead/sign-up. Required if uid is not provided.
uid:
type: string
description: ID to match the sale with the lead if the email can be changed before the first sale. Required if email is not provided.
tid:
type: string
description: Visitor tracking ID. It's set when the visitor tracking script tracks the referral visit on our system. The value is found inside _fprom_tid cookie. Required if ref_id is not provided.
ref_id:
type: string
description: Default referral id of the promoter. Use this only when you want to assign the lead to a specific promoter. Required if tid is not provided.
ip:
type: string
description: IP of the visitor who generated the sign up. It's used for fraud analysis.
created_at:
type: string
description: ISO date string of the date of the signup event
skip_email_notification:
type: boolean
description: Set this to true to skip email notifications. Default is false.
oneOf:
- required:
- email
- required:
- uid
parameters:
- $ref: '#/components/parameters/AccountId'
responses:
'200':
description: Successful signup response
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 45831611
etype:
type: string
example: signup
sale_amount:
type: integer
nullable: true
example: null
original_sale_amount:
type: integer
nullable: true
example: null
original_sale_currency:
type: string
nullable: true
example: null
event_id:
type: string
nullable: true
example: null
plan_id:
type: string
nullable: true
example: null
billing_period:
type: string
nullable: true
example: null
created_at:
type: string
format: date-time
example: '2025-04-25T09:29:51.973Z'
referral:
type: object
properties:
id:
type: integer
example: 29203686
email:
type: string
example: testme@test1.com
uid:
type: string
nullable: true
example: null
commissions:
type: array
items: {}
example: []
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Error. Email and uid can not be blank!
'404':
description: Not Found
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Visitor invalid, not found or you are trying to use the signup tracking test via API which doesn't work on API calls.
'422':
description: Unprocessable Entity
content:
application/json:
schema:
type: object
properties:
transaction_id:
type: string
example: there is already a signup event registered on this lead
tags:
- Track
/track/sale:
post:
description: Assign sales and commissions to your promoters. To track sales and generate commissions correctly, you need to use this API call each time a non-zero amount sale is processed in your system, even if it comes from a recurring charge or one-time charge. To avoid fraudulent sales, we don't use JS conversion pixels to track sales, which are very unreliable and can be easily faked. Instead, we use server-side tracking for all sales to ensure that a sale is tracked only when you actually receive money in your billing account.
To maintain the same standards with the API, we recommend making the sale API call (this call) only when you receive confirmation of the sale from your billing provider, such as from a webhook, an IPN, or a success response from an API charge call.
You just need to pass the sale amount (before taxes) and we'll take care of the rest. The commissions/rewards will be calculated based on that amount and the plan ID, in case you use the plan-level rewards feature. Using email or UID parameters, we identify the lead/customer who generated the sale, which also helps us determine the promoter who owns the reward/commission.
The lead is added to our system either by the client signup tracking script when the user signs up or by calling the signup API endpoint. There is also the option to bypass the signup tracking by using TID or ref_id parameters, which will create the lead and assign the sale in one go.
**If we don't find the lead in our system, then it means that the sale is not a referral sale, you'll get a 404 response. Also, if the promoter is banned, you'll get a 404 response. You don't have to identify which sale is from referrals and which is not; we'll take care of that.** **For zero-decimal** currencies like `JPY`, `amount` and `mrr` parameters should be sent as **whole values**.
**For other currencies**, `amount` and `mrr` parameter values should be in cents, i.e., you will need to **multiply the value by 100** before sending the request.**HTTP Request**
`POST https://api.firstpromoter.com/api/v2/track/sale`
parameters:
- $ref: '#/components/parameters/AccountId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- event_id
- amount
properties:
email:
type: string
description: Email of the lead/sign-up. Required if uid is not provided.
uid:
type: string
description: uid of the lead added on signup tracking. Required if email is not provided.
event_id:
type: string
description: Transaction or sale event ID. Required to avoid duplicate sales.
amount:
type: integer
description: The sale amount in cents. For zero-decimal currencies like JPY, amount should be whole values.
quantity:
type: integer
description: Number of subscriptions/items. Optional if quantity is 1.
plan:
type: string
description: Customer plan ID from billing provider. Used for plan-level rewards.
currency:
type: string
description: Required only if different from FirstPromoter settings default currency.
mrr:
type: string
description: Monthly Recurring Revenue generated by the customer.
promo_code:
type: string
description: For promo code tracking.
tid:
type: string
description: Visitor tracking ID from _fprom_tid cookie.
ref_id:
type: string
description: Referral ID of the promoter.
skip_email_notification:
type: boolean
description: Set true to skip email notifications. Default is false.
oneOf:
- required:
- email
- required:
- uid
responses:
'200':
description: Sale tracked successfully
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 45831949
etype:
type: string
example: sale
sale_amount:
type: integer
example: 2000
original_sale_amount:
type: integer
example: 2000
original_sale_currency:
type: string
nullable: true
example: null
event_id:
type: string
nullable: true
example: null
plan_id:
type: string
nullable: true
example: null
billing_period:
type: string
nullable: true
example: null
created_at:
type: string
format: date-time
example: '2025-04-25T09:39:42.289Z'
referral:
type: object
properties:
id:
type: integer
example: 29203686
email:
type: string
example: testme@test1.com
uid:
type: string
nullable: true
example: null
commissions:
type: array
items:
type: object
properties:
id:
type: integer
example: 13533003
status:
type: string
example: approved
metadata:
type: object
example: {}
is_self_referral:
type: boolean
example: false
commission_type:
type: string
example: sale
created_by_user_email:
type: string
nullable: true
example: null
created_by_user_at:
type: string
nullable: true
example: null
sale_amount:
type: integer
example: 2000
original_sale_amount:
type: integer
example: 2000
original_sale_currency:
type: string
nullable: true
example: null
event_id:
type: string
nullable: true
example: null
plan_id:
type: string
nullable: true
example: null
tier:
type: integer
example: 1
internal_note:
type: string
nullable: true
example: null
external_note:
type: string
nullable: true
example: null
unit:
type: string
example: cash
fraud_check:
type: string
example: no_suspicion
amount:
type: integer
example: 400
is_paid:
type: boolean
example: false
is_split:
type: boolean
example: false
created_at:
type: string
format: date-time
example: '2025-04-25T09:39:42Z'
status_updated_at:
type: string
nullable: true
example: null
promoter_campaign:
type: object
properties:
id:
type: integer
example: 14850130
campaign_id:
type: integer
example: 28004
promoter_id:
type: integer
example: 8262622
created_at:
type: string
format: date-time
example: '2025-01-16T18:16:41Z'
promoter:
type: object
properties:
id:
type: integer
example: 8262622
email:
type: string
example: test@promoter.com
name:
type: string
example: Test Promoter
campaign:
type: object
properties:
id:
type: integer
example: 28004
name:
type: string
example: Quinn Ramirez
color:
type: string
example: '#EC4899'
referral:
type: object
properties:
id:
type: integer
example: 29203686
email:
type: string
example: testme@test1.com
uid:
type: string
nullable: true
example: null
reward:
type: object
properties:
id:
type: integer
example: 157427
name:
type: string
example: 20% recurring commission
'404':
description: Not Found
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Referral corresponding to email or uid parameter not found or promoter is banned.
code:
type: string
example: not_found
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Error. Amount blank or invalid.
'409':
description: Conflict
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The 'sale' event with the id 'test_sale_12340987' already exists.
tags:
- Track
/track/refund:
post:
description: The refund call is similar to the sale call. It works the same way, except that it generates negative commissions. **HTTP Request**
`POST https://api.firstpromoter.com/api/v2/track/refund`
parameters:
- $ref: '#/components/parameters/AccountId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- event_id
- amount
properties:
email:
type: string
description: Email of the lead/sign-up. Required if uid is not provided.
uid:
type: string
description: uid of the lead added on signup tracking. Required if email is not provided.
event_id:
type: string
description: Transaction or refund event ID. Required to avoid generating duplicate refunds.
amount:
type: string
description: The refund amount in cents. Used to calculate negative commissions/rewards.
currency:
type: string
description: This field is only required if the currency of the sale/refund is not the same as the one set on FirstPromoter settings. We'll automatically convert the amount from this currency to the default one set on your FirstPromoter account.
quantity:
type: string
description: Number of subscriptions/items refunded. Optional if quantity is 1.
sale_event_id:
type: string
description: The event id of the sale for which the refund is processed. Should match the event_id from the sales tracking API call. Required for accurate tracking of multiple products or changing commission levels.
skip_email_notification:
type: boolean
description: Set true to skip email notifications. Default is false.
oneOf:
- required:
- email
- required:
- uid
responses:
'200':
description: Success response
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 33847726
type:
type: string
example: refund
amount_cents:
type: integer
example: -1000
reward:
type: object
properties:
id:
type: integer
example: 10940148
status:
type: string
example: approved
amount:
type: integer
example: -200
unit:
type: string
example: cash
created_at:
type: string
format: date-time
example: '2024-09-11T14:36:01.016Z'
lead:
$ref: '#/components/schemas/Lead'
event_id:
type: string
example: test_sale_12340987_refund
conversion_amount:
type: integer
example: -1000
tier_level:
type: integer
example: 1
split_type:
type: string
nullable: true
example: null
lead:
$ref: '#/components/schemas/Lead'
promoter:
$ref: '#/components/schemas/Promoter'
'204':
description: No Content
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Error. Amount blank or invalid.
'409':
description: Conflict
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The 'refund' event with the id 'test_sale_12340987_refund' already exists.
tags:
- Track
/track/cancellation:
post:
description: This call will mark the customer as cancelled and will decrease the MRR generated by them. **HTTP Request**
`POST https://api.firstpromoter.com/api/v2/track/cancellation`
parameters:
- $ref: '#/components/parameters/AccountId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: Email of the lead/sign-up. Required if uid is not provided.
uid:
type: string
description: uid of the lead added on signup tracking. Required if email is not provided.
oneOf:
- required:
- email
- required:
- uid
responses:
'200':
description: Success response
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 33848911
type:
type: string
example: cancellation
amount_cents:
type: integer
nullable: true
example: null
reward:
type: object
nullable: true
example: null
lead:
$ref: '#/components/schemas/Lead'
promoter:
$ref: '#/components/schemas/Promoter'
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Error. Email and uid can not be blank!
tags:
- Track
components:
schemas:
Lead:
type: object
properties:
id:
type: integer
example: 20738339
state:
type: string
example: cancelled
email:
type: string
example: hello@testmintli.com
uid:
type: string
nullable: true
example: null
customer_since:
type: string
format: date-time
example: '2024-09-11T14:22:12.160Z'
cancelled_at:
type: string
format: date-time
example: '2024-09-11T15:07:46.174Z'
plan_name:
type: string
nullable: true
example: null
suspicion:
type: string
example: no_suspicion
username:
type: string
nullable: true
example: null
website:
type: string
nullable: true
example: null
created_at:
type: string
format: date-time
example: '2024-09-09T16:22:44.168Z'
split_promotion_id:
type: string
nullable: true
example: null
custom_fields:
type: string
nullable: true
example: null
split_percentage_value:
type: string
nullable: true
example: null
visitor_sub_id:
type: string
nullable: true
example: null
Promoter:
type: object
properties:
id:
type: integer
email:
type: string
name:
type: string
parameters:
AccountId:
name: Account-ID
in: header
required: true
description: Account ID. You can find your Account ID on Your FirstPromoter Dashboard. Navigate to Settings → Integrations
schema:
type: string
securitySchemes:
BearerAuth:
type: http
scheme: bearer
description: API key passed as Bearer token