Conversion tracking report
The page layout, how conversion totals and rates are defined, each event's measurement rules, the fixed 28-day window and plan limits.
Page layout#
The conversion tracking page is /dashboard/mkit/conversions; the former standalone /dashboard/mkit/forms-aff now redirects there. The page has two halves.
| Area | Data source |
|---|---|
| Top half | GET /api/v1/overview?range=28&compare=0, reusing module.ga4.conversions and totals.sessions |
| Bottom half: Forms & AFF | GET /api/v1/reports/forms-aff, covering forms, outbound clicks, AFF, scroll, downloads and SEO sub-tables |
Note: The page always requests 28 days and has no date picker. GA4 not connected shows ConnectionRequired; GTM not marked deployed shows GtmSetupGate.
Conversion total and rate#
The top half has only two KPI cards.
| Card | Definition |
|---|---|
| Conversion total | The sum of all event counts in module.ga4.conversions |
| Conversion rate | Conversion total / module.ga4.totals.sessions × 100 |
Note: Important limit: the conversion total and rate cover only the Top 5 key events marked in GA4. The backend sorts by keyEvents descending, drops zeros and takes the first 5; a page comment says top 6, but the implementation is top 5. Behaviour not marked as a key event never enters these two numbers.
Tip: If the main table is empty, the GA4 property usually has no Key Events marked; mark them in Settings → Goals (/dashboard/settings/goals). Even with more events marked, the current implementation still takes only the top 5 by count.
Event definitions#
The Forms & AFF half reads GA4 events and custom dimensions, aggregating by event type.
| Event / area | Definition |
|---|---|
| form_submit | GA4 form_submit × customEvent:form_id / pagePath / customEvent:form_text |
| click (outbound) | GA4 click where outbound=true × linkDomain / linkUrl / linkText |
| AFF | customEvent:affiliate_program / affiliate_id / affiliate_type; when dimensions are not registered, matchAffiliate() falls back to linkUrl rules |
| scroll | GA4 scroll × customEvent:percent_scrolled, in four tiers: 25 / 50 / 75 / 100 |
| file_download | GA4 file_download × fileName / fileExtension / pagePath |
| Form conversion rate | submits / users (same form + page); the average rate is submitsTotal / siteSessions |
| Outbound and AFF rates | Outbound clicks / sessions; AFF program conv_rate = clicks / sessions |
Note: Forms listed in form_exclusions are filtered from all form stats, while raw GA4 data is retained. outbound.delta_pct is always null in the backend, so the outbound section has no real period-over-period change.
Window, cache and plans#
| Item | Rule |
|---|---|
| Time window | The page is fixed at 28 days; the backend allows Pro 28 days, Business 90 days |
| Cache | 30 minutes |
| Free | locked: the Forms & AFF half returns { locked: true } |
| Business only | SEO → AFF sub-table (seo_aff) |
| SEO sub-tables | GSC query × page clicks joined with GA4 events by pagePath; the page labels this as an estimate of roughly 70-80% accuracy |
Note: AFF pattern GET (list) and POST (create) check the plan (Free is locked/rejected), but PATCH, DELETE and POST test have no explicit plan check; with a pattern id, a Free user could theoretically still call those three endpoints.
Related docs#
- Affiliate tracking: /aff
- Ecommerce attribution report: /ecommerce-report
- Data latency & metric definitions: /data-latency
- Realtime monitoring: /live