The Eastlink API gives enterprise customers programmatic access to campaigns, conversions, affiliates, analytics, and webhooks. Use it to integrate affiliate tracking directly into your existing CRM, e-commerce platform, or booking system.
Every response follows a consistent envelope:
{
"success": true,
"data": { ... },
"meta": {
"timestamp": "2026-04-25T10:30:00.000Z",
"version": "v1",
"total": 150,
"page": 1,
"limit": 20
}
}
Error responses use the same envelope with success: false:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "saleValue is required for sale conversions"
},
"meta": {
"timestamp": "2026-04-25T10:30:00.000Z",
"version": "v1"
}
}
All API requests must include your API key in the X-API-Key request header. Generate and manage your keys on the API Keys page.
curl https://api.eastlink.africa/v1/campaigns \
-H "X-API-Key: elk_live_your_key_here"
const response = await fetch('https://api.eastlink.africa/v1/campaigns', {
headers: { 'X-API-Key': 'elk_live_your_key_here' }
});
const { data } = await response.json();
| Scope | Access |
|---|---|
| campaigns:read | Read campaign data |
| conversions:read | Read conversion records |
| conversions:write | Record new conversions and confirm/reject them |
| affiliates:read | Read affiliate data |
| analytics:read | Access analytics data |
| products:read | Read product catalog |
The API enforces a rate limit of 100 requests per minute per API key. If you exceed this, you will receive a 429 Too Many Requests response.
| HTTP Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Request body is missing required fields or has invalid values |
| 401 | MISSING_API_KEY | X-API-Key header is absent |
| 401 | INVALID_API_KEY | API key is invalid, revoked, or does not exist |
| 403 | FORBIDDEN | Authenticated but not authorized to access this resource |
| 403 | INSUFFICIENT_SCOPE | Key lacks the required scope for this operation |
| 403 | IP_NOT_WHITELISTED | Request IP is not in the key's IP whitelist |
| 404 | NOT_FOUND | Requested resource does not exist |
| 409 | DUPLICATE_ORDER | Conversion with this orderId already exists (deduplication) |
| 422 | VALIDATION_ERROR | Semantically invalid — fields present but fail validation rules |
| 429 | RATE_LIMIT_EXCEEDED | Exceeded 100 requests per minute |
| 500 | INTERNAL_ERROR | Server error — contact support if persistent |
Returns all campaigns belonging to the authenticated merchant, ordered by creation date descending.
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number (default: 1) |
| limit | integer | Results per page, max 100 (default: 20) |
{
"success": true,
"data": {
"campaigns": [
{
"id": "camp_abc123",
"name": "Kenya Hotel Referral Program",
"status": "active",
"type": "open",
"commissionRate": 10,
"commissionType": "percentage",
"cookieDuration": 30,
"productsCount": 3,
"affiliatesCount": 47,
"countries": ["KE", "TZ", "UG"],
"channels": ["social", "blog"],
"createdAt": "2026-01-15T08:30:00.000Z"
}
]
},
"meta": { "total": 5, "page": 1, "limit": 20, "pages": 1 }
}
Returns full details for a single campaign including its products array.
{
"success": true,
"data": {
"id": "camp_abc123",
"name": "Kenya Hotel Referral Program",
"description": "Refer travellers to our Nairobi properties",
"status": "active",
"type": "open",
"commissionStructure": { "type": "percentage", "value": 10 },
"cookieDuration": 30,
"payoutHoldDays": 7,
"countries": ["KE", "TZ"],
"channels": ["social", "email"],
"multiTierEnabled": false,
"products": [
{
"id": "prod_xyz",
"name": "Nairobi Hilton — Standard Room",
"type": "booking",
"price": 150,
"currency": "USD",
"commissionType": "percentage",
"commissionValue": 10,
"status": "active"
}
],
"createdAt": "2026-01-15T08:30:00.000Z",
"updatedAt": "2026-03-01T12:00:00.000Z"
}
}
Conversions represent completed actions — sales, leads, bookings, or applications — referred by an affiliate. Recording conversions via the API is the most important integration for enterprise customers.
Records a conversion. Eastlink validates the affiliate, calculates commission, deducts from merchant wallet, and credits the affiliate balance atomically.
| Field | Type | Required | Description |
|---|---|---|---|
| campaignId | string | required | ID of the campaign |
| affiliateId | string | required | ID of the referring affiliate |
| conversionType | string | required | sale | lead | booking | application |
| saleValue | number | required for sale | Transaction value in the specified currency |
| currency | string | optional | ISO 4217 currency code (default: USD) |
| orderId | string | optional | Your unique order ID — used for deduplication |
| customerEmail | string | optional | Customer email address |
| customerPhone | string | optional | Customer phone number |
| metadata | object | optional | Any additional key-value data you want to attach |
curl -X POST https://api.eastlink.africa/v1/conversions \
-H "X-API-Key: elk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"campaignId": "camp_abc123",
"affiliateId": "aff_xyz789",
"conversionType": "sale",
"saleValue": 250.00,
"currency": "USD",
"orderId": "ORDER-98765",
"customerEmail": "customer@example.com",
"metadata": {
"product": "Safari Package",
"nights": 3
}
}'
{
"success": true,
"data": {
"conversionId": "conv_Kd8Xp2m",
"commissionAmount": 25.00,
"platformFee": 1.50,
"affiliateReceives": 23.50,
"status": "pending"
},
"meta": { "timestamp": "2026-04-25T10:30:00.000Z", "version": "v1" }
}
orderId field enables idempotent deduplication — submitting the same orderId twice returns a 409 DUPLICATE_ORDER error rather than creating a duplicate conversion.Returns a paginated list of conversions for the authenticated merchant.
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by: pending | approved | rejected |
| campaignId | string | Filter to a specific campaign |
| from | string | ISO date string — filter createdAt >= this date |
| to | string | ISO date string — filter createdAt <= this date |
| page | integer | Page number (default: 1) |
| limit | integer | Max 100 results (default: 50) |
Returns full details for a single conversion, including rejection reason and timestamps.
Approve or reject a pending conversion. Approving moves the affiliate's pending balance to available. Rejecting refunds the commission back to the merchant wallet.
| Field | Type | Required | Description |
|---|---|---|---|
| confirmed | boolean | required | true to approve, false to reject |
| reason | string | optional | Rejection reason (only used when confirmed is false) |
curl -X PUT https://api.eastlink.africa/v1/conversions/conv_Kd8Xp2m/confirm \
-H "X-API-Key: elk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "confirmed": false, "reason": "Order was refunded by customer" }'
Returns all affiliates approved for the merchant's campaigns, with per-affiliate performance stats.
| Parameter | Type | Description |
|---|---|---|
| campaignId | string | Filter to affiliates in a specific campaign |
| status | string | approved (default) | pending | rejected |
| page / limit | integer | Pagination |
{
"success": true,
"data": {
"affiliates": [
{
"affiliateId": "aff_xyz789",
"name": "Amina Hassan",
"country": "TZ",
"trustLevel": "premium",
"totalClicks": 1204,
"totalConversions": 87,
"totalEarnings": 1042.50,
"campaignId": "camp_abc123",
"campaignName": "Kenya Hotel Referral Program",
"status": "approved",
"joinedAt": "2026-02-10T09:00:00.000Z"
}
]
},
"meta": { "total": 47, "page": 1, "limit": 50 }
}
Returns aggregated performance metrics for the merchant across a date range. Defaults to the last 30 days.
| Parameter | Type | Description |
|---|---|---|
| from | string | Start date (ISO format, e.g. 2026-01-01) |
| to | string | End date (ISO format) |
{
"success": true,
"data": {
"clicks": 12400,
"conversions": 347,
"conversionRate": 2.80,
"revenue": 87500.00,
"commissionPaid": 8750.00,
"topAffiliates": [
{ "id": "aff_xyz789", "name": "Amina Hassan", "conversions": 87, "earnings": 1042.50 }
],
"topProducts": [
{ "id": "prod_xyz", "name": "Nairobi Hilton", "conversions": 120, "revenue": 18000.00 }
],
"byCountry": [
{ "country": "KE", "clicks": 5200, "conversions": 180 },
{ "country": "TZ", "clicks": 4100, "conversions": 120 }
],
"byDay": [
{ "date": "2026-04-01", "clicks": 420, "conversions": 12 }
]
}
}
Returns all active products in the merchant's catalog. Useful for building affiliate-facing product listings or syncing your catalog.
Webhooks deliver real-time notifications to your server when events occur on the platform. Configure your webhook URL and signing secret on the API Keys page.
| Event | Description |
|---|---|
| conversion.created | A new conversion has been recorded (pending approval) |
| conversion.confirmed | A conversion has been approved and commission released |
| conversion.rejected | A conversion was rejected and commission refunded |
| affiliate.applied | An affiliate has applied to join a campaign |
| affiliate.approved | An affiliate has been approved for a campaign |
| payout.completed | An affiliate payout has been successfully disbursed |
{
"event": "conversion.created",
"timestamp": "2026-04-25T10:30:00.000Z",
"data": {
"conversionId": "conv_Kd8Xp2m",
"campaignId": "camp_abc123",
"affiliateId": "aff_xyz789",
"affiliateName": "Amina Hassan",
"conversionType": "sale",
"saleValue": 250.00,
"currency": "USD",
"commissionAmount": 25.00,
"status": "pending"
}
}
If your endpoint fails (non-2xx response or timeout), Eastlink retries:
failed in webhook logsEvery webhook includes an X-Eastlink-Signature header — an HMAC-SHA256 signature of the raw request body using your webhook secret. Always verify this before processing the payload.
const crypto = require('crypto');
function verifyWebhook(req, webhookSecret) {
const signature = req.headers['x-eastlink-signature'];
const expected = crypto
.createHmac('sha256', webhookSecret)
.update(JSON.stringify(req.body))
.digest('hex');
return signature === expected;
}
app.post('/webhook/eastlink', (req, res) => {
if (!verifyWebhook(req, process.env.EASTLINK_WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
if (event === 'conversion.created') {
// Handle new conversion
console.log('New conversion:', data.conversionId);
}
res.status(200).send('OK');
});
Sends a test payload to a webhook URL. Useful for verifying connectivity before going live.
| Field | Type | Description |
|---|---|---|
| webhookUrl | string | The URL to send the test payload to |
Official SDKs are in development. In the meantime, the REST API works directly with any HTTP client.
| Language | Status |
|---|---|
| JavaScript / Node.js | Coming Soon |
| Python | Coming Soon |
| PHP | Coming Soon |
Initial release of the Eastlink Enterprise API.