Skip to content

feat: attribution topic (report, metrics, dimensions, values) - #35

Open
seifer wants to merge 8 commits into
mainfrom
feat/attribution-topic
Open

seifer wants to merge 8 commits into
mainfrom
feat/attribution-topic

Conversation

@seifer

@seifer seifer commented Sep 24, 2026 •

Copy link
Copy Markdown

What

A new adapty attribution topic. It reads Attribution analytics for an app, the same data as the Attribution dashboard, so customers and their agents can query it from the terminal.

Command What it does
attribution metrics Metric catalog (name, unit, family, whether it is spend-based, ratio denominator) plus the request limits
attribution dimensions Dimensions: groupable/filterable, identity, date granularities
attribution values The values a dimension takes for an app over a period, i.e. what --filter can use
attribution report Metrics over a period for one app, grouped by dimensions, with totals

Built on the migrated stack, the same way asa is: src/sdk/attribution → src/cli/base/attribution → src/cli/commands/attribution, with one-line shims in src/commands.

It talks to https://api-ua.adapty.io/api/v1/cli with the existing developer session. ADAPTY_ATTRIBUTION_API_URL overrides the URL.

Contract points agents rely on

  • null means not computable, never zero. The human view prints —. Apple Search Ads has no spend source in Attribution, so its spend-based values are null, as are totals ratios once any row lacks spend.
  • Usage errors exit 2 in both human and --json mode, API errors exit 4, network errors exit 5, auth errors exit 3.
  • A 429 or 503 carries retry_after_seconds in the --json error.
  • report and values are sent once and never retried.
  • Catalog reads retry once. A long server Retry-After surfaces as an error immediately instead of a silent sleep.
  • Agent docs are in docs/agent/attribution.md and the skill references. check-agent-docs now also covers the attribution commands.

Backend

The Attribution backend /api/v1/cli has been in production since 2026-09-24. A follow-up backend MR drops two meta hints (max_valid_day, spend_channels) that this CLI no longer reads, so the order of the two releases doesn't matter.

Verification

  • pnpm install --frozen-lockfile, pnpm build, pnpm check:agent-docs, pnpm test (442 passing, eslint clean) and tsc --noEmit, on the branch rebased onto main.
  • Smoke-tested against production with a real session:
    • metrics, dimensions, values, and report by channel, weekly, with predictions, and with an ASA-only filter;
    • error paths: unknown metric (exit 4), window too wide (exit 4), --group-by date without --granularity (exit 2 before any request), malformed --filter under --json (exit 2), and an app the token cannot read (exit 4, attribution_app_not_found).

Release

package.json is bumped to 0.8.8. Per onPushToMain.yml + onTag.yml, merging creates the v0.8.8 tag and GitHub release, publishes to npm as latest, and dispatches the doc sync to apple-ads-cli. Drop the chore: bump version to 0.8.8 commit to merge without releasing.

🤖 Generated with Claude Code

Timur Nurutdinov and others added 8 commits September 24, 2026 15:09
createAttribution talks to the UA CLI namespace with the shared bearer
token, parses its errors[] envelope, validates report and values input
before the network, and never retries report or values requests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ECY4soDhA4oW8LZYT6MmZ
…alues commands

A new attribution adapter reuses the Adapty session with its own
ADAPTY_ATTRIBUTION_API_URL, and four commands on the migrated stack
expose UA analytics with --json as the contract and null shown as a dash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ECY4soDhA4oW8LZYT6MmZ
…ic names

API errors carrying Retry-After now include retry_after_seconds in the
--json error, and attribution examples use the contract form d7_roas
instead of roas_d7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ECY4soDhA4oW8LZYT6MmZ
docs/agent/attribution.md covers discovery, units, null semantics, caps,
errors, and a crosswalk with asa metrics; the skill reference and trigger
mention the topic; check-agent-docs now enforces attribution commands,
flags, and contract strings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ECY4soDhA4oW8LZYT6MmZ
…hout a UA feed

The backend catalog marks every metric read from the ad-network feed as
spend_based, including impressions and network clicks, so the agent docs
now say those are null on Apple Search Ads rows, not only spend.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ECY4soDhA4oW8LZYT6MmZ
- exit 2 for flag-parser usage errors under --json too, not 1
- catalog reads no longer sleep through a long server Retry-After; the error
  carries retry_after_seconds instead
- a 200 whose body is not the expected envelope fails as malformed_response
- values items may carry a null value or channel; the view prints a dash
- --group-by date without --granularity is refused locally (exit 2)
- metrics shows the report limits, spend_based and the ratio denominator;
  dimensions shows the identity; report and values examples include --json
- the report meta is only the echoed query
- agent docs: the 25-metric cap is a validation error, one --filter per
  dimension, how to learn the app timezone, the limits, the Apple Search Ads
  spend rule, and apps a member may not read answer app_not_found
- tests for the escaped-comma filter, the value render path, network and 404
  exits, and resolveAttributionSession

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seifer seifer changed the title feat: attribution topic for UA analytics (report, metrics, dimensions, values) feat: attribution topic (report, metrics, dimensions, values) Sep 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant