p202 report winners

Rows to SCALE: profitable, converting keywords/geos; closers come back as CLOSER

All commands

01Run it

Replace the <placeholders> with your own values, or use the builder below.

p202 report winners

02What you get

Captured from the real binary, run against a demo store with 30 days of traffic. Switch tabs to see the same run as JSON, the shape scripts and agents parse.

p202 report winners --breakdown keyword --period last30
$ p202 report winners --breakdown keyword --period last30
id  name                        Clicks  Conversions  Cost    Profit   Avg CPC  bucket  reason                    assisted_conversions  first_touch_roi
--  --------------------------  ------  -----------  ------  -------  -------  ------  ------------------------  --------------------  ---------------
4   height adjustable desk      64      3            70.40   1690.60  1.10     SCALE   profit +$1690.60, 3 conv  0                     2401.42
7   wrap dress midi             87      7            56.55   1071.45  0.65     SCALE   profit +$1071.45, 7 conv  0                     1894.69
15  linen shirt                 148     7            63.54   918.46   0.4293   SCALE   profit +$918.46, 7 conv   1                     1445.48
20  digital gift card           54      5            25.92   599.08   0.48     SCALE   profit +$599.08, 5 conv   0                     2311.27
14  electric sit stand desk     64      2            70.40   595.60   1.10     SCALE   profit +$595.60, 2 conv   0                     846.02
9   team task tracker           47      2            112.80  583.20   2.40     SCALE   profit +$583.20, 2 conv   0                     517.02
5   last minute gift            52      4            24.96   525.04   0.48     SCALE   profit +$525.04, 4 conv   0                     2103.53
1   standing desk uk            62      1            68.20   508.80   1.10     SCALE   profit +$508.80, 1 conv   0                     746.04
10  wrap dress                  156     2            66.90   271.10   0.4288   SCALE   profit +$271.10, 2 conv   0                     405.23
11  gantt chart tool            49      1            117.60  230.40   2.40     SCALE   profit +$230.40, 1 conv   0                     195.92
12  whole bean coffee delivery  70      6            26.60   191.40   0.38     SCALE   profit +$191.40, 6 conv   0                     719.55
6   spring collection           92      2            59.80   138.20   0.65     SCALE   profit +$138.20, 2 conv   0                     231.10
8   fresh roasted coffee        65      4            24.70   103.30   0.38     SCALE   profit +$103.30, 4 conv   0                     418.22
3   gift cards australia        54      1            25.92   99.08    0.48     SCALE   profit +$99.08, 1 conv    0                     382.25
18  linen shirt men             80      1            52      94       0.65     SCALE   profit +$94.00, 1 conv    0                     180.77
17  project tool free trial     59      6            106.20  67.80    1.80     SCALE   profit +$67.80, 6 conv    0                     63.84
16  coffee subscription         74      2            28.12   61.88    0.38     SCALE   profit +$61.88, 2 conv    0                     220.06
19  free project planner        51      4            91.80   24.20    1.80     SCALE   profit +$24.20, 4 conv    0                     26.36
Real output · p202 1.9.77 · demo dataexit 0

Profit by keyword

  • height adjustable desk$1,690.60
  • wrap dress midi$1,071.45
  • linen shirt$918.46
  • digital gift card$599.08
  • electric sit stand desk$595.60
  • team task tracker$583.20
  • last minute gift$525.04
  • standing desk uk$508.80
  • wrap dress$271.10
  • gantt chart tool$230.40
  • whole bean coffee delivery$191.40
  • spring collection$138.20

Drawn from the JSON output above.

03Build your command

Pick values and the command line writes itself, quoted and ready to paste.

p202 report winners

Set flags below; the command updates as you type.

04Flags

26 flags, plus the global flags every command takes.

