Conversions API
Report conversions to Affilync via server-side API calls, JavaScript pixel, postback URLs, or platform integrations. All conversion methods support deduplication via order_id and automatic fraud detection.
Overview
Affilync provides two conversion tracking pipelines:
- Public Pixel/API (
/api/track/*) — Merchant websites, tracking pixels, third-party networks - E-commerce Integrations (
/api/conversions/*) — WooCommerce, Shopify, TikTok Shop (authenticated)
All public endpoints require HMAC-SHA256 signature verification in production.
Server-Side Conversion (Direct Pixel)
The recommended approach for accurate, fraud-resistant attribution.
curl -X POST https://api.affilync.com/api/track/conversion \
-H "Content-Type: application/json" \
-H "X-Affilync-Signature: {signature}" \
-d '{
"click_id": "550e8400-e29b-41d4-a716-446655440000",
"transaction_id": "txn_abc123xyz",
"order_id": "order_456",
"order_value": 99.99,
"currency": "USD",
"conversion_type": "sale",
"customer_email": "[email protected]",
"products": [
{
"sku": "PROD-001",
"name": "Widget",
"quantity": 2,
"price": 49.99
}
]
}'
Signature Computation
HMAC signatures protect against unauthorized conversion reporting. Compute the signature as:
HMAC-SHA256(POSTBACK_SECRET_DIRECT, "{click_id}.{transaction_id}.{order_value}")
Example (Python):
import hashlib
import hmac
canonical = f"{click_id}.{transaction_id}.{order_value}"
signature = hmac.new(
POSTBACK_SECRET_DIRECT.encode(),
canonical.encode(),
hashlib.sha256
).hexdigest()
Response (201):
{
"success": true,
"data": {
"conversion_id": "conv_abc123",
"status": "pending",
"message": "Conversion tracked successfully"
},
"message": "Success"
}
Request Fields
Required:
| Field | Type | Description |
|---|---|---|
click_id | string (UUID) | The Affilync click ID from the redirect |
transaction_id | string | Unique transaction ID (for deduplication) |
order_value | decimal | Total conversion value |
Highly Recommended:
| Field | Type | Description |
|---|---|---|
order_id | string | Merchant order ID (prevents duplicate reporting) |
signature | string | HMAC-SHA256 signature (required in production) |
Optional:
| Field | Type | Description |
|---|---|---|
currency | string | ISO 4217 code (default: USD) |
conversion_type | string | sale, lead, signup, download, subscription, custom (default: sale) |
customer_email | string | Hashed for privacy; enables cross-device attribution |
customer_id | string | Customer identifier from merchant |
referer_url | string | Referrer URL |
products | array | Product details (see below) |
metadata | object | Custom key-value pairs |
conversion_timestamp | datetime | When conversion occurred (ISO 8601) |
Product Object (in products array):
{
"sku": "PROD-001",
"name": "Product Name",
"quantity": 1,
"price": 49.99,
"category": "Electronics"
}
| Field | Type | Required | Description |
|---|---|---|---|
sku | string | Yes | Product SKU |
name | string | Yes | Product name |
quantity | integer | Yes | Quantity purchased (≥ 1) |
price | decimal | Yes | Unit price (≥ 0) |
category | string | No | Product category |
Third-Party Network Postbacks
Handle conversion postbacks from affiliate networks (Impact, CJ, ShareASale, Rakuten, Awin).
curl -X POST https://api.affilync.com/api/track/postback/impact \
-H "Content-Type: application/json" \
-d '{
"tracking_code": "aff_abc123",
"order_id": "order_789",
"order_value": 150.00,
"currency": "USD",
"signature": "{hmac_signature}"
}'
Valid Sources: impact, cj, shareasale, rakuten, awin, custom
Signature Computation
HMAC-SHA256(POSTBACK_SECRET_<SOURCE>, "{tracking_code}.{order_id}.{order_value}")
Example for CJ postbacks:
signature = hmac.new(
os.environ["POSTBACK_SECRET_CJ"].encode(),
f"{tracking_code}.{order_id}.{order_value}".encode(),
hashlib.sha256
).hexdigest()
Request Fields
| Field | Type | Description |
|---|---|---|
tracking_code | string | Affiliate tracking code from order cart/metadata |
order_id | string | Merchant order ID (dedup key) |
order_value | decimal | Order/sale amount |
currency | string | ISO 4217 code (default: USD) |
signature | string | HMAC-SHA256 signature (required in production) |
custom_parameters | object | Optional custom parameters from network |
Response (200):
{
"success": true,
"data": {
"status": "recorded",
"conversion_id": "conv_xyz123"
},
"message": "Postback processed"
}
Conversion Adjustments (Refunds/Chargebacks)
Reverse affiliate commission(s) when an attributed order is refunded or charged back.
curl -X POST https://api.affilync.com/api/track/adjustment \
-H "X-Affilync-Signature: {signature}" \
-H "Content-Type: application/json" \
-d '{
"original_order_id": "order_456",
"adjustment_type": "refund",
"adjustment_amount": 50.00,
"refund_id": "ref_123"
}'
Request Fields
| Field | Type | Description |
|---|---|---|
original_order_id | string | Order ID of the original conversion |
adjustment_type | string | refund, chargeback, or partial_refund |
adjustment_amount | decimal | Refunded amount (for partial refunds) |
refund_id | string | Optional refund/chargeback ID |
metadata | object | Optional metadata |
Response:
{
"success": true,
"data": {
"status": "reversed",
"order_id": "order_456",
"reversed_commissions": 1,
"adjusted_commissions": 0
},
"message": "Adjustment processed"
}
For full refunds/chargebacks, all commissions are reversed (including already-paid ones, which are clawed back via ledger). For partial refunds, unpaid commissions are scaled proportionally.
E-commerce Integration (WooCommerce)
For brand-authenticated e-commerce plugins that hold the click_id from their own cookie.
curl -X POST https://api.affilync.com/api/conversions/track \
-H "Authorization: Bearer {BRAND_JWT}" \
-H "Content-Type: application/json" \
-d '{
"click_id": "550e8400-e29b-41d4-a716-446655440000",
"order_reference": "woo_order_12345",
"order_total": 99.99,
"currency": "USD",
"platform": "woocommerce",
"customer_email": "[email protected]"
}'
Request Fields
| Field | Type | Description |
|---|---|---|
click_id | string (UUID) | Click UUID from integration cookie |
order_reference | string | Merchant order ID |
order_total | decimal | Order total amount |
currency | string | ISO 4217 code (default: USD) |
platform | string | Integration platform (e.g., woocommerce) |
customer_email | string | Customer email |
commission_amount | decimal | Optional: pre-calculated commission |
affiliate_id | string (UUID) | Optional: affiliate UUID for fallback |
Response: Same as direct pixel tracking above.
E-commerce platforms (Shopify, TikTok Shop, BigCommerce): conversions are reported automatically by the managed Affilync app for each platform — no manual API calls required. Install the integration from Settings > Integrations and conversions (including refunds, cancellations, and chargebacks) sync on their own. See Integrations.
Affiliate Endpoints
Get Affiliate's Conversions
curl "https://api.affilync.com/api/affiliate/conversions?status=approved&page=1&per_page=50" \
-H "Authorization: Bearer {AFFILIATE_JWT}"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: pending, approved, rejected, reversed |
campaign_id | string (UUID) | Filter by campaign |
date_from | datetime | ISO 8601 start date |
date_to | datetime | ISO 8601 end date |
page | integer | Page number (≥ 1, default: 1) |
per_page | integer | Results per page (1-100, default: 50) |
Response:
{
"success": true,
"data": {
"conversions": [
{
"id": "conv_123",
"order_id": "order_456",
"campaign_id": "camp_789",
"click_id": "clk_abc123",
"order_amount": 99.99,
"commission_amount": 10.00,
"commission_rate": 10.0,
"commission_type": "percentage",
"status": "approved",
"converted_at": "2026-03-20T14:30:00Z",
"created_at": "2026-03-20T14:25:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 50,
"total": 42,
"pages": 1
}
}
}
Get Affiliate's Conversion Analytics
curl "https://api.affilync.com/api/affiliate/conversions/analytics?start_date=2026-03-01&end_date=2026-03-31" \
-H "Authorization: Bearer {AFFILIATE_JWT}"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start_date | datetime | ISO 8601 start date |
end_date | datetime | ISO 8601 end date |
campaign_id | string (UUID) | Filter by campaign |
Response: Analytics summary including conversion rates, revenue, top products, and trends.
Brand Endpoints
Get Brand's Conversions
curl "https://api.affilync.com/api/brand/conversions?status=pending&page=1" \
-H "Authorization: Bearer {BRAND_JWT}"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status |
campaign_id | string (UUID) | Filter by campaign |
affiliate_id | string (UUID) | Filter by affiliate |
date_from | datetime | Start date |
date_to | datetime | End date |
min_value | decimal | Minimum order value |
max_value | decimal | Maximum order value |
conversion_type | string | Filter by type |
requires_review | boolean | Show only flagged conversions |
page | integer | Page number |
per_page | integer | Results per page |
Response:
{
"success": true,
"data": {
"conversions": [
{
"id": "conv_456",
"order_id": "order_789",
"campaign_id": "camp_abc",
"affiliate_id": "usr_xyz",
"click_id": "clk_def456",
"order_amount": 150.00,
"commission_amount": 15.00,
"commission_rate": 10.0,
"status": "pending",
"conversion_type": "sale",
"fraud_score": 0.15,
"requires_review": false,
"converted_at": "2026-03-21T10:15:00Z",
"created_at": "2026-03-21T10:10:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 50,
"total": 127,
"pages": 3
}
}
}
Get Conversions Pending Review
curl "https://api.affilync.com/api/brand/conversions/pending-review?campaign_id=camp_abc" \
-H "Authorization: Bearer {BRAND_JWT}"
Returns conversions flagged for manual review (high fraud score, unusual patterns, or still pending approval).
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
campaign_id | string (UUID) | Optional: filter by campaign |
Response:
{
"success": true,
"data": {
"conversions": [
{
"id": "conv_789",
"order_id": "order_101",
"campaign_id": "camp_def",
"affiliate_id": "usr_abc",
"order_amount": 500.00,
"commission_amount": 50.00,
"status": "pending",
"fraud_score": 0.72,
"requires_review": true,
"converted_at": "2026-03-21T09:00:00Z"
}
],
"total": 5
}
}
Review a Conversion
curl -X PUT https://api.affilync.com/api/brand/conversions/conv_456/review \
-H "Authorization: Bearer {BRAND_JWT}" \
-H "Content-Type: application/json" \
-d '{
"decision": "approved",
"notes": "Verified in customer database"
}'
Request Fields:
| Field | Type | Description |
|---|---|---|
decision | string | approved or rejected |
notes | string | Optional review notes |
Response:
{
"success": true,
"data": {
"id": "conv_456",
"status": "approved",
"commission_created": true
}
}
Bulk Review Conversions
curl -X POST https://api.affilync.com/api/brand/conversions/bulk-review \
-H "Authorization: Bearer {BRAND_JWT}" \
-H "Content-Type: application/json" \
-d '{
"conversion_ids": ["conv_456", "conv_789"],
"decision": "approved",
"notes": "Batch approval"
}'
Request Fields:
| Field | Type | Description |
|---|---|---|
conversion_ids | array | Conversion UUIDs to review |
decision | string | approved or rejected |
notes | string | Optional review notes |
Response:
{
"success": true,
"data": {
"processed": 2,
"failed": 0,
"results": [...],
"errors": []
}
}
Update Attribution Settings
Configure attribution model and lookback windows for a campaign.
curl -X PUT https://api.affilync.com/api/brand/conversions/campaigns/camp_abc/attribution \
-H "Authorization: Bearer {BRAND_JWT}" \
-H "Content-Type: application/json" \
-d '{
"model": "last_click",
"lookback_window_days": 30,
"enable_cross_device": false,
"fingerprinting_enabled": false
}'
Request Fields:
| Field | Type | Description |
|---|---|---|
model | string | Attribution model: last_click, first_click, linear, time_decay, position_based, data_driven |
lookback_window_days | integer | Attribution window in days (1-365, default: 30) |
time_decay_half_life_hours | integer | Half-life for time decay model |
position_based_weights | object | Weights for position-based model (must sum to 100) |
enable_cross_device | boolean | Enable cross-device tracking |
fingerprinting_enabled | boolean | Enable device fingerprinting |
Response:
{
"success": true,
"data": {
"campaign_id": "camp_abc",
"attribution_settings": {
"model": "last_click",
"lookback_window_days": 30,
"enable_cross_device": false,
"fingerprinting_enabled": false
}
}
}
Get Fraud Analysis
curl "https://api.affilync.com/api/brand/conversions/fraud-analysis?start_date=2026-03-01&end_date=2026-03-31" \
-H "Authorization: Bearer {BRAND_JWT}"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start_date | datetime | ISO 8601 start date |
end_date | datetime | ISO 8601 end date |
campaign_id | string (UUID) | Optional: filter by campaign |
Response:
{
"success": true,
"data": {
"average_fraud_score": 22.5,
"high_risk_conversions": 3,
"fraud_patterns": [
{
"pattern": "high_fraud_score",
"count": 3,
"description": "Conversions scored above 0.5 by fraud detection"
},
{
"pattern": "flagged_for_review",
"count": 2,
"description": "Conversions flagged requiring manual review"
}
],
"suspicious_affiliates": [
{
"affiliate_id": "usr_xyz",
"conversions": 5,
"average_fraud_score": 65.0
}
],
"recommendations": [
"Manually review high-fraud-score conversions before approval.",
"Investigate affiliates whose conversions average a high fraud score."
]
}
}
Fraud Detection
All conversions are automatically scored for fraud (0-1 scale, displayed as 0-100%). Factors include:
- Velocity checks — Multiple conversions from same IP/email in short timeframe
- Cross-device attribution — Unusual device fingerprint combinations
- Bot detection — Click patterns and user agent analysis
- Geographic anomalies — Mismatches between click location and conversion location
- Affiliate history — Past conversion approval rates and chargebacks
Conversions scoring above 0.5 (50%) are flagged for manual review (requires_review=true).
Deduplication
Conversions are deduplicated by:
- Order ID — Primary dedup key; resubmitting same
order_idreturns original conversion - Transaction ID — Secondary dedup key for direct pixel tracking
Submitting the same order twice returns the original conversion without creating a duplicate, ensuring idempotent conversion reporting.
Attribution Window
Conversions are attributed to clicks within the campaign's attribution window (default: 30 days). The window is configured per-campaign via the Update Attribution Settings endpoint.
Attribution Priority:
click_id— Direct click attribution (most accurate)tracking_code— Last recent click for affiliate linkaffiliate_id— Fallback to affiliate ID if no click
Conversion Statuses
| Status | Description | Commission Created |
|---|---|---|
pending | Awaiting brand approval | No (held pending) |
approved | Brand approved | Yes (if not already) |
rejected | Brand rejected | No |
reversed | Refund/chargeback processed | No (clawed back if paid) |
Error Handling
Common HTTP Status Codes:
| Code | Reason | Action |
|---|---|---|
| 201 | Conversion created | Success |
| 400 | Invalid request (missing required field, validation error) | Fix payload and retry |
| 401 | Missing or invalid signature | Compute correct HMAC-SHA256 signature |
| 403 | Insufficient permissions | Use correct auth token for your role |
| 404 | Click/conversion not found | Verify click_id exists |
| 409 | Duplicate order_id | Idempotent — previous conversion returned |
| 429 | Rate limited (60 requests per hour per IP) | Retry with backoff |
| 503 | Postback source not configured (production only) | Configure POSTBACK_SECRET env var |
Error Response:
{
"success": false,
"data": {
"error": "Invalid signature"
},
"message": "Failed to track conversion"
}
Best Practices
- Use click_id for accuracy — Always pass the click_id from the pixel's
afk_cidcookie when available - Include order_id — Prevents accidental duplicate submission
- Sign in production — Always include HMAC signature in production; it's required and fails-closed
- Use consistent currency — Report all orders in the same currency as configured in campaigns
- Validate before posting — Check order_value > 0, valid email format
- Retry with exponential backoff — Network errors on 5xx responses (jitter randomness)
- Monitor conversion latency — Aim for < 30 seconds between purchase and conversion tracking
- Test postbacks — Use test mode networks (staging Impact accounts, etc.) before live deployment