Appearance
EPC Model - Exhaustive Specification
Fyralynx's core intelligence is a deterministic, multi-factor EPC scoring formula that ranks every candidate route for a given click and selects the one most likely to maximise the creator's earnings. This document covers every signal, the complete formula, confidence modelling, and how to interpret a CRC trace.
Design Goals
| Goal | How it's achieved |
|---|---|
| Deterministic | Same inputs always produce the same output. No random seeds, no stochastic elements. |
| Explainable | Every signal and its contribution is stored in the CRC trace and visible in the Creator Routing Console. |
| Region-aware | All EPCs are normalised to USD before ranking. Local currency EPCs are never compared directly. |
| Conservative | Uncertainty is penalised, not optimised around. When data is missing, the signal defaults to zero (no bonus) rather than an estimate. |
| Real-time-safe | Uses only KV reads and in-memory arithmetic. Zero live affiliate network API calls in the routing path. |
| Creator-configurable | Private deal overrides and network preference biases are respected without breaking explainability. |
Supported Merchants & Networks
The EPC model operates across:
- 35 merchants - Amazon (8 regions), Walmart, Best Buy, Target, eBay (5 regions), AliExpress, Newegg, B&H Photo Video, Etsy, Wayfair, Macy's, Nordstrom, Zappos, Home Depot, ASOS, Zalando, Argos, Currys, Otto, Decathlon, Rakuten (JP), Flipkart, Myntra, Nykaa, TataCliq, Croma, Lazada, Shopee, Noon, Namshi, Jumia, Takealot, Mercado Libre, Temu, Shein.
- 7 affiliate networks - CJ, Awin, Impact, Admitad, Cuelinks (India-focused), Rakuten Advertising, Involve Asia (SE Asia).
- 4 direct/in-house programs - Amazon Associates, Flipkart Affiliate (incl. Myntra), Noon Affiliate, Jumia Affiliate. (Takealot Affiliate removed - programme closed, 2026.)
- 25+ countries - Full region intelligence for IN, US, GB, DE, FR, CA, AU, JP, SG, MY, TH, ID, PH, VN, TW, AE, SA, EG, NG, KE, GH, ZA, BR, MX, AR.
The 16 Input Signals
Every routing candidate (a specific merchant + region + network combination) is scored across 16 signals. The table below lists each signal, its code, type, default value, and data source.
| # | Signal | Code | Type | Default | Source |
|---|---|---|---|---|---|
| 1 | Historical Base EPC | epc_base | Required | From merchant profile epcHints | Merchant profile (ops-seeded) |
| 2 | Short-term trend multiplier | trend | Optional | 0.0 | Analytics aggregator worker (7-day EWMA) |
| 3 | FX rate to USD | fx | Required | 1.0 (if USD) | fx_rates KV - refreshed daily |
| 4 | Device Bias Multiplier | device_bias | Required | 0.0 | Merchant profile deviceBiases, device detection |
| 5 | Deep-link Validity Bonus | deeplink_bonus | Conditional | 0.0 | Deep-link validator cache (dl:* KV keys) |
| 6 | Region Match Bonus | region_match | Required | 0.0 | Visitor country vs storefront country |
| 7 | Link Health Penalty | link_health_penalty | Required | 0.0 (no penalty) | Redirect chain + 404 probe results |
| 8 | Historical Refund Rate Penalty | refund_penalty | Required if data present | 0.0 | Merchant profile refundRateEstimate |
| 9 | Offer/Promo Bonus | offer_bonus | Optional | 0.0 | offer_alerts:{merchantId} KV - 12h TTL |
| 10 | Network Trust Adjustment | network_trust | Optional | 0.0 | Static network trust table |
| 11 | Merchant Category Multiplier | category_multiplier | Optional | 1.0 | Auto-detected category × merchant profile categoryMultipliers |
| 12 | COD Factor | cod_factor | Required (IN, NG, BD, PK, PH, VN, ID) | 1.0 | Merchant profile codFactor per region |
| 13 | UA / Referrer Penalty | ua_penalty | Optional | 0.0 | Edge request User-Agent analysis |
| 14 | UTM Preservation Factor | utm_preservation | Optional | 0.0 | Merchant deep-link profile utmPreservation flag |
| 15 | Destination Country Availability Penalty | availability_penalty | Required | 0.0 | shipsToCountries flag in region profile |
| 16 | Creator Private Deal Override | deal_override | Optional | 0.0 | Creator's local profile (encrypted sync optional) |
Signal Deep-Dives
1. Historical Base EPC (epc_base)
The foundation of the model. For every merchant + region + network combination, ops maintains a seeded epcHints value expressed in the merchant's local currency (e.g. 0.061 USD for Amazon US via Impact, 4.20 INR for Flipkart via Cuelinks).
A value of 0.0 means this network is not available for this merchant/region - the candidate is excluded from scoring entirely.
EPC hints are seeded from:
- Published affiliate network EPC reports.
- Affiliate community data (AffiliateFix, STM Forum).
- Creator-reported actual EPCs (opt-in telemetry, anonymised).
They are maintained by ops in packages/merchant-profiles/data/merchants/{merchantId}.json. Every change is versioned and logged in the public CHANGELOG.md.
2. Short-term Trend Multiplier (trend)
An exponential weighted moving average (EWMA) of click-level EPC data, computed hourly by the analytics aggregator worker.
Formula:
EWMA(t) = Σ [ epc_i × exp(-ln(2) × age_hours_i / 6) ] / Σ [ exp(-ln(2) × age_hours_i / 6) ]The 6-hour half-life means an EPC spike from 6 hours ago has half the weight of a spike from right now. This captures short-term effects (flash sales, promotions) without over-indexing them.
trend_r is the fractional difference between the EWMA and the seeded epc_base:
trend_r = (EWMA - epc_base) / epc_baseIf no trend data is available for a given merchant/network (the aggregator has no consented telemetry for that route), trend_r = 0.0. Absence of data never penalises a route.
Cap: [-0.20, +0.30]
3. FX Rate to USD (fx)
All base EPCs are in local merchant currency. Before scoring, they are normalised to USD:
normalized_epc_base_r = epc_base_r (local) × fx_rate(local_currency → USD)FX rates are refreshed daily at 00:05 UTC. If the cached rate is:
- < 12 hours old:
+0.01confidence bonus. - 12-36 hours old: No confidence change.
- > 36 hours old:
−0.02confidence penalty applied to this candidate'sC_r. - > 72 hours old: Warning shown in CRC; rates are considered unreliable.
All 23 supported currencies: USD, GBP, EUR, INR, CAD, AUD, JPY, SGD, MYR, THB, IDR, PHP, AED, SAR, EGP, NGN, ZAR, BRL, MXN, ARS, KRW, TWD, VND.
4. Device Bias Multiplier (device_bias)
Merchants have different conversion rates by device type. For example, in India and SE Asia, mobile (especially Android) converts significantly better than desktop for most categories. In contrast, Wayfair (home furnishings) has a strong desktop bias.
Per-region device biases are stored in the merchant profile as fractional adjustments:
json
"deviceBiases": {
"ios": 0.06,
"android": 0.08,
"desktop": -0.02
}The visitor's device type is detected from the User-Agent header at the edge. The matching bias value becomes device_bias_r.
Cap: [-0.05, +0.10]
5. Deep-link Validity Bonus (deeplink_bonus)
Deep links (app URI scheme links) typically convert 5-12% better than web links when the app is installed. However, deep link patterns can break silently when apps update.
The deep-link validator probes each merchant's deep-link patterns in the background (non-blocking, using waitUntil) and caches results in KV:
| Probe result | KV TTL | Effect on bonus |
|---|---|---|
| Valid (2xx/3xx) | 72 hours | Full deepLinkMultiplier from merchant profile applied |
| Invalid (4xx/5xx) | 24 hours | deeplink_bonus_r = 0.0, web URL used instead |
| Timeout | 1 hour | deeplink_bonus_r = 0.0, treated as unchecked (not penalised) |
| TTL expired | - | deeplink_bonus_r = 0.0 until next probe completes |
The deepLinkMultiplier varies by merchant: values of 0.08-0.12 are typical.
Cap: [0.0, +0.12]
Confidence effect: +0.05 when validated and fresh; −0.05 when TTL expired.
6. Region Match Bonus (region_match)
A visitor from Nigeria shopping on Amazon Nigeria (or being routed to Jumia Nigeria) has a much higher probability of converting than a Nigerian visitor hitting Amazon US (which doesn't ship to Nigeria).
| Scenario | region_match_bonus_r |
|---|---|
| Visitor country matches storefront country exactly | +0.08 |
| Visitor country is in the same continent/zone as storefront | +0.03 |
| Visitor country does not match | 0.0 |
Combined with the availability_penalty signal, this strongly biases routing toward the correct regional storefront for the visitor's country.
Cap: [0.0, +0.08]
7. Link Health Penalty (link_health_penalty)
The redirect-chain tracer measures how deep the redirect stack is for a given route and detects loops and 404 probabilities.
| Condition | link_health_penalty_r |
|---|---|
| Redirect depth 0-1 (direct or single hop) | 0.0 |
| Redirect depth 2-3 | 0.05 |
| Redirect depth 4-5 | 0.15 |
| Redirect loop detected | 0.25 |
| 404 on destination | 0.25 |
A hard redirect-loop detection at link creation prevents the link from being saved (not merely penalised).
Cap: [0.0, 0.25]
Confidence effect: +0.02 for depth 0-1; 0.00 for 2-3; −0.08 for depth > 3 or loop.
8. Historical Refund Rate Penalty (refund_penalty)
High-refund merchants (e.g. AliExpress, Temu) have lower effective EPCs because a significant fraction of commissions are reversed on refund. The refundRateEstimate (0.0-1.0) is stored in the merchant profile and seeded from network reports and affiliate community data.
refund_penalty_r = refundRateEstimate × 0.35This means a 20% refund rate applies a 7% EPC penalty. A 100% refund rate caps at 35%.
Cap: [0.0, 0.35]
9. Offer / Promo Bonus (offer_bonus)
The ops team maintains an offer alerts feed per merchant, refreshed every 12 hours from the offer_alerts:{merchantId} KV key. When a valid promotion is active for the current merchant/network, offer_bonus_r is set to the promotion's declared uplift fraction.
Example: "Amazon US running 10% CJ bonus until 2026-06-30" → offer_bonus_r = 0.10.
Expired offers are treated as 0.0. Offers are visible to the creator in the CRC's Offer Alerts section and the popup banner.
Cap: [0.0, +0.25]
10. Network Trust Adjustment (network_trust)
A static, conservative per-network adjustment reflecting the network's attribution reliability, payout consistency, and tracking quality. Values are seeded by ops and reviewed quarterly.
| Network | network_trust_adjustment_r |
|---|---|
| CJ | +0.02 |
| Awin | +0.03 |
| Impact | +0.03 |
| Admitad | 0.00 |
| Cuelinks | +0.01 |
| Rakuten | +0.02 |
| Involve Asia | 0.00 |
Cap: [-0.05, +0.05]
11. Merchant Category Multiplier (category_multiplier)
Different product categories have different conversion rates within the same merchant. For example, electronics often have lower commissions but higher EPC due to order value; fashion has higher commissions but higher return rates.
The content script auto-detects the product category using 5 DOM-based signals (URL patterns, breadcrumbs, Open Graph tags, Schema.org JSON-LD, page title keywords). If a category is detected, the corresponding multiplier from the merchant profile is applied:
json
"categoryMultipliers": {
"Electronics": 1.05,
"Fashion": 1.12,
"Beauty": 1.08,
"Books": 0.90,
"Home": 1.03
}If no category is detected or the merchant profile has no multiplier for the detected category, category_multiplier_r = 1.0 (neutral).
12. COD Factor (cod_factor)
In markets where cash-on-delivery (COD) is dominant - India, Nigeria, Philippines, Vietnam, Indonesia - a significant fraction of orders are never actually collected. This reduces the effective EPC even when attribution fires. The codFactor (0.0-1.0) is stored per merchant region.
| Market | Typical codFactor |
|---|---|
| India (IN) | 0.85 |
| Nigeria (NG) | 0.75 |
| Philippines (PH) | 0.85 |
| Vietnam (VN) | 0.80 |
| Indonesia (ID) | 0.82 |
| US, UK, DE, AU, JP | 1.0 |
cod_factor_r is applied as a direct multiplier (not a delta), so it can meaningfully scale the EPC base for COD-heavy markets.
13. UA / Referrer Penalty (ua_penalty)
Some environments systematically suppress tracking attribution - in-app browsers (TikTok, Instagram, Twitter/X), certain VPN exits, and known bot user agents. When the User-Agent or referrer signals indicate a high-risk tracking environment, a penalty is applied.
Cap: [0.0, 0.15]
This signal never causes a routing decision to change dramatically - it is a small, conservative adjustment.
14. UTM Preservation Factor (utm_preservation)
For merchants that strip UTM parameters in their deep-link redirect chain (e.g. app URLs that do not forward query strings), applying UTMs adds analytical noise without attribution value. The merchant profile declares utmPreservation: false for these cases.
| Condition | utm_preservation_factor_r |
|---|---|
| UTMs survive redirect chain | +0.05 |
| UTMs known to be stripped | −0.05 |
| Unknown / not checked | 0.0 |
Cap: [-0.05, +0.05]
15. Destination Country Availability Penalty (availability_penalty)
Every merchant region profile declares a shipsToCountries array. If the visitor's country is not in this list, the merchant cannot convert that visitor - routing to it wastes the click.
| Condition | availability_penalty_r |
|---|---|
Visitor country is in shipsToCountries | 0.0 |
Visitor country is NOT in shipsToCountries | 0.20 |
shipsToCountries is null (global availability) | 0.0 |
Cap: [0.0, 0.20]
Confidence effect: −0.03 when penalty is applied.
16. Creator Private Deal Override (deal_override)
When a creator has negotiated a private deal with a network (e.g. +20% commission on Amazon US via CJ), they can declare it in Settings → Private Deal Overrides:
json
{
"networkId": "CJ",
"merchantId": "amazon",
"regionCode": "US",
"epcUpliftFraction": 0.20,
"dealNote": "Private deal with CJ account manager - valid until 2026-12-31",
"validUntil": "2026-12-31"
}The deal_override_r signal adds epcUpliftFraction to the score for that specific route. The override:
- Is stored entirely locally in the extension (never transmitted to Fyralynx servers unless the creator opts in to sync on Publisher tier+).
- Expires on
validUntil- expired overrides are treated as0.0and the creator is shown a renewal notification. - Is explicitly labelled in the CRC trace so the creator can always see when their deal influenced a routing decision.
Cap: [0.0, +0.30] - a 30% ceiling prevents accidental gaming of the model.
Confidence effect: +0.02 (trust signal - the creator has specific knowledge about this route).
EPC Normalisation
Before scoring, every candidate's epc_base is normalised to USD:
normalized_epc_base_r = epc_base_r(local) × fx_rate(local_currency → USD)If FX data is older than 36 hours, a −0.02 confidence penalty is applied to C_r (see below). FX data older than 72 hours triggers a warning in the CRC.
Scoring Formula
Intermediate Score
The 16 signals combine as a chain of multipliers applied to the normalised EPC base:
S_r = normalized_epc_base_r
× (1 + trend_r)
× (1 + device_bias_r)
× (1 + deeplink_bonus_r)
× (1 + region_match_bonus_r)
× (1 − link_health_penalty_r)
× (1 − refund_penalty_r)
× (1 + offer_bonus_r)
× (1 + network_trust_adjustment_r)
× category_multiplier_r
× cod_factor_r
× (1 − ua_penalty_r)
× (1 + utm_preservation_factor_r)
× (1 − availability_penalty_r)
× (1 + deal_override_r)Confidence Factor
C_r is a composite confidence score that modulates how much to trust the intermediate score S_r. It is bounded to [0.65, 1.10] to prevent extreme amplification or suppression of the base EPC.
| Signal condition | Confidence delta |
|---|---|
| Deep-link validated and fresh (< TTL) | +0.05 |
| Deep-link TTL expired | −0.05 |
| Merchant profile completeness ≥ 90% | +0.03 |
| FX data fresh (< 12 hours) | +0.01 |
| FX data stale (> 36 hours) | −0.02 |
| High historical variance on this route | −0.03 |
| Link health perfect (depth ≤ 1) | +0.02 |
| Link health warning (depth 2-3) | 0.00 |
| Link health failure (depth > 3 or loop) | −0.08 |
| Enrichment data available and fresh | +0.04 |
| Creator private deal override applied | +0.02 |
| Availability penalty applied | −0.03 |
Starting value: C_r = 0.80 (neutral baseline). All deltas are additive, then clamped to [0.65, 1.10].
Final Route Score
ROUTE_SCORE_r = S_r × C_rThe candidate with the highest ROUTE_SCORE_r across all eligible candidates is selected as the winner. In a tie (rare), the candidate with higher C_r is preferred as it represents higher confidence in the estimate.
Signal Input Ranges (Caps)
Hard caps are enforced on each signal to prevent any single factor from completely dominating the routing decision.
| Signal | Min | Max |
|---|---|---|
trend_r | −0.20 | +0.30 |
device_bias_r | −0.05 | +0.10 |
deeplink_bonus_r | 0.0 | +0.12 |
region_match_bonus_r | 0.0 | +0.08 |
link_health_penalty_r | 0.0 | 0.25 |
refund_penalty_r | 0.0 | 0.35 |
offer_bonus_r | 0.0 | +0.25 |
network_trust_adjustment_r | −0.05 | +0.05 |
ua_penalty_r | 0.0 | 0.15 |
utm_preservation_factor_r | −0.05 | +0.05 |
availability_penalty_r | 0.0 | 0.20 |
deal_override_r | 0.0 | +0.30 |
Merchant Trust Score
Each merchant carries a trust score (0-100) that acts as a reliability multiplier for the routing decision. The trust score is not a gatekeeping mechanism - a low trust score penalises the route's EPC contribution but never prevents routing entirely unless the score falls below the emergency threshold (< 30), which triggers a hard fallback to the original URL.
Trust score inputs (static, seeded by ops):
- Historical attribution reliability - do sales reliably fire tracking pixels?
- Average payout delay (days from sale to payment).
- Known tracking breakage incidents.
- Refund rate stability.
- Cookie window consistency.
The trust score is displayed in the CRC for transparency. Creators cannot modify it. Ops can apply emergency overrides via the admin panel (effective within 30 seconds via KV update).
Interpreting a CRC Trace
A CRC trace (available in the extension's Creator Routing Console or via GET /links/{id}) contains:
json
{
"winner": { ... },
"alternatives": [ ... ],
"signals": [
{
"code": "deeplink_bonus",
"label": "Deep-link Validity Bonus",
"value": 0.08,
"contribution": 0.0049,
"confidenceDelta": 0.05,
"isEssential": true,
"tooltip": "App link verified for this device type - typically converts 5-12% better than web."
},
...
],
"scoringFormula": {
"intermediateScore": 0.0610,
"confidenceFactor": 0.87,
"finalScore": 0.0531
},
"presetApplied": "auto",
"fxRateUsed": 1.0,
"fxDataAgeHours": 8.3,
"computedAtMs": 34
}Reading the signals list:
value- the signal's value as plugged into the formula.contribution- the approximate dollar-per-click impact of this signal on the normalised EPC (positive = helped, negative = hurt).confidenceDelta- this signal's contribution toC_r.isEssential-truemeans this signal is always available (from static merchant profile data).falsemeans it came from network API enrichment or trend data that may not always be present.
Essential vs Enrichment Mode
Every signal is either Essential or Enrichment:
| Mode | Description | Availability |
|---|---|---|
| Essential | Uses only static merchant profile data and KV reads. No network API calls. | 100% of routing decisions |
| Enrichment | Uses live data from affiliate network APIs (cached in KV, 6h TTL). | When creator has provided API credentials and cache is fresh |
Enrichment data never gates a routing decision. If enrichment data is unavailable or stale, routing falls back to Essential mode silently. The isEssential: false label in the CRC trace means the contribution is best-effort and may not always be present.
Worked Example: Indian Creator, Nigerian Visitor
Input:
- Original URL:
https://www.amazon.com/dp/B0CRMZHDG4 - Visitor country:
NG(Nigeria) - Device:
android - Creator declared networks: CJ, Impact, Cuelinks
Candidate generation:
Amazon US + Impact- epcHint = $0.061Amazon US + CJ- epcHint = $0.052Jumia NG + Jumia Affiliate- epcHint = ₦850 → ~$0.027 (normalised)- Original URL fallback - conservative EPC estimate
Scoring (simplified):
| Signal | Amazon US / Impact | Jumia NG / Jumia Affiliate |
|---|---|---|
epc_base (normalised) | $0.061 | $0.027 |
region_match | 0.0 (US ≠ NG) | +0.08 (NG = NG) |
availability_penalty | −0.20 (Amazon US ↛ NG) | 0.0 |
device_bias (android) | 0.0 | +0.07 |
cod_factor (NG) | 1.0 (not COD market for Amazon) | 0.75 |
network_trust | +0.03 | 0.0 |
Amazon US ROUTE_SCORE: $0.061 × (1+0) × (1+0) × (1−0.20) × (1+0.03) ≈ $0.051 × C_r
Confidence penalty from availability: C_r ≈ 0.72 → ROUTE_SCORE ≈ $0.037
Jumia NG ROUTE_SCORE: $0.027 × (1+0.08) × (1+0.07) × 0.75 ≈ $0.023 × C_r
Confidence from region match: C_r ≈ 0.88 → ROUTE_SCORE ≈ $0.020
Winner: Amazon US via Impact - despite the availability penalty, the raw EPC differential is large enough that it still wins.
CRC explanation shown to creator: "Amazon US via Impact chosen. Warning: Amazon US does not ship to Nigeria - conversion probability is significantly lower. Consider adding Jumia NG to your network accounts for Nigerian audience segments."
This is the kind of transparency that makes Fyralynx's routing auditable and trustworthy.
See Also
- Routing Engine Explained - how candidates are generated and scored
- Choice Pages - presenting multiple merchant options to your audience
- Authentication - API access for Publisher+ tier