FlagWhat it does
--aff-campaign-idstringFilter by INTERNAL campaign id (from campaign list), not the public id in tracking URLs
--aff-network-idstringFilter by affiliate network ID
--breakdown, -bstring · default keywordDimension to triage: campaign, aff_network, ppc_account, ppc_network, landing_page, keyword, country, city, region, browser, platform, device, isp, text_ad, ip, referer, referer_url, device_type, c1, c2, c3, c4, utm_source, utm_medium, utm_campaign, utm_term, utm_content, rotator, rotator_rule (aliases: geo=country, lp=landing_page, network=aff_network, offer=campaign, referrer=referer, referrer_url=referer_url, rule=rotator_rule, source=ppc_account)
campaignaff_networkppc_accountppc_networklanding_pagekeywordcountrycityregionbrowserplatformdeviceisptext_adiprefererreferer_urldevice_typec1c2c3c4utm_sourceutm_mediumutm_campaignutm_termutm_contentrotatorrotator_rulegeo → countrylp → landing_pagenetwork → aff_networkoffer → campaignreferrer → refererreferrer_url → referer_urlrule → rotator_rulesource → ppc_account
--browser-idstringFilter by browser ID (the id of a --breakdown browser row)
--country-idstringFilter by country ID
--device-typestringFilter by device type ID: 1 Desktop, 2 Mobile, 3 Tablet, 4 Bot (the ids of --breakdown device_type rows)
--first-touch-modelstringAttribution model id for the closer check (default: the first active First touch model)
--ipstringOnly clicks from this one IP address, IPv4 or IPv6
--isp-idstringFilter by ISP/carrier ID (the id of a --breakdown isp row)
--keywordstringOnly clicks whose keyword contains this text (case-insensitive)
--landing-page-idstringFilter by landing page ID
--max-cpcfloat64Break-even CPC target (else payout × each row's CVR, from --payout or the campaign)
--method-of-promotionstringOnly direct-link clicks or only landing-page clicks: directlink, landingpage
directlinklandingpage
--min-clicksfloat64 · default 1Ignore rows with fewer than N clicks (significance floor)
--no-attribution-checkboolList classic last-click winners only, without the first-touch closer check
--payoutfloat64Revenue per conversion, e.g. your average order value: each row's break-even CPC is this × its conversion rate, and its profit (total_net) and first-touch ROI value each sale at this. Unlike --aff-campaign-id it doesn't filter the report, so the attribution check still runs
--period, -pstringPeriod: today, yesterday, last7, last14, last30, last90, thismonth, lastmonth, thisyear, lastyear, alltime
todayyesterdaylast7last14last30last90thismonthlastmonththisyearlastyearalltime
--platform-idstringFilter by platform (OS) ID (the id of a --breakdown platform row)
--ppc-account-idstringFilter by PPC account ID
--ppc-network-idstringFilter by PPC network ID, or none for the clicks with no traffic source
--refererstringOnly clicks whose referring URL contains this text (case-insensitive)
--region-idstringFilter by region ID (the id of a --breakdown region row)
--showstringWhich clicks count (default all): all, real, filtered, filtered_bot, leads; real = not filtered, filtered_bot = filtered as bots, leads = converted
allrealfilteredfiltered_botleads
--text-ad-idstringFilter by text ad ID
--time-fromstringStart: unix seconds, a date (2026-10-01, from its first second in the account's timezone) or a time with its offset (2026-10-01T09:30:00Z)
--time-tostringEnd, inclusive: unix seconds, a date (2026-10-01, through its last second in the account's timezone) or a time with its offset

05How it works

Rows to SCALE from the classic (last-click) report: profitable and converting. Profit is the campaign's recorded income less cost, or with --payout (your revenue per conversion) sales × payout less cost, the value the first-touch ROI below then uses too. Sales are counted with the Last touch model where the check can read it (a converted click can have several), so a source profitable only through repeat sales is listed too.

Each SCALE row is then checked against the attribution report under a first-touch model, for the same dimension and range. A row that loses money under first touch comes back as CLOSER, with its first-touch ROI and assists: last-click credits it with sales other rows started (retargeting, brand search and email often look like this), so more budget won't bring more new buyers. Check what feeds it before scaling.

The check runs for campaign, ppc_account (traffic source), landing_page, keyword and country, and needs a First touch model (the first active one, or --first-touch-model) and an attribution:read key. When it can't run, the classic winners are still listed with the reason on stderr. A filter other than the breakdown itself (an entity id, --keyword, --show, ...) turns it off; --no-attribution-check does too.

06For agents

Running this from an agent

  • Read the same facts as JSON: p202 commands report winners --json.
  • With AI_AGENT, CLAUDECODE or another agent variable set, output is compact JSON and errors arrive on stderr as a JSON envelope with a hint.
  • Exit codes: 0 ok, 1 bad input, 2 auth, 3 network, 4 server error, 5 partial failure.
p202 commands report winners --json
{
  "path": "p202 report winners",
  "use": "winners",
  "short": "Rows to SCALE: profitable, converting keywords/geos; closers come back as CLOSER",
  "long": "Rows to SCALE from the classic (last-click) report: profitable and converting. Profit is the campaign's\nrecorded income less cost, or with --payout (your revenue per conversion) sales × payout less cost, the value the\nfirst-touch ROI below then uses too. Sales are counted with the Last touch model where the check can read it\n(a converted click can have several), so a source profitable only through repeat sales is listed too.\n\nEach SCALE row is then checked against the attribution report under a first-touch model, for the same dimension\nand range. A row that loses money under first touch comes back as CLOSER, with its first-touch ROI and assists:\nlast-click credits it with sales other rows started (retargeting, brand search and email often look like this),\nso more budget won't bring more new buyers. Check what feeds it before scaling.\n\nThe check runs for campaign, ppc_account (traffic source), landing_page, keyword and country, and needs a First\ntouch model (the first active one, or --first-touch-model) and an attribution:read key. When it can't run, the\nclassic winners are still listed with the reason on stderr. A filter other than the breakdown itself (an entity\nid, --keyword, --show, ...) turns it off; --no-attribution-check does too.",
  "runnable": true,
  "flags": [
    {
      "name": "aff-campaign-id",
      "type": "string",
      "default": "",
      "usage": "Filter by INTERNAL campaign id (from `campaign list`), not the public id in tracking URLs",
      "required": false
    },
    {
      "name": "aff-network-id",
      "type": "string",
      "default": "",
      "usage": "Filter by affiliate network ID",
      "required": false
    },
    {
      "name": "breakdown",
      "shorthand": "b",
      "type": "string",
      "default": "keyword",
      "usage": "Dimension to triage: campaign, aff_network, ppc_account, ppc_network, landing_page, keyword, country, city, region, browser, platform, device, isp, text_ad, ip, referer, referer_url, device_type, c1, c2, c3, c4, utm_source, utm_medium, utm_campaign, utm_term, utm_content, rotator, rotator_rule (aliases: geo=country, lp=landing_page, network=aff_network, offer=campaign, referrer=referer, referrer_url=referer_url, rule=rotator_rule, source=ppc_account)",
      "allowed_values": [
        "campaign",
        "aff_network",
        "ppc_account",
        "ppc_network",
        "landing_page",
        "keyword",
        "country",
        "city",
        "region",
        "browser",
        "platform",
        "device",
        "isp",
        "text_ad",
        "ip",
        "referer",
        "referer_url",
        "device_type",
        "c1",
        "c2",
        "c3",
        "c4",
        "utm_source",
        "utm_medium",
        "utm_campaign",
        "utm_term",
        "utm_content",
        "rotator",
        "rotator_rule"
      ],
      "value_aliases": {
        "geo": "country",
        "lp": "landing_page",
        "network": "aff_network",
        "offer": "campaign",
        "referrer": "referer",
        "referrer_url": "referer_url",
        "rule": "rotator_rule",
        "source": "ppc_account"
      },
      "required": false
    },
    {
      "name": "browser-id",
      "type": "string",
      "default": "",
      "usage": "Filter by browser ID (the id of a `--breakdown browser` row)",
      "required": false
    },
    {
      "name": "country-id",
      "type": "string",
      "default": "",
      "usage": "Filter by country ID",
      "required": false
    },
    {
      "name": "device-type",
      "type": "string",
      "default": "",
      "usage": "Filter by device type ID: 1 Desktop, 2 Mobile, 3 Tablet, 4 Bot (the ids of `--breakdown device_type` rows)",
      "required": false
    },
    {
      "name": "first-touch-model",
      "type": "string",
      "default": "",
      "usage": "Attribution model id for the closer check (default: the first active First touch model)",
      "required": false
    },
    {
      "name": "ip",
      "type": "string",
      "default": "",
      "usage": "Only clicks from this one IP address, IPv4 or IPv6",
      "required": false
    },
    {
      "name": "isp-id",
      "type": "string",
      "default": "",
      "usage": "Filter by ISP/carrier ID (the id of a `--breakdown isp` row)",
      "required": false
    },
    {
      "name": "keyword",
      "type": "string",
      "default": "",
      "usage": "Only clicks whose keyword contains this text (case-insensitive)",
      "required": false
    },
    {
      "name": "landing-page-id",
      "type": "string",
      "default": "",
      "usage": "Filter by landing page ID",
      "required": false
    },
    {
      "name": "max-cpc",
      "type": "float64",
      "default": "0",
      "usage": "Break-even CPC target (else payout × each row's CVR, from --payout or the campaign)",
      "required": false
    },
    {
      "name": "method-of-promotion",
      "type": "string",
      "default": "",
      "usage": "Only direct-link clicks or only landing-page clicks: directlink, landingpage",
      "allowed_values": [
        "directlink",
        "landingpage"
      ],
      "required": false
    },
    {
      "name": "min-clicks",
      "type": "float64",
      "default": "1",
      "usage": "Ignore rows with fewer than N clicks (significance floor)",
      "required": false
    },
    {
      "name": "no-attribution-check",
      "type": "bool",
      "default": "false",
      "usage": "List classic last-click winners only, without the first-touch closer check",
      "required": false
    },
    {
      "name": "payout",
      "type": "float64",
      "default": "0",
      "usage": "Revenue per conversion, e.g. your average order value: each row's break-even CPC is this × its conversion rate, and its profit (total_net) and first-touch ROI value each sale at this. Unlike --aff-campaign-id it doesn't filter the report, so the attribution check still runs",
      "required": false
    },
    {
      "name": "period",
      "shorthand": "p",
      "type": "string",
      "default": "",
      "usage": "Period: today, yesterday, last7, last14, last30, last90, thismonth, lastmonth, thisyear, lastyear, alltime",
      "allowed_values": [
        "today",
        "yesterday",
        "last7",
        "last14",
        "last30",
        "last90",
        "thismonth",
        "lastmonth",
        "thisyear",
        "lastyear",
        "alltime"
      ],
      "required": false
    },
    {
      "name": "platform-id",
      "type": "string",
      "default": "",
      "usage": "Filter by platform (OS) ID (the id of a `--breakdown platform` row)",
      "required": false
    },
    {
      "name": "ppc-account-id",
      "type": "string",
      "default": "",
      "usage": "Filter by PPC account ID",
      "required": false
    },
    {
      "name": "ppc-network-id",
      "type": "string",
      "default": "",
      "usage": "Filter by PPC network ID, or none for the clicks with no traffic source",
      "required": false
    },
    {
      "name": "referer",
      "type": "string",
      "default": "",
      "usage": "Only clicks whose referring URL contains this text (case-insensitive)",
      "required": false
    },
    {
      "name": "region-id",
      "type": "string",
      "default": "",
      "usage": "Filter by region ID (the id of a `--breakdown region` row)",
      "required": false
    },
    {
      "name": "show",
      "type": "string",
      "default": "",
      "usage": "Which clicks count (default all): all, real, filtered, filtered_bot, leads; real = not filtered, filtered_bot = filtered as bots, leads = converted",
      "allowed_values": [
        "all",
        "real",
        "filtered",
        "filtered_bot",
        "leads"
      ],
      "required": false
    },
    {
      "name": "text-ad-id",
      "type": "string",
      "default": "",
      "usage": "Filter by text ad ID",
      "required": false
    },
    {
      "name": "time-from",
      "type": "string",
      "default": "",
      "usage": "Start: unix seconds, a date (2026-10-01, from its first second in the account's timezone) or a time with its offset (2026-10-01T09:30:00Z)",
      "required": false
    },
    {
      "name": "time-to",
      "type": "string",
      "default": "",
      "usage": "End, inclusive: unix seconds, a date (2026-10-01, through its last second in the account's timezone) or a time with its offset",
      "required": false
    }
  ]
}