Skip to Content
Developer Docs

The referral dashboard is the fully featured partner view from partners.revroute.ru — link, share buttons, click and conversion stats, commission history, payout balance — rendered inline in your app.

Prerequisites

  • Workspace API key with partners.read permission
  • A program created in your workspace
  • The user has already been enrolled as a partner in that program (manually, via the application form, or by API)
  • @dub/embed-react installed — see Installation

Mint the token

curl -X POST https://api.revroute.ru/tokens/embed/referrals \ -H "Authorization: Bearer $REVROUTE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "partnerId": "pn_5MhYz", "programId": "prog_CYCu7IMAapjkRpTnr8F1azjN" }'
Body fieldRequiredDescription
partnerIdone of these twoRevRoute partner id (pn_...)
tenantIdone of these twoThe partner’s external id in your system, if you mapped one when enrolling
programIdyesWhich program’s dashboard to render

Response:

{ "publicToken": "dub_embed_eyJhbGc...", "expires": "2026-05-15T13:34:56.789Z" }

The token is valid for ~1 hour and is scoped to a single partner. Re-mint it on every page load — never cache across users.

Mount the component

import { DubEmbed } from "@dub/embed-react"; <DubEmbed data="referrals" token={publicToken} style={{ width: "100%", height: "720px", border: 0, borderRadius: 12 }} />
PropTypeRequiredDescription
tokenstringyesThe publicToken from the embed-token endpoint
data"referrals"yesSelects which embed to render
optionsobjectnoTheming and locale, see Theming
styleCSSPropertiesnoInline styles applied to the wrapping <div>
classNamestringnoClass name applied to the wrapping <div>

All other HTML props (id, data-*, aria-*, etc.) are forwarded to the wrapping <div>.

What the partner sees

The component shows tabs for:

  • Overview — referral link, copy / share buttons, click + conversion stats, top countries
  • Earnings — pending and paid commissions, with filters by status and date
  • Payouts — confirmed payouts, current balance, expected next payout
  • Resources — any landing pages or creatives uploaded to the program

Partners can copy their unique link, generate UTM-tagged variants, share via deep links, and view all their conversion history — without leaving your product.

Auto-enrolling new partners

A common pattern is to enroll users into the program lazily — i.e. mint the token on demand and pass a tenantId matching your internal user id; if no partner exists yet, RevRoute creates one and returns the new id.

const res = await fetch("https://api.revroute.ru/tokens/embed/referrals", { method: "POST", headers: { Authorization: `Bearer ${process.env.REVROUTE_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ tenantId: user.id, // your internal id programId: process.env.REVROUTE_PROGRAM_ID, partner: { name: user.name, email: user.email }, // sent on first call }), });

tenantId is unique within a workspace — subsequent calls return the same partner.

Resizing and layout

The embed has an internal scroll if its container is too small. Pick the height that fits your design and let the component scroll inside it. Avoid position: fixed parents — the iframe may misreport its size during reflows.

For responsive layouts, set height: 100% on a flex parent rather than relying on viewport units, which jump on mobile.

Listening to events (advanced)

The embed posts events to the parent window via postMessage. You can listen for them to drive your own analytics:

useEffect(() => { function onMessage(e: MessageEvent) { if (e.origin !== "https://app.revroute.ru") return; if (e.data?.source !== "dub-embed") return; // e.data.event: "link.copied" | "tab.changed" | "share.clicked" ... track("embed_" + e.data.event, e.data.payload); } window.addEventListener("message", onMessage); return () => window.removeEventListener("message", onMessage); }, []);

Only listen for events from https://app.revroute.ru — never trust untrusted origins.

Troubleshooting

SymptomLikely causeFix
Blank iframe, no errorsCSP blocks frame-srcAdd frame-src https://app.revroute.ru to your CSP
401 on token mintWrong / missing API keyCheck Authorization: Bearer ... header
404 partner not foundWrong partnerId / tenantIdVerify the partner exists in this program
Component renders but shows “Session expired”Token expiredRefetch the token, pass the new value to token=
Dark theme not appliedTheme set after first mountPass theme through options before mount; do not toggle CSS variables on the iframe wrapper

See also: Theming and Installation.

Last updated on