docs(cli): per-field operator support, page_scope, retired filter params - #129
Conversation
`contains` was documented as social-only. The profiles surface supports it on routable string attributes and, since P-2387, on `labels.value`; `startsWith`/`endsWith` were missing from the operator list entirely. Add the per-field support table the API enforces. Document `page_scope` on the kpis/top_*/revenue_*/volume_by_metric pipes, and record that the retired per-family analytics params are rejected with a 400 rather than silently ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba5a81bf91
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | `revenue_timeseries` | `address` (required) | | ||
| | `revenue_by_metric`, `volume_by_metric`, `top_sources` | `metric_column`, `limit`, `offset` | | ||
| | `top_chains`, `top_events`, `top_locations`, `top_pages`, `top_wallets` | `limit`, `offset` | | ||
| | `kpis`, `top_*`, `revenue_*`, `volume_by_metric` | `page_scope` — `page` (default) or `session` | |
There was a problem hiding this comment.
Exclude revenue_timeseries from the page_scope wildcard
The revenue_* wildcard includes revenue_timeseries, but the authoritative GET /v0/revenue_timeseries definition in api/openapi.json accepts only address, date_from, and date_to; unlike revenue_overview and revenue_by_metric, it accepts neither filters nor page_scope. Users following this table can therefore pass an unsupported parameter that cannot affect this wallet-scoped endpoint. List the two revenue endpoints that actually expose page_scope instead of using the wildcard.
Useful? React with 👍 / 👎.
| | `top_chains`, `top_events`, `top_locations`, `top_pages`, `top_wallets` | `limit`, `offset` | | ||
| | `kpis`, `top_*`, `revenue_*`, `volume_by_metric` | `page_scope` — `page` (default) or `session` | | ||
|
|
||
| `page_scope` only affects requests that carry a `page` filter. The default scopes metrics to activity on that page; `session` restores the legacy behaviour where metrics include all activity in any session that viewed the page. |
There was a problem hiding this comment.
Describe the KPI-specific page scope behavior
For kpis with a page filter, the default does not scope every metric to activity on that page as this sentence claims. The contract documented in api/query/kpis.mdx and AnalyticsPageScope keeps sessions and visitors unchanged, counts only pageviews on the filtered page, and computes bounce rate and duration for sessions that landed there. The generic wording will cause users to misinterpret KPI results, so this section should state that exception or link to the precise KPI behavior.
Useful? React with 👍 / 👎.
|
|
||
| A JSON array of `{ field, op, value }` filters, e.g. `[{"field":"location","op":"eq","value":"US"}]`. For multi-value matching, use `in` / `nin` with an array value (e.g. `["chrome","firefox"]`); pipe-delimited strings remain supported by the analytics query boundary. | ||
|
|
||
| This one array carries every predicate. On the user-aggregate pipes (`lifecycle`, `frequency`) it also takes profile metrics, social identity fields, a lifecycle entry (`{"field":"lifecycle","op":"in","value":["New","Power user"]}`), and resource entries using the stable fields `chains.balance`, `apps.balance`, `tokens.balance` and `labels.value` with named qualifiers (`chain_id`, `app_id`, `token_address`, `scope`, `tag_id`). |
There was a problem hiding this comment.
Preserve the separate user-aggregate filter parameters
On both lifecycle and frequency, the OpenAPI contract still exposes behavior_filters, source_filter, and channel_filter as separate predicates in addition to filters. In particular, behavior filters use an incompatible {event, op, times, ...} shape, while source and channel filters have distinct semantics, so they cannot all be moved into this one array. Saying that --filters carries every predicate leaves CLI users without a documented way to express these supported constraints; limit this claim to the migrated profile-family filters and document the remaining parameters under --params.
Useful? React with 👍 / 👎.
| | `labels.value` | comparison operators plus `contains` (case-insensitive) | | ||
| | Numeric profile metrics (`users.net_worth_usd`, `users.volume`, `users.revenue`, `users.points`) | comparison operators | | ||
| | Routable string attributes (`users.device`, `users.os`, `users.referrer`, `users.utm_*`, `users.click_id`, and the `first_*`/`last_*` attribution variants) | the full vocabulary; `contains`, `startsWith` and `endsWith` match case-sensitively | | ||
| | Social fields (`users.twitter`, `users.email`, `users.farcaster`, …) | `contains` (case-insensitive) and `notEmpty`; `startsWith`, `endsWith` and `isEmpty` are rejected | |
There was a problem hiding this comment.
Reconcile the social-field operator guidance
This exhaustive supported-operator row now conflicts with the published profile API guide in api/profiles/search.mdx, which says social fields support exact eq and neq matching and describes isEmpty as the inverse presence check, including an exact-email example. The new CLI page instead omits eq/neq and explicitly says isEmpty is rejected, leaving users with mutually exclusive instructions for the same endpoint. If this row reflects the current implementation, update the API guide in the same change so the site has one consistent contract.
Useful? React with 👍 / 👎.
Why
Follow-up to #124 and #125, which brought the CLI docs onto the canonical filter envelope. Two gaps remained.
containswas listed alongside the other operators with no per-field guidance, andstartsWith/endsWithwere absent from the list even though the API accepts them. Perpackages/shared/constants/filterCapability.tsinformono, each field class implements a different subset and an unsupported pairing is a400— the docs gave no way to predict that.What changed
cli/profiles.mdx— addstartsWith/endsWithto the operator list, plus the per-field support table:.balancefields: comparison operators only, JSON number valueslabels.value: comparison pluscontains(case-insensitive, new in P-2387)contains+notEmpty;startsWith/endsWith/isEmptyrejectedusers.paid_source: fixed ad-network enumusers.lifecycle:eqandinonlycli/analytics.mdx— documentpage_scope(P-2378, onkpis/top_*/revenue_*/volume_by_metric), spell out that the single--filtersarray now carries profile, social, lifecycle and resource predicates on the user-aggregate pipes, and warn that the retired per-family params are rejected with a400rather than ignored.Pairs with getformo/cli#34.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.