Technical Integration

Tracking Built for Performance

Our backend runs on SalesRender CRM with a dedicated proxy layer handling lead normalisation, status mapping, real-time postback forwarding, and full audit logging.

System Architecture

How the Integration Stack Works

A secure proxy sits between you and SalesRender — normalising traffic, hiding API credentials, mapping statuses, and logging every event end-to-end.

End-to-End Data Flow

🖥️
Publisher
Media Buyer LP
PROXY LAYER
api.php
Normalise · Log · Route
🗄️
SalesRender
GraphQL CRM
📦
Advertiser
Postback Receiver
CPA Flow
Publisher → Proxy → SalesRender

Lead submission via campaign alias. Proxy normalises payload, executes GraphQL mutation in SalesRender, returns order ID.

Webhook Flow
SalesRender → Proxy → Advertiser

SalesRender fires webhook on status change. Proxy maps status ID to human label and forwards postback to your tracker URL.

Status Update Flow
Advertiser → Proxy → SalesRender

Advertiser sends human-readable status. Proxy maps it to a SalesRender status ID and updates order via GraphQL mutation.

SalesRender GraphQL API

API Integration

OKNutraLife uses SalesRender's GraphQL-based API for all CRM operations. Two modules are available depending on your role.

CRM Module

CRM API — Direct Integration

Full access to company entities — orders, statuses, products, users. Used by our proxy to create and update orders. Token is created inside the SalesRender company dashboard.

Endpoint
https://de.backend.salesrender.com/companies/{Company_ID}/CRM
Token location: Management → API Tokens
CPA Module

CPA API — Webmaster / Media Buyer

Scoped API for publishers submitting orders to specific offers. No company-level access — only offer submission and lead status queries. Webmaster generates token from their own account.

Endpoint
https://de.backend.salesrender.com/companies/{Company_ID}/CPA
Token location: Webmaster account → My Token
Authentication

Two Auth Methods

SalesRender supports token-based auth via request header or URL parameter. Our proxy always uses the header method to keep tokens out of access logs.

Method 1 — Header (Recommended)
Authorization: your_token_here
Method 2 — URL Parameter
.../CRM?token=your_token_here

⚠️ Required header: Always include Content-Type: application/json on every request or SalesRender will reject the call.

Create Order — CRM API (PHP)
GraphQL Mutation
$curl = curl_init();
curl_setopt_array($curl, [
  CURLOPT_URL => 'https://de.backend.salesrender.com'
              . '/companies/{Company_ID}/CRM',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_POSTFIELDS => json_encode(['query' =>
    'mutation {
      orderMutation {
        addOrder(input: {
          projectId: 1
          statusId: 1
          orderData: {
            humanNameFields: {
              field: "name"
              value: { lastName: "John" }
            }
            phoneFields: {
              field: "phone"
              value: "447123456789"
            }
          }
          cart: {
            items: [{ itemId: 1, variation: 1, quantity: 1 }]
          }
        }) { id }
      }
    }'
  ]),
  CURLOPT_HTTPHEADER => [
    'Authorization: ' . $token,
    'Content-Type: application/json',
  ],
]);
$response = curl_exec($curl);
// {"data":{"orderMutation":{"addOrder":{"id":84921}}}}
CPA Module — For Media Buyers

Submitting Leads via CPA API

Media buyers submit leads either through our proxy endpoint (recommended) or directly via SalesRender's CPA API using their webmaster token.

Recommended Via OKNutraLife Proxy
GET · api.php — Proxy Endpoint
# Submit lead through proxy
GET https://api.oknutralife.com/api.php
  ?action=receive
  &alias=cpa_uk_weight_loss
  &name=John Doe
  &phone=447123456789
  &sub1=adset_29384
  &sub2=creative_118
  &click_id=abc123xyz

// Proxy normalises → GraphQL mutation
// SalesRender API credentials never exposed
// Returns:
{
  "status":  "success",
  "lead_id": 84921
}

Accepts any additional sub-ID parameters, logs the full raw payload, and returns the SalesRender order ID. The campaign alias acts as the contract — it determines which SR project, offer, and token to use.

Direct SalesRender CPA GraphQL (PHP)
POST · SalesRender CPA GraphQL
$curl = curl_init();
curl_setopt_array($curl, [
  CURLOPT_URL => 'https://de.backend.salesrender.com'
              . '/companies/{Company_ID}/CPA',
  CURLOPT_CUSTOMREQUEST  => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POSTFIELDS => json_encode(['query' =>
    'mutation {
      leadMutation {
        addLead(input: {
          offerId: 1
          externalId: "click_abc123"
          externalTag: "fb_uk_wl"
          data: {
            phone_1: "447123456789"
            humanName_1: {
              firstName: "John"
              lastName: "Doe"
            }
          }
          source: { utm_source: "facebook" }
        }) { id }
      }
    }'
  ]),
  CURLOPT_HTTPHEADER => [
    'Authorization: ' . $webmaster_token,
    'Content-Type: application/json',
  ],
]);
$response = curl_exec($curl);
S2S Postback System

Postback Integration

SalesRender fires webhooks on every order status change. Our proxy intercepts them, maps numeric status IDs to human-readable labels, and fires your postback URL in real time.

