API ReferenceTrack
Track Sale
Report a sale conversion event and attribute revenue to the referring partner for commission calculation.
POST /api/track/saleReports a sale event when a referred customer completes a purchase. Refport uses this to calculate the partner's commission and queue a payout.
Request
Headers
| Header | Value |
|---|---|
Authorization | Bearer YOUR_API_KEY |
Content-Type | application/json |
Body
{
"clickId": "abc123",
"customerExternalId": "user_001",
"amount": 4900,
"currency": "usd",
"eventName": "Purchase",
"invoiceId": "inv_001",
"paymentProcessor": "stripe",
"customerEmail": "alice@example.com",
"customerName": "Alice",
"metadata": {
"plan": "pro"
}
}| Field | Type | Required | Description |
|---|---|---|---|
clickId | string | Yes | The refp_id click ID from the user's cookie |
customerExternalId | string | Yes | Your internal user or customer ID |
amount | number | Yes | Sale amount in the smallest currency unit (e.g. cents for USD) |
currency | string | No | ISO 4217 currency code — defaults to "usd" |
eventName | string | No | Descriptive name for the event — defaults to "Purchase" |
invoiceId | string | No | Your invoice/order ID — used for deduplication |
paymentProcessor | string | No | One of stripe, shopify, polar, paddle, revenuecat, custom |
customerEmail | string | No | Customer's email address |
customerName | string | No | Customer's display name |
customerAvatar | string | No | URL to the customer's avatar |
metadata | object | No | Arbitrary key-value data attached to the event |
Response
200 OK
{
"eventName": "Purchase",
"customer": {
"externalId": "user_001",
"email": "alice@example.com",
"name": "Alice"
},
"sale": {
"id": "sale_xyz",
"amount": 4900,
"currency": "usd",
"commissionAmount": 490,
"status": "pending",
"invoiceId": "inv_001",
"paymentProcessor": "stripe"
}
}commissionAmount is in the same unit as amount (smallest currency unit).
Error responses
| Status | Code | Description |
|---|---|---|
400 | INVALID_CLICK_ID | The clickId does not match any recorded click |
400 | VALIDATION_ERROR | Missing or malformed required field |
401 | UNAUTHORIZED | Invalid or missing API key |
409 | DUPLICATE_INVOICE | A sale with this invoiceId was already recorded |
429 | RATE_LIMIT_EXCEEDED | Too many requests — retry after backing off |
Deduplication
If you pass the same invoiceId twice, the second request returns 409 Duplicate Invoice. This protects against double-counting from webhook retries or accidental duplicate calls.
SDK equivalent
await refport.track.sale({
clickId: 'abc123',
customerExternalId: 'user_001',
amount: 4900,
currency: 'usd',
invoiceId: 'inv_001',
paymentProcessor: 'stripe',
});See the Node.js SDK reference for full parameter details.