fix(amplitude): correct wire formats and add funnels/retention analytics#5355
fix(amplitude): correct wire formats and add funnels/retention analytics#5355waleedlatif1 wants to merge 5 commits into
Conversation
- Fix Identify/Group Identify APIs sending JSON instead of required form-urlencoded bodies - Fix Send Event using snake_case productId/revenueType instead of Amplitude's camelCase fields - Fix Get Revenue parsing a response shape that doesn't match the real Revenue LTV API - Add EU data residency support across all tools (Amplitude rejects EU projects on the US host) - Add missing filters/formula/segment params to Event Segmentation, group-by/segment to Active Users and Revenue - Add first_used/last_used to User Activity and non_active/flow_hidden to List Events - Add real-time/hourly interval options to Event Segmentation - Add Funnels and Retention tools for conversion and retention analysis
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview API correctness: Identify and Group Identify now POST EU data residency: New New & extended analytics: Funnels and Retention operations, tools, registry entries, block UI, outputs ( Other: Block brand colors updated; User Profile description notes EU unavailability. Reviewed by Cursor Bugbot for commit f60b057. Configure here. |
Greptile SummaryThis PR fixes four wire-format bugs in the existing Amplitude tools (form-urlencoded body for Identify/Group Identify, camelCase
Confidence Score: 5/5Safe to merge — all changed code paths have been verified against Amplitude's API contracts and the framework's request-body handling. The wire-format fixes (form-urlencoded bodies, camelCase revenue fields, corrected Revenue LTV response shape) are straightforward and align with Amplitude's documented API. The EU residency routing is handled by a clean utility function used consistently across every affected tool. The two new tools (funnels, retention) both validate required JSON params with descriptive errors before building the URL, matching the pattern established for filters in event_segmentation. The block config correctly forwards dataResidency through the executor's spread merge, and the config.params mappings for the new operations are complete. No silent-failure paths were introduced. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Block UI
participant Exec as GenericBlockHandler
participant Tool as Tool
participant US as api2.amplitude.com
participant EU as api.eu.amplitude.com
UI->>Exec: block.config.params (all UI values incl. dataResidency)
Exec->>Exec: config.params(inputs) → transformedParams
Exec->>Exec: "finalInputs = {...inputs, ...transformedParams}"
Exec->>Tool: executeTool(finalInputs)
alt identify_user / group_identify
Tool->>Tool: URLSearchParams body (form-urlencoded)
else send_event
Tool->>Tool: JSON body (productId, revenueType)
else funnels
Tool->>Tool: "Validate events array, append ?e= per step"
else retention
Tool->>Tool: Validate startEvent/returnEvent as JSON objects
end
alt "dataResidency == eu"
Tool->>EU: GET/POST request
EU-->>Tool: Response
else "dataResidency == us (default)"
Tool->>US: GET/POST request
US-->>Tool: Response
end
Tool-->>Exec: ToolResponse
Exec-->>UI: block output
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Block UI
participant Exec as GenericBlockHandler
participant Tool as Tool
participant US as api2.amplitude.com
participant EU as api.eu.amplitude.com
UI->>Exec: block.config.params (all UI values incl. dataResidency)
Exec->>Exec: config.params(inputs) → transformedParams
Exec->>Exec: "finalInputs = {...inputs, ...transformedParams}"
Exec->>Tool: executeTool(finalInputs)
alt identify_user / group_identify
Tool->>Tool: URLSearchParams body (form-urlencoded)
else send_event
Tool->>Tool: JSON body (productId, revenueType)
else funnels
Tool->>Tool: "Validate events array, append ?e= per step"
else retention
Tool->>Tool: Validate startEvent/returnEvent as JSON objects
end
alt "dataResidency == eu"
Tool->>EU: GET/POST request
EU-->>Tool: Response
else "dataResidency == us (default)"
Tool->>US: GET/POST request
US-->>Tool: Response
end
Tool-->>Exec: ToolResponse
Exec-->>UI: block output
Reviews (5): Last reviewed commit: "fix(amplitude): tighten JSON shape valid..." | Re-trigger Greptile |
- Guard against non-array/non-object JSON in the funnel steps param instead of crashing on for...of - Throw a descriptive error instead of silently sending an empty funnel when the JSON is unparseable
|
@cursor review |
Throw a descriptive error when the parsed events JSON yields zero valid step objects instead of silently sending a funnel request with no steps.
|
@cursor review |
…tial funnel steps - Event Segmentation now throws on invalid filters JSON instead of silently running unfiltered - Funnels now rejects the request when any parsed step isn't a valid object instead of silently dropping it and sending a shorter funnel
|
@cursor review |
…n/retention - Funnels: require a strict JSON array of plain objects (reject nested arrays as steps, reject single-object leniency), and guard transformResponse against a non-array data.data - Event Segmentation: require filters to parse to an array, not just any JSON value - Retention: validate startEvent/returnEvent parse to plain JSON objects before sending, matching the funnels/segmentation precedent
|
@cursor review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f60b057. Configure here.

Summary
product_id/revenue_typeinstead of Amplitude's camelCaseproductId/revenueTypefilters/formula/segmentparams to Event Segmentation,groupBy/segmentto Active Users and Revenuefirst_used/last_usedto User Activity output,non_active/flow_hiddento List Events outputType of Change
Testing
Verified every fix against Amplitude's live API docs with 3 independent verification passes (wire format, response shape, block/tool alignment, backwards compatibility).
bun run lintandtsc --noEmitboth clean.Checklist