Webhook → Postback Flow

1
CRM Status Changes

SalesRender call center updates order status — e.g., status_id 3 = accepted by the operator.

2
SalesRender Fires Webhook

POST to proxy webhook endpoint with order ID, status ID, and full order data payload.

3
Proxy Receives & Logs

Full incoming payload is written to the audit log before any further action is taken.

4
Status ID Mapped to Label

Proxy maps status_id: 3 → "accepted" using the campaign's params_json status_map config.

5
Postback Fires to Your Tracker

Proxy sends GET request to your configured postback URL with mapped status, click_id, and payout.

Your Postback URL — submit to your account manager
# Binom / Keitaro / Voluum / RedTrack format
https://yourtracker.com/postback
  ?clickid={click_id}
  &status={status}
  &payout={payout}
  &lead_id={lead_id}

# Available proxy macros
{click_id}   — sub1 passed at lead submission
{lead_id}    — SalesRender order ID
{status}     — accepted | rejected | pending
{payout}     — payout amount in USD
{geo}        — lead country ISO code
{campaign}   — campaign alias
Campaign params_json — Status Mapping Config per campaign
{
  "allowed_statuses": [
    "accepted", "rejected",
    "pending",  "cancelled"
  ],
  "status_map": {
    "pending":   1,
    "cancelled": 2,
    "accepted":  3,
    "rejected":  4
  },
  "postback_url": "https://tracker.com/pb?..."
}
// Mapping runs BEFORE validation.
// Unknown statuses → rejected immediately.
// Legacy numeric input accepted if numeric.
Status: accepted

Fired when the SalesRender call center confirms the order. Fire your conversion postback on this event only.

Status: pending

Fired when lead enters the queue or awaits callback. Valid lead — not yet reached by the call center.

Status: rejected

Fired on rejection. The CRM comment text (reason) is included so you can optimise your traffic source.

Advertiser → SalesRender

Order Status Updates

Advertisers push order status updates back into SalesRender using human-readable labels via the proxy. The proxy maps the label to the correct SalesRender status ID and runs the GraphQL mutation.

GET · api.php?action=order_status
# ✅ Correct — human-readable alias + status
GET https://api.oknutralife.com/api.php
  ?action=order_status
  &alias=status_change_uk
  &lead_id=84921
  &order_status=accepted
  &comment=Client confirmed, shipped today

# ❌ Invalid — numeric IDs rejected by design
GET .../api.php?action=order_status
  &order_id=84921&status_id=3
Status mapping runs before validation — unknown labels are always rejected
Optional &comment= passes a note to the CRM operator on the order record
The alias acts as the contract — it determines which SR token and project to use
⚠️Legacy numeric status inputs are only accepted if the value is purely numeric
CRM Lead Feedback

Real Call Center Comments Returned

Because OKNutraLife controls the SalesRender CRM, we relay the actual call center comment text per lead — not just a numeric code. This is what powers granular traffic optimisation.

accepted

Client confirmed order. Wants standard package. Great quality lead.

rejected

Wrong number — not reachable after 3 attempts across 2 days.

rejected

Already a customer. Duplicate from same IP within 48h.

accepted

Very interested, upgraded to premium bundle. High-intent lead.

pending

Called — voicemail. Scheduled callback for tomorrow morning.

Audit & Transparency

Full Log Visibility

Every request, SalesRender response, and status change is logged end-to-end. Nothing is silently dropped.

Log Status Reference

SUCCESS

Lead accepted and order created successfully in SalesRender CRM.

ERROR

GraphQL schema or validation error returned from SalesRender.

HTTP_FAIL

Network failure or SalesRender API timeout — recorded for retry.

NO_ID

Missing campaign alias or required identifier in the request.

Each log entry stores: raw incoming payload, the normalised GraphQL query sent to SalesRender, the full SalesRender response, and a timestamp. Log exports available for any campaign period on request.

What Gets Logged Per Request

logs table — single entry structure
{
  "incoming_text":
    "alias=cpa_uk_wl&name=John&phone=447...",

  "converted_json": {
    "query": "mutation{orderMutation{addOrder..."
  },

  "salesrender_response": {
    "data": {
      "orderMutation": {
        "addOrder": { "id": 84921 }
      }
    }
  },

  "status": "SUCCESS",
  "created_at": "2025-06-12 14:32:01"
}
Tracker Compatibility

Works with Your Stack

Any tracker that accepts a standard GET-based S2S postback URL is fully compatible. Custom webhook delivery via POST is available on request.

Binom
Keitaro
Voluum
RedTrack
Bemob
Peerclick
Hyros
Custom Tracker

Any tracker accepting https://tracker.com/postback?clickid={click_id}&status={status} format works out of the box with no additional configuration.

Integration Checklist

Getting Set Up

01Apply and get approved as a media buyer or publisher.
02Receive your campaign alias from your account manager.
03Configure sub1 / click_id passthrough in your tracker.
04Submit your postback URL to your manager for campaign config.
05Run a test lead via the proxy endpoint and verify the log entry.
06Confirm postback fires correctly on the test lead status change.
07Go live — every event is logged for full audit visibility.
API Access

Ready to Integrate?

Campaign alias, postback configuration, and SalesRender API access are provided upon partnership approval.