aso-weekly-report

Run Bloom's unattended weekly organic ASO report using Appfigures and DataForSEO. Use when the weekly ASO cron fires, or when asked for an ASO performance report, organic app store report, App Store keyword ranking update, keyword gaps report, or weekly app store growth summary. For interactive audits use aso-audit instead.

9 stars

Best use case

aso-weekly-report is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Run Bloom's unattended weekly organic ASO report using Appfigures and DataForSEO. Use when the weekly ASO cron fires, or when asked for an ASO performance report, organic app store report, App Store keyword ranking update, keyword gaps report, or weekly app store growth summary. For interactive audits use aso-audit instead.

Teams using aso-weekly-report should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/aso-weekly-report/SKILL.md --create-dirs "https://raw.githubusercontent.com/exiao/skills/main/app-store/aso/aso-weekly-report/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/aso-weekly-report/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How aso-weekly-report Compares

Feature / Agentaso-weekly-reportStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Run Bloom's unattended weekly organic ASO report using Appfigures and DataForSEO. Use when the weekly ASO cron fires, or when asked for an ASO performance report, organic app store report, App Store keyword ranking update, keyword gaps report, or weekly app store growth summary. For interactive audits use aso-audit instead.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# ASO Weekly Report

Automated weekly report on Bloom's organic App Store performance. Pull organic metrics from Appfigures, keyword rankings from DataForSEO, compare against the prior snapshot, save a new snapshot, then return a concise chat-ready report.

This skill is designed for unattended cron runs. Do the work directly; do not ask follow-up questions unless required credentials or app IDs are missing.

## Required environment

Load credentials from the runtime environment, usually `~/.hermes/.env` in Hermes Agent cron contexts. Do not print credential values.

Required:
- `$APPFIGURES_PAT`
- `$APPFIGURES_BLOOM_IOS_ID`
- `$BLOOM_APP_STORE_ID`
- `$DATAFORSEO_AUTH_BASE64`

Optional:
- `$APPFIGURES_BLOOM_ANDROID_ID`
- `$APPFIGURES_COMPETITOR_APP_IDS`, comma-separated Appfigures product IDs for tracked competitors
- `$ASO_COMPETITOR_APP_STORE_IDS`, comma-separated Apple app IDs for DataForSEO gap checks
- `$ASO_LOCATION_CODE`, DataForSEO location code. Default: `2840` for United States.
- `$ASO_LANGUAGE_CODE`, DataForSEO language code. Default: `en`.
- `$ASO_SNAPSHOT_DIR`, snapshot directory. Default: `$HOME/.hermes/skills/analytics/aso-weekly-report/snapshots/`.

Related skills with endpoint details:
- `appfigures-cli`
- `dataforseo-cli`
- `aso-audit`
- `keyword-research`
- `competitor-analysis`
- `Apple Search Ads` for paid search, not this organic report

## Data windows

Use complete trailing weekly windows:
- This week: last 7 complete days.
- Prior week: the 7 complete days before that.

If the APIs only support relative offsets in the current environment, use Appfigures integer offsets, not `-7d` style strings.

## Workflow

### 1. Appfigures organic metrics

Use the Appfigures API to fetch current and prior-week data for Bloom iOS, plus Android when `$APPFIGURES_BLOOM_ANDROID_ID` is set.

Base setup:
```bash
AUTH="Authorization: Bearer $APPFIGURES_PAT"
BASE="https://api.appfigures.com/v2"
PRODUCTS="$APPFIGURES_BLOOM_IOS_ID"
if [ -n "$APPFIGURES_BLOOM_ANDROID_ID" ]; then PRODUCTS="$PRODUCTS,$APPFIGURES_BLOOM_ANDROID_ID"; fi
```

Fetch:
- Sales/downloads for a complete 14-day window: `GET /reports/sales/?products=$PRODUCTS&group_by=dates&start_date=-14&end_date=-1`, then split locally into this week and prior week.
- Revenue including IAPs for the same complete 14-day window: add `include_inapps=true`.
- Subscriptions if available: `GET /reports/subscriptions`
- Current ratings: `GET /ratings?products=$APPFIGURES_BLOOM_IOS_ID`
- Category ranks for the same complete 14-day window: `GET /ranks/$APPFIGURES_BLOOM_IOS_ID/daily/-14/-1?countries=US`
- Recent 1 to 2 star reviews: `GET /reviews?products=$APPFIGURES_BLOOM_IOS_ID&stars=1,2&count=10&sort=-date`

Compute:
- Downloads, uninstalls, net installs when available.
- Revenue, trials, trial conversions, active subscriptions, churn when available.
- Week-over-week deltas for each metric with prior-week data.
- Current rating and total rating count.
- Category rank best, average, latest, and 7-day change.
- Negative review themes from new 1 to 2 star reviews only.

