- Embed analytics by rendering provider data in your own components, not an iframe.
- Proxy the API through your backend so the secret key never reaches the browser.
- Cache aggregates for a minute or two; the numbers barely move.
Definitions used in this guide
The share of trial users who become paying subscribers within the measurement window you define.
Revenue tied to customers in billing retry, grace period, failed payment, or similar recovery states.
The practice of connecting behavioural evidence to subscription and payment outcomes so you can explain why money moved.
What should be true before you start?
Before you embed anything, decide where the metrics belong in your product and whether they must match your design. An iframe is fast but unstyleable; a server-proxied API lets you render native components. This is the embed-grade version of the app revenue API, and it pairs well with the dashboard indie developers actually need.
Teams that do this well make the data model boring before they make the UI impressive. They decide what the product trusts, how the customer is identified, and which events prove that a premium flow worked. That upfront discipline prevents pricing changes, support escalations, or platform additions from turning into a rewrite later.
- Pick the surface: a settings page, an admin panel, a customer-facing widget.
- Decide native components vs iframe — native wins on design and trust.
- Keep the secret key server-side; the browser calls your backend only.
How should you implement this step by step?
Add a thin endpoint in your app that calls the provider server-side, caches, and returns just the display values. Your frontend renders those with your own chart library. For a joined, per-customer widget, the same approach calls the cross-match instead of a single-layer endpoint.
Implementation should move from trust to explanation. First make the purchase and access state reliable. Then add the events and context that explain whether the path is working for real customers. That order matters because a beautiful funnel built on unreliable access logic will still mislead the team.
- Add a backend route that calls the provider API with your secret key.
- Cache the response briefly and return only the fields your widget needs.
- Render native components — cards, a sparkline — in your product's style.
- For per-customer widgets, call the cross-match scoped to that customer.
| Concern | Iframe | Server-proxied API |
|---|---|---|
| Styling | Limited | Fully native |
| Key safety | Varies | Key stays on your backend |
| Performance | Extra round trips | Cached on your server |
app.get('/widgets/mrr', async (req, res) => {
const r = await fetch('https://api.cross-deck.com/v1/revenue?days=30', {
headers: { Authorization: 'Bearer ' + process.env.CROSSDECK_SECRET_KEY }
});
const { data } = await r.json();
res.json({ mrr: data.current.mrrCents / 100 }); // your UI renders this
});
Where do teams make mistakes?
Most embed problems come from calling the provider straight from the browser.
Most production problems here are not caused by missing one API call; they are caused by model mistakes. Teams mix catalog structure with access logic, treat frontend success states as final truth, or log events without preserving identity. Those shortcuts often feel fine during integration and expensive during the first real support incident.
- Exposing a secret key in frontend code instead of proxying through your backend.
- Dropping in an iframe you cannot style, then fighting it for a week.
- Skipping the cache and hammering the API on every render.
How does Crossdeck operationalize the workflow?
Crossdeck returns aggregates over a secret-key gate, so an embedded widget is just your backend proxying a cached call. You own the look; the provider owns the pipeline. The same route can serve a single number or a joined per-customer view via the cross-match.
The result is analytics that looks like your product, not a stranger's dashboard wedged into an iframe — and a key that never leaves your server.
The operating win is not just cleaner instrumentation. It is that product, support, and engineering can all look at the same customer and reason from the same truth. That shortens the loop between insight, bug fixing, and revenue recovery.
What should a healthy rollout let your team do?
After rollout, the team should be able to inspect one customer and answer four basic questions quickly: what they bought, what access they should have, what they did before the key moment, and whether an error or product break interrupted the path. If those answers still live in different systems, the rollout is not finished yet.
A healthy setup should also make pricing, platform, and lifecycle changes cheaper. New SKUs, trial structures, payment rails, or premium features should mostly be mapping and instrumentation updates, not excuses to rewrite the access model from scratch.
- Trace one premium journey from paywall view to verified access.
- Confirm support can explain a paid-user issue without engineering stitching exports together.
- Review whether new products can be attached without changing feature checks.
What should you review after launch?
The first review cycle should happen with real production questions, not a checklist alone. Look at a new conversion, a failed payment or retry, a support ticket, and a customer who used a premium feature successfully. If the workflow is sound, those stories should be easy to reconstruct.
From there, keep reviewing the signal as an operating surface. The point is not only to collect data. It is to make the next pricing change, onboarding improvement, or incident response faster because the evidence is already joined.
- Review the earliest events that predict retained value.
- Check the gap between entitlement state and what the UI showed.
- Use the next support conversation as a live test of the model.
How should the whole team use the workflow?
A workflow like this becomes more valuable when it is not trapped inside engineering. Support should be able to confirm access and recent failure context. Product should be able to connect the path to adoption or conversion quality. Engineering should be able to see which state or step broke first.
When those three views line up, the system starts compounding. Each incident teaches the team something about pricing, onboarding, premium UX, or instrumentation instead of dying as a one-off ticket.
- Support: confirm entitlement state and the last premium action quickly.
- Product: review which steps correlate with value or friction.
- Engineering: prioritize breaks by customer and revenue impact.
Frequently asked questions
How do I embed analytics in my app?
Proxy an external analytics API through your backend, cache the response, and render the numbers as native components in your own UI. Avoid calling the provider directly from the browser.
Should I use an iframe or an API to embed analytics?
An API lets you render native, styled components and keeps the key on your server. An iframe is faster to drop in but hard to style and brand. For a product surface, the API path is usually worth it.
How do I embed a per-customer metric?
Call a joined, identity-scoped endpoint like the cross-match for the one customer, server-side, and render the result in your widget.
Does Crossdeck work across iOS, Android, and web?
Yes. Crossdeck is designed around one customer timeline across Apple, Google Play, Stripe, and web or mobile product events, so the same entitlement and revenue model can travel across surfaces.
What should I do after reading this guide?
Use the CTA in this article to start free or go straight into browse the reporting api reference so you can turn the concept into a verified implementation.
Take this into the product
Open the Reporting API reference, proxy an endpoint through your backend, and render a native metric widget.