t1k:marketing:monetization:mintegral-regional-report
| Field | Value |
|---|---|
| Module | monetization |
| Version | 1.16.9 |
| Effort | medium |
| Tools | — |
How to invoke
Section titled “How to invoke”/t1k:marketing:monetization:mintegral-regional-reportMintegral Regional Report (HTML)
Section titled “Mintegral Regional Report (HTML)”Produces a finished, archived regional report that breaks Mintegral monetization down by macro-region and renders it as a self-contained HTML dashboard (gradient header + KPI strip, color-coded regional rollup with revenue-share bars, per-region cards with top countries, and a channel-level UA section). Markdown and JSON are optional secondary outputs.
Sibling to t1k:marketing:monetization:mintegral-report (the day-over-day daily report) and t1k:marketing:monetization:mintegral (the API/MCP integration reference). THIS skill is the geo / regional deliverable and the default for “give me an HTML report”.
When to use
Section titled “When to use”Activate on: “regional report”, “report by region”, “report for each region”, “mintegral region/geo breakdown”, “html report”, “mintegral report as html”, “regional revenue/eCPM”.
- Default window = last 7 complete UTC+8 days. A 7-day window is the right default for regional cuts — small countries have tiny daily samples, so a single day is noisy. Override with an explicit date range when asked.
- For a single-day day-over-day report (headline + trend + top apps + campaigns), use the daily report skill instead.
Prerequisite — credentials
Section titled “Prerequisite — credentials”Needs the Publisher + Advertiser credential families in ~/.claude.json (local scope) — same setup as the daily report. The generator reads them automatically (never hardcoded, never from the repo):
| Family | Env vars | Powers |
|---|---|---|
| Publisher | MINTEGRAL_PUB_SKEY / MINTEGRAL_PUB_SECRET | regional revenue, eCPM, fill, per-country |
| Advertiser | MINTEGRAL_ADV_USERNAME (Access Key) / MINTEGRAL_ADV_API_KEY | UA channel total (spend / installs / CPI) |
Missing a family → the generator prints WARNING: missing credential … to stderr and that part comes back empty. Surface that rather than reporting zeroes as real.
Executed by
Section titled “Executed by”Steps 1–2 (resolve the window, run the generator) and step 3 (open the HTML)
are mechanical; step 4, the analyst notes on the markdown variant, is the
judgment part and stays on a reasoning tier (routing SSOT:
rules/orchestration-rules.md § “Task-Type → Agent Routing”):
| Step | Agent |
|---|---|
Run fetch-mintegral-regional-report.cjs for the resolved window and report the emitted tables | t1k-fact-fetcher |
Step 4 — write the 4–6 evidence-based analyst takeaways (--md variant) | stays on a reasoning tier, not delegated |
| Commit + push the archived report | t1k-git-manager (via /t1k:git) |
The generator already computes the regional rollup, per-format eCPM, and the
bid-floor matrix — a cheap agent’s job is to run it and surface the rendered
output (including any WARNING: missing credential line) verbatim, not to
recompute per-region ratios by hand.
Workflow
Section titled “Workflow”-
Resolve the window. Default = last 7 complete days (UTC+8). Accept an explicit
start end(YYYY-MM-DD or YYYYMMDD) or--days=N. -
Run the generator (deterministic — fetches, aggregates by region, recomputes ratios, renders, archives):
Terminal window # default last-7-days HTML, archived to data/mintegral/reports/regional-<start>_<end>.htmlnode .claude/skills/t1k-marketing-monetization-mintegral-regional-report/scripts/fetch-mintegral-regional-report.cjs# explicit range, also emit markdown + json alongside the HTMLnode .claude/skills/.../scripts/fetch-mintegral-regional-report.cjs 2026-06-04 2026-06-10 --html --md --json# print to stdout without archiving (preview)node .claude/skills/.../scripts/fetch-mintegral-regional-report.cjs --no-writeFlags:
--html(default),--md,--json,--days=N,--no-write. HTML is written when no format flag is given. -
Open it for the user.
open data/mintegral/reports/regional-<start>_<end>.html(macOS) so they see the dashboard immediately. -
(If
--md) write analyst notes. The markdown variant has an## Analyst notesplaceholder — replace it with 4–6 evidence-based takeaways: ad-format eCPM spread + per-format/per-geo floor recommendations (from the bid-floor matrix), the Banner-drags-the-blend caveat, value-vs-volume split, the Top-5% premium tail, and the UA data gap. The HTML’s strategic-takeaways section is auto-generated bycomputeInsights()(includes a per-format floor takeaway). Tie each note to a number in the report. -
Commit + push so the report history accrues (per
CLAUDE.mddata policy):/t1k:git cp → docs(mintegral): regional report <start>..<end>
What the generator emits
Section titled “What the generator emits”- KPI strip — total ad revenue, blended eCPM, fill, impressions, UA spend, UA installs.
- Regional rollup — 8–9 macro-regions ranked by revenue, with share bars, eCPM, Top-5% eCPM (premium-inventory ceiling), fill, impressions, country count, and a TOTAL row.
- Per-region cards — each region’s revenue/eCPM/fill/impressions, a Top-5%-inventory eCPM line, and top-6 countries (with flag emoji).
- eCPM by ad type — Rewarded Video / Interstitial / Banner (+ “Other” remainder): revenue, share, eCPM, fill, impressions. The blended eCPM is a near-useless average across formats — this table is the real read.
- eCPM by ad type × region — bid-floor matrix — per-format eCPM within each region, the cut used to set per-format/per-geo
target_ecpm/ecpm_floor. - UA channel total — spend / installs / CPI / clicks / impressions / active offers, with the hard NOT-a-regional-split caveat.
Advertiser UA pull — chunk to ≤7-day windows + zero-result guard
Section titled “Advertiser UA pull — chunk to ≤7-day windows + zero-result guard”The advertiser (UA) report enforces an undeclared date-range cap: a single request spanning more than ~7 days returns an empty / $0 payload with no error (HTTP looks fine). The default 7-day window is safe, but any wider window (--days=30, an explicit multi-week range) silently truncates to $0. Treat the cap as a hard procedure, not a footnote:
- Auto-chunk the advertiser pull into ≤7-day segments spanning the full requested window. Walk the window in contiguous ≤7-day slices, issue one advertiser request per slice, and SUM spend / installs / clicks / impressions across all slices (recompute CPI = total spend ÷ total installs at the end — never average per-slice CPIs). A 7-day-or-shorter window is one slice; do not chunk needlessly.
- Zero-result guard (errors over silent fallbacks). If the requested window spans >1 day and the advertiser pull comes back empty / $0 across the whole window, do NOT render
$0as truth. Treat it as suspect and surface a warning in the report and to the user — e.g.WARNING: advertiser UA returned $0 over an N-day window — likely a date-range-cap truncation or auth issue, not real zero spend. Re-pull in ≤7-day chunks before trusting this.A genuine $0 over a multi-day live channel is implausible; a capped/empty pull looks identical, so flag rather than report. - Per-slice empties are still suspect. If any individual ≤7-day slice returns $0 while sibling slices return spend, flag that slice rather than silently summing a zero into the total.
This is the same est_revenue is estimated / errors-over-silent-fallbacks discipline applied to the advertiser side: a quiet empty payload must never be presented as a real number. The chunking also matches the publisher surface, which already caps at 7 days per request.
Gotchas
Section titled “Gotchas”- Advertiser date-range cap → $0 over long windows. See “Advertiser UA pull” above. A multi-day advertiser window beyond ~7 days returns empty/$0 silently — always chunk to ≤7-day slices and SUM, and zero-guard any empty multi-day result. (Was: the generator pulled the whole window in one advertiser call, so a 30-day window returned $0 while a 7-day subset returned real spend — issue #20.)
- UA is channel-level ONLY — never split UA by region. The advertiser API returns spend grouped by offer, and each offer’s
geofield is its targeting allow-list (a ~200-country “WW” string), NOT the delivery geo. Allocating UA spend to regions is fabrication. A true regional UA cut needs MMP (AppsFlyer/Adjust) install-by-country data. The generator hard-codes this caveat into the report — keep it. - Never average ratios. eCPM and fill are recomputed per region (and per ad type) from summed raw
est_revenue/impression/filled/request. Averaging the per-country eCPM/fill columns would be wrong (it ignores volume weighting). - Ad type is a FILTER, not a
group_bydimension. The publisher API’sgroup_byonly acceptsdate,country,app_id,platform,placement_id,unit_id,bidding_type,timestamp—group_by=ad_type/ad_formatsilently falls back to grouping by date (a classic silent-wrong-result trap). Ad-type eCPM is obtained by running one filtered country pull perad_formatand aggregating. The verified live tokens (2026-06) are exactly three:rewarded_video,new_interstitial(interstitial video),sdk_banner. Other guesses (interstitial,reward_video,banner,native,splash) return zero rows. They reconcile to ~100% of the unfiltered total; the small remainder is shown as “Other”. If a new format appears, add its token to theAD_FORMATSarray. - Banner skews the blend. Banner (
sdk_banner) is typically ~30% of impressions but ~1% of revenue at a ~$0.30 eCPM and ~35% fill — it single-handedly drags both the blended eCPM and the blended fill down. Rewarded Video and Interstitial fill at ~98%. Read eCPM/fill per ad type, not blended, especially before concluding there’s “fill headroom”. - Top-5% eCPM = volume-weighted eCPM of the highest-eCPM countries making up the top 5% of a region’s impressions (premium-inventory ceiling). Volume-weighting keeps micro-sample geos from skewing it; the displayed country list may include tiny high-eCPM geos that contribute ~0 weight to the blend.
- Timezone is UTC+8 (Mintegral default) throughout. Publisher uses
YYYYMMDD; Advertiser uses Unix-second integers — the generator handles both. - NOT total revenue / NOT ROAS. Monetization is Mintegral-mediated ad revenue only; the UA total is Mintegral-channel spend only. Same-day/same-window in vs out is not profit.
- The region map is a fixed ISO-2 → macro-region lookup in the script. New/unknown country codes fall into “Other / Unmapped” (filtered from the report when negligible). If a real territory lands there, add it to the
REGIONSmap. - The generator is read-only — never mutates Mintegral, no write guard involved.
Reference
Section titled “Reference”- Data + HTML generator:
scripts/fetch-mintegral-regional-report.cjs(self-contained: fetch → aggregate → render). - Auth model + API params: base skill
t1k:marketing:monetization:mintegral§Authentication. - Archive location:
data/mintegral/reports/regional-<start>_<end>.{html,md,json}.