Skip to main content
POST
https://api.earnos.com
/
conversion
/
v1
Conversion API
curl --request POST \
  --url https://api.earnos.com/conversion/v1 \
  --header 'Content-Type: application/json' \
  --data '
{
  "click_id": "<string>",
  "event_name": "<string>",
  "event_id": "<string>",
  "payout_amount": "<string>",
  "payout_currency": "<string>",
  "occurred_at": "<string>",
  "status": "<string>",
  "metadata": {}
}
'
{
  "success": true,
  "conversion_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "accepted"
}

How It Works

  1. User clicks an EarnOS tracking link containing a click_id
  2. User completes an action on your platform (install, purchase, etc.)
  3. Your server sends a conversion event to EarnOS with the click_id
  4. EarnOS validates and rewards the user
The click_id is passed to you via the tracking URL parameter configured for your account (commonly subid, click_id, or aff_sub).

Authentication

Contact EarnOS to receive your credentials. We support two authentication methods: Include your API key in the X-Api-Key header:
curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Option B: HMAC Signature (For high-security integrations)

Sign requests using HMAC-SHA256 with your secret key. Headers required:
  • X-Signature: HMAC-SHA256 signature (hex-encoded)
  • X-Timestamp: Unix timestamp (seconds)
Signature computation:
payload = timestamp + "." + request_body
signature = HMAC-SHA256(payload, your_secret_key)
Example (Node.js):
const crypto = require('crypto');

const timestamp = Math.floor(Date.now() / 1000);
const body = JSON.stringify({
  click_id: "550e8400-e29b-41d4-a716-446655440000",
  event_name: "install",
  event_id: "txn_abc123"
});

const payload = `${timestamp}.${body}`;
const signature = crypto
  .createHmac('sha256', 'your_secret_key')
  .update(payload)
  .digest('hex');

// Send request with headers:
// X-Timestamp: {timestamp}
// X-Signature: {signature}
Example (Python):
import hmac
import hashlib
import time
import json

timestamp = str(int(time.time()))
body = json.dumps({
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "install",
    "event_id": "txn_abc123"
})

payload = f"{timestamp}.{body}"
signature = hmac.new(
    b'your_secret_key',
    payload.encode(),
    hashlib.sha256
).hexdigest()

# Send request with headers:
# X-Timestamp: {timestamp}
# X-Signature: {signature}
Note: Timestamps must be within 5 minutes of server time.

Request Body

click_id
string
required
EarnOS click ID from tracking link
event_name
string
required
Event type: install, signup, purchase, level_completed, etc.
event_id
string
required
Your unique transaction/event ID (for deduplication)
payout_amount
string
Payout amount, e.g. "1.50"
payout_currency
string
default:"USD"
Currency code
occurred_at
string
When the event occurred (ISO 8601)
status
string
default:"completed"
"completed" or "reversed"
metadata
object
Additional data for your reference

Response

success
boolean
required
Whether the request was processed successfully
conversion_id
string
required
Unique identifier for the conversion
status
string
required
One of accepted, duplicate, or reversed
message
string
Additional detail (present for duplicates and reversals)
{
  "success": true,
  "conversion_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "accepted"
}

Error Codes

HTTP CodeErrorMeaningAction
400INVALID_CLICK_IDClick ID not foundDo not retry - invalid click
400ATTRIBUTION_WINDOW_CLOSEDClick expired (>7 days old)Do not retry
400EVENT_NOT_ALLOWEDEvent type not configuredContact EarnOS
400CLICK_PARTNER_MISMATCHClick belongs to different partnerCheck click_id source
400REVERSALS_NOT_ALLOWEDReversals not enabledContact EarnOS
401INVALID_SIGNATUREHMAC signature invalidCheck secret key
401TIMESTAMP_EXPIREDTimestamp >5 min oldSync server clock
401MISSING_AUTH_HEADERSNo auth providedAdd API key or signature
503SERVICE_UNAVAILABLETemporary errorRetry with backoff

Retry Logic

  • 200: Success - do not retry
  • 400: Client error - do not retry (fix the request)
  • 401: Auth error - do not retry (fix credentials)
  • 503: Server error - retry with exponential backoff
Recommended retry schedule: 1s, 5s, 30s, 2min, 10min, 1hr (then alert)

GET (Legacy)

For networks that only support GET-style callbacks. Same parameters as query string:
GET https://api.earnos.com/conversion/v1?click_id=xxx&event_name=install&event_id=txn123&payout_amount=1.50

Common Scenarios

Basic Install Event

curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "install",
    "event_id": "install_user_789"
  }'

Purchase with Payout

curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "purchase",
    "event_id": "order_12345",
    "payout_amount": "5.00",
    "payout_currency": "USD"
  }'

Multiple Events (Same Click)

A single click can have multiple events. Each event needs a unique event_id:
# First: install
curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "install",
    "event_id": "install_user_789"
  }'

# Later: signup
curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "signup",
    "event_id": "signup_user_789"
  }'

# Later: purchase
curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_name": "purchase",
    "event_id": "order_12345",
    "payout_amount": "2.50"
  }'

Testing

Test Mode

Contact EarnOS to get test credentials. Test events are processed but don’t trigger real rewards.

Verification Checklist

  1. Verify click_id capture: Ensure you’re extracting the click_id from the correct URL parameter
  2. Send test event: Use a real click_id from a test click
  3. Check response: Confirm you receive "status": "accepted"
  4. Test duplicate handling: Send the same event again, confirm "status": "duplicate"
  5. Test error handling: Send an invalid click_id, confirm you handle 400 gracefully

Test Request

# Replace with a real click_id from a test click
curl -X POST https://api.earnos.com/conversion/v1 \
  -H "X-Api-Key: your_test_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "click_id": "your-test-click-id",
    "event_name": "install",
    "event_id": "test_'$(date +%s)'"
  }'

FAQ

Q: What’s the attribution window? A: 7 days by default. Events for clicks older than 7 days will be rejected. Q: What happens if I send a duplicate? A: You’ll get a 200 response with "status": "duplicate". The original conversion is unchanged. Q: Can I send multiple events for the same click? A: Yes. Each event needs a unique event_id. Common flow: install → signup → purchase. Q: How do I handle reversals/chargebacks? A: Send an event with the same event_id and "status": "reversed". This must be enabled for your account. Q: How quickly are rewards processed? A: Rewards are queued immediately after accepting the event. Actual payout timing depends on reward configuration.

Support

  • Integration issues: Contact your EarnOS partner manager
  • Technical questions: [email protected]