### 2. DataForSEO keyword rankings

Use DataForSEO Labs Apple endpoints. They are synchronous and cheaper than task endpoints for this report.

```bash
DFS_AUTH="Authorization: Basic $DATAFORSEO_AUTH_BASE64"
DFS_BASE="https://api.dataforseo.com/v3"
ASO_LOCATION_CODE="${ASO_LOCATION_CODE:-2840}"
ASO_LANGUAGE_CODE="${ASO_LANGUAGE_CODE:-en}"
```

Fetch Bloom's top App Store keywords:
```bash
curl -s -X POST "$DFS_BASE/dataforseo_labs/apple/keywords_for_app/live" \
  -H "$DFS_AUTH" -H "Content-Type: application/json" \
  -d '[{"app_id":"'"$BLOOM_APP_STORE_ID"'","location_code":'"$ASO_LOCATION_CODE"',"language_code":"'"$ASO_LANGUAGE_CODE"'","limit":100,"order_by":["ranked_serp_element.serp_item.rank_absolute,asc"]}]'
```

Parse `tasks[0].result[0].items`. For each item, extract:
- `keyword_data.keyword`
- `keyword_data.keyword_info.search_volume`
- `ranked_serp_element.serp_item.rank_absolute`

Track top 50 by rank in the snapshot. In the report, show only the most useful top keywords or movers.

### 3. Competitors and keyword gaps

Prefer `$ASO_COMPETITOR_APP_STORE_IDS` when set. Otherwise use DataForSEO `app_competitors/live` to discover competitors:

```bash
curl -s -X POST "$DFS_BASE/dataforseo_labs/apple/app_competitors/live" \
  -H "$DFS_AUTH" -H "Content-Type: application/json" \
  -d '[{"app_id":"'"$BLOOM_APP_STORE_ID"'","location_code":'"$ASO_LOCATION_CODE"',"language_code":"'"$ASO_LANGUAGE_CODE"'","limit":5}]'
```

For up to 3 competitors, fetch their `keywords_for_app/live` results with limit 50.

Gap rules:
- High priority: competitor ranks top 10, Bloom is absent or worse than 50, and the keyword is relevant to investing, stocks, finance, portfolio tracking, research, or AI investing.
- Medium priority: competitor ranks top 20, Bloom ranks 30 to 100.
- Skip irrelevant keywords, even if volume is high.
- Remember: DataForSEO volume is Google search volume used as a proxy, not exact App Store search demand.

### 4. Snapshot comparison

Snapshot directory:
```bash
SNAPSHOT_DIR="${ASO_SNAPSHOT_DIR:-$HOME/.hermes/skills/analytics/aso-weekly-report/snapshots}"
```

Filename format:
```text
YYYY-MM-DD.json
```

Snapshot structure:
```json
{
  "date": "YYYY-MM-DD",
  "period": {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"},
  "downloads_7d": 0,
  "revenue_7d": 0,
  "rating": 0,
  "ratings_count": 0,
  "category_rank": null,
  "keywords": [
    {"keyword": "ai investing app", "rank": 14, "volume": 68}
  ],
  "competitor_gaps": [
    {"keyword": "stock research", "competitor": "Example", "competitor_rank": 8, "bloom_rank": null, "volume": 54, "priority": "high"}
  ]
}
```

Compare this week to the most recent prior snapshot:
- Existing keyword: compute rank movement. Lower rank number is better.
- New keyword: mark new.
- Keyword missing from this week: mark lost if it was important last week.
- Ratings endpoint is a snapshot, so estimate new ratings by comparing rating count to the prior snapshot.

If no snapshot exists, skip rank movement and establish the baseline.

Save this week's snapshot after comparison. Keep old snapshots; do not remove files during cron runs.

### 5. Recommendations

Generate 2 to 3 specific recommendations. Use these triggers:

| Signal | Recommendation |
|---|---|
| Keyword dropped 5+ positions | Defend that keyword in metadata or supporting copy. |
| High-volume relevant gap | Add or test that keyword in the keyword field, subtitle, description, or paid ASA exploration. |
| Downloads down week-over-week | Check metadata freshness, ranking losses, category movement, and recent review themes. |
| Negative reviews cluster around one issue | Flag the issue for product or paywall/onboarding copy. |
| Keyword enters top 10 | Reinforce the term in screenshots, description, or related content. |
| Trial volume spikes but conversions lag | Watch conversion and churn before assuming quality improved. |

Do not overreact to one weird week. Call out incomplete data, attribution uncertainty, or campaign-driven spikes when the numbers suggest it.

## Output format

Return only the report. Do not call message-sending tools from cron.

Keep it under 50 lines:

```text
📱 ASO Weekly Report: [YYYY-MM-DD] to [YYYY-MM-DD]

Organic performance:
- Downloads: [N] ([delta])
- Revenue: $[N] ([delta])
- Trials/conversions/subs: [only if available]
- Rating: [X.XX]★ from [N] ratings
- Category rank: best #[N], avg #[N]
- Negative reviews: [N or theme]

Keyword rankings:
- [top 5 to 8 useful rankings or movers]

Competitor gaps:
- [keyword]: [competitor] #[rank], Bloom [rank/not top 100], volume [N]

Takeaway:
[One concise interpretation]

Recommendations:
1. [Specific action]
2. [Specific action]
3. [Specific action if warranted]

Snapshot saved: $SNAPSHOT_DIR/[YYYY-MM-DD].json
```

First run ending:
```text
Baseline established. Next week's report will include rank movement.
```

## Common mistakes

- Do not use stale skill names `dataforseo` or `appfigures`; use `dataforseo-cli` and `appfigures-cli`.
- Do not fabricate prior-week movement if the prior snapshot or API comparison is missing.
- Do not treat DataForSEO volume as exact App Store volume.
- Do not dump raw tables. This report goes to chat.
- Do not label spikes as fraud or bots without evidence. State the data and the uncertainty.
- Do not expose tokens, API keys, account IDs, or private app IDs in the report.

## Approximate DataForSEO cost

- Bloom `keywords_for_app/live`: about $0.012.
- `app_competitors/live`: about $0.011.
- Three competitor `keywords_for_app/live` calls: about $0.036.
- Appfigures via PAT: no per-request cost.

Expected weekly cost: about $0.06.

## Skill source

Recreated from prior local cron prompts and run outputs after the original runtime skill was lost during skill repository cleanup. To refresh this skill, compare future cron reports against this runbook, then update endpoint details from the `appfigures-cli` and `dataforseo-cli` skills rather than pasting private operational state into this public repository.

Related Skills

writer

9
from exiao/skills

Write content in Eric's voice — articles, blog posts, tweets, social media posts, marketing copy, newsletter drafts. Loads WRITING-STYLE.md and enforces kill phrases.

positioning-angles

9
from exiao/skills

Use when defining product positioning, choosing strategic angles, crafting value propositions, competitive positioning, product messaging, differentiation strategy, or go-to-market angles. Also use for 'how should I position my app', 'what angle should I use', 'painkiller vs vitamin', or 'market positioning'.

outline-generator

9
from exiao/skills

Use when generating outlines, article structures, content outlines, blog outlines, planning article sections, structuring posts, breaking down topics into sections, or organizing ideas for long-form content. Also use for 'outline this', 'structure this article', or 'plan the sections'.

last30days-open

9
from exiao/skills

Use only when the user explicitly asks for the open variant of last30days, including watchlists, briefings, and history queries. Sources: Reddit, X, YouTube, web.

last30days

9
from exiao/skills

Use when researching what happened in the last 30 days on a topic. Also triggered by 'last30'. Sources: Reddit, X, YouTube, web. Produces expert-level summary with copy-paste-ready prompts.

hooks

9
from exiao/skills

Use when generating hooks, headlines, titles, and scroll-stopping openers for content. Also use when analyzing viral posts, Reels, TikToks, YouTube Shorts, or successful social examples to extract reusable hook patterns and improve hook guidance.

evaluate-content

9
from exiao/skills

Use when judging content quality OR editing/improving existing copy: shareability, readability, voice, cuttability, angle, copy sweeps.

editor-in-chief

9
from exiao/skills

Use when a first draft is complete and all Phase 1 gates are done: topic selected (seo-research), title approved (hooks), outline approved (outline-generator), draft written (writer). Runs autonomous diagnosis-prescribe-rewrite loop before Substack.

copywriting

9
from exiao/skills

Write or improve marketing copy for any surface: pages, ads, app stores, landing pages, TikTok/Meta scripts, push notifications, UGC. Combines page copy frameworks with direct response principles.

content-strategy

9
from exiao/skills

Use when building content strategy: hooks, angles, and ideas from what's trending now. Covers organic and paid creative across TikTok, X, YouTube, Meta, LinkedIn.

content-pipeline

9
from exiao/skills

Orchestrator for the 3-article content pipeline — runs research phase, spawns parallel article sub-agents, creates Typefully drafts. Use when running the full content pipeline (usually via cron at 3am).

yt-dlp

9
from exiao/skills

Download audio/video from YouTube and other sites using yt-dlp. Use when the user asks to download music, songs, albums, podcasts, or video from YouTube or similar platforms. Triggers on 'download song', 'get mp3', 'yt-dlp', 'youtube download', 'rip audio'.