RekomiRekomiBlogPricing
Rekomi Docs
Rekomi Docs
Welcome to Rekomi
Quickstart for brandsPlans and trialsIntegrationsStripe Connect (sales tracking)Organization settingsTeam managementNotifications
Migrations from other platformsMigrating from RewardfulMigrating from TapfiliateMigrating from FirstPromoterMigrating from PartnerStackMigrating from Dub PartnersMigrating from Tolt

Campaigns and commissions

CampaignsCommission modelsPay per click or lead (CPC & CPL)Coupon-code attributionSub-affiliate recruitingTracking and attribution

Affiliates

Recruit affiliatesManage affiliatesAI co-pilotApply to the curated network

Money flow

SalesPayoutsMulti-currencyTax formsReports

Email

Sending domainBroadcasts
For brandsMigrate from another platform
|Brands|

Migrations from other platforms

Move your affiliate roster onto Rekomi from Rewardful, Tapfiliate, FirstPromoter, PartnerStack, Dub Partners, or Tolt. Self-serve CSV importers for all six with slug preservation and optional auto-notify.

If you are switching from another affiliate platform, this page is your jumping-off point. Rekomi ships self-serve CSV importers for six sources - pick the dedicated guide for your platform below. On any other platform, use the Custom / other CSV option in Settings, Import, which lets you map your export's columns to Rekomi fields (email, name, status, referral slug, PayPal) yourself.

Dedicated migration guides

Each guide walks through the export flow, the exact column mapping the importer reads, the status translation, slug preservation behavior, and a step-by-step cutover plan.

Migrating from Rewardful

Direct CSV export. Slugs preserved from the `token` column. `?via=` links keep working.

Migrating from Tapfiliate

Emailed CSV export. Slugs preserved from `referral_code`. `?ref=` links keep working.

Migrating from FirstPromoter

Direct CSV export. Handles v1 + v2 columns. Slugs preserved from `cust_ref` / `ref_id`. `?fpr=` links keep working.

Migrating from PartnerStack

Emailed CSV export. Path-based URLs need reverse-proxy redirects for link continuity. Status reclassified after import.

Migrating from Dub Partners

Kebab-menu CSV export. Slugs extracted from `partner_link`. `?via=` links keep working.

Migrating from Tolt

Partner CSV export. Slugs preserved from `referral_code` / `?aff=` link when present. `?aff=` links keep working.

Shared behavior across all 6 importers

The mechanics below apply to every source-specific guide. Read this once and the per-platform pages focus on what's unique to each.

What gets imported

Every importer brings across the same canonical shape:

  • Email (required, primary dedup key, lowercased + trimmed).
  • Full name (single column or first_name + last_name joined).
  • Status, normalized to Rekomi's 4-state enum: Approved / Pending / Rejected / Banned.
  • PayPal email where the source provides it (Rewardful, FirstPromoter, Tolt).
  • Default tracking link, with the slug preserved from the source platform when possible. Falls back to a fresh 12-character random slug when the source field is missing, malformed, or globally taken.

This is Step 1: your affiliate roster. An optional Step 2 imports their history and earnings (past conversions, commissions, and customer attribution); see Importing history and earnings below.

The roster importer does NOT bring across:

  • Historical clicks: first-party cookie data is not portable across platforms (no affiliate tool migrates raw clicks).
  • Existing tracking links beyond the slug: imported affiliates get a Rekomi-side link, with the slug preserved when feasible (see per-platform guides for the matrix).

For LeadDyno, GrowSurf, Reditus, Impact.com, or in-house systems, use the white-glove migration path: contact us via the in-app messenger and we will scope it. White-glove is included in early-adopter onboarding for every plan.

Importing history and earnings (Step 2)

After your affiliates are in (Step 1), upload your platform's referrals / commissions export (a different file from the affiliate roster) under Settings, Migrate, Step 2. This brings over each affiliate's past performance so their stats are not reset to zero, and it can keep their existing customers paying them.

What the history import does:

  • Records past conversions and commissions, matched to the affiliate by email (or preserved slug) within the target campaign. The commission amount and date are taken from your export verbatim, not recomputed.
  • Honors paid vs unpaid. The import itself only records data; Rekomi never pays anyone automatically. Rows your old platform already paid import as settled history (they show in lifetime totals but are never paid again). Rows that were still owed also import as history, and they only become payable (added to your next payout run, which you start yourself) if you explicitly authorize it on the preview screen; otherwise they are recorded as settled and Rekomi will not pay them.
  • Keeps recurring commissions going. When your export includes a customer's Stripe customer/subscription id, we seed the attribution so the next invoice.paid renewal credits the same affiliate. This needs your Stripe account connected and those ids present in the export.
  • Previews first. Every history import runs a dry-run preview showing how many rows import and exactly how much, if anything, Rekomi would be asked to pay, before you commit. Re-running is safe: duplicates are skipped automatically.

Voided, refunded, fraud, and lead-only rows are skipped. The history import is available on Starter or higher, the same as the roster importer.

Plan requirements

TierSelf-serve importerAuto-notifyWhite-glove
Starter (trial)YesNoEarly adopters
Starter (paid)YesNoEarly adopters
Growth (trial)YesNoEarly adopters
Growth (paid)YesYesEarly adopters
ProYesYesAlways

The importer is available on Starter or higher (paid or trialing). Auto-notify requires Growth tier with an Active subscription. Trial users can compose and preview the notification (including a "send sample to myself"), but cannot fan out to imported affiliates until a payment method is on file.

When the gate fires, the API returns 402 with error: "paid_plan_required", required: "Growth", subscriptionStatus, and a trialing flag.

Choosing your destination campaign

Every importer assigns imported affiliates to one of your existing Rekomi campaigns. Pick the campaign before uploading. You can run multiple imports across multiple campaigns; the importer refuses to run a second concurrent import for the same organization until the first one finishes (prevents duplicate-affiliate races).

Auto-notify (Growth or higher)

If you want every imported affiliate to receive a sign-up invite right after the import lands, check Notify affiliates after import and write a personal note in the rich-text editor.

The personal note supports bold, italic, and link formatting (allowlisted to https links only), up to ~500 visible characters. It renders inside a brand-accent blockquote at the top of every notification email. Below it sits a single call-to-action button: Claim your account. The button opens app.rekomi.com/sign-up/affiliate with the affiliate's email prefilled, so they bind to the existing imported record on first sign-in (no duplicate accounts).

Before kicking off the real send, click Send a sample to myself. We fire a single preview email to your verified email address with the same payload your affiliates would see, plus a yellow "THIS IS A PREVIEW" banner so you can sanity-check the copy and HTML rendering.

When the bulk send fires, Hangfire throttles it to one email per second with up to 200ms jitter, so a 500-row import takes about 8 minutes end to end. The history table shows live Notifications: X sent · Y failed counters per job.

Affiliates sign in and claim

When an imported affiliate clicks the sign-up button in their email (or you share app.rekomi.com/sign-up/affiliate?email=their@email directly), Clerk creates their account. The Rekomi auto-claim handler binds the new Clerk user to the existing imported Affiliate row by matching emails. They land on their new affiliate dashboard with their tracking link already provisioned.

Skip reasons and what they mean

Per-row outcomes are visible in the import history detail panel:

ReasonWhat happened
missing_emailThe CSV row had no email column or it was blank.
already_existsAn affiliate with this email already exists in the target campaign.
row_parse_failedThe CSV row could not be parsed. Full error captured in Sentry; the operator-visible row stays generic to avoid leaking row content.
unsubscribedAffiliate previously unsubscribed from your org's emails. Honored at send-time.
plan_downgradedOrg tier dropped below Growth between enqueue and send. Pending notifications stop.
no_emailAffiliate row imported but the linked record has no email at send-time.
tenant_mismatchAffiliate row's organization no longer matches the import job's. Should not occur under normal use.
affiliate_anonymizedThe affiliate was anonymized between import and the throttled send. Right-to-be-forgotten honored.
send_failedTransient delivery failure. Full exception captured in Sentry. The row will not retry automatically; re-run the importer to retry.

Security and deliverability

  • HTML sanitization: your personal note is server-side sanitized to an allowlist (paragraph, line-break, bold, italic, link with https-only href). Script tags, inline styles, and non-https links are stripped.
  • Recipient pinning: the Hangfire job carries only the row identifier, not the email. The worker re-resolves the affiliate's email from the database at send-time, so a poisoned queue cannot redirect mail.
  • Unsubscribe honored: every email includes List-Unsubscribe headers and we re-check your org's unsubscribe list at send-time, not just at enqueue-time.
  • Throttling: one email per second per import job. Keeps you under Resend's transactional limits and well below Gmail / Microsoft 365 burst-detection heuristics for a fresh sender reputation.
  • Audit log: every state transition (migration.completed, migration.notify.queued, migration.notify.sent, migration.notify.failed, migration.notify.sample_sent) is recorded to your org's audit log for compliance and forensics.

Import via API or MCP

The dashboard importers above parse a specific vendor CSV for you. If you would rather automate the migration, or your data lives somewhere without a CSV export, you can import the same two things over the public REST API and through the MCP server (so an AI assistant can do it for you). These accept generic canonical JSON rows instead of a vendor file, and they run the exact same audited import services as the dashboard, so the money and identity rules are identical.

  • Affiliates: POST /api/v1/affiliates/import (MCP tool import_affiliates). Dedupes by email, preserves slugs, optional status filter and notify.
  • Conversions and commissions: POST /api/v1/conversions/import plus a dry-run POST /api/v1/conversions/import/preview (MCP tools import_conversions and preview_conversion_import). Paid rows lock as settled history; unpaid rows become payable only when you pass confirmUnpaidPayout=true. Always preview first to see the unpaid balance.

Both are Starter+ for API-key callers, capped at 1,000 rows per request, rate-limited, idempotent, and produce the same revertible import job you see in import history. Full request and response schemas are in the API reference and the MCP guide.

FAQ

Which importer should I pick if my source isn't in the list?

For LeadDyno, GrowSurf, Reditus, Impact.com, or in-house systems, use the white-glove path (chat in bottom right). We will scope the import end-to-end.

Can I edit the personal note after starting the import?

No. The note is locked at upload time and replays the same content to every affiliate in that batch. If you want a different message, run a separate import with a different note, or send a broadcast from /dashboard/broadcasts after the fact.

Can affiliates opt out of the notification?

Yes. Every email carries List-Unsubscribe headers and a footer unsubscribe link. Opting out skips them on this send and on every future org-scoped email until they re-subscribe.

What if I import into the wrong campaign?

The affiliate records are tied to the campaign at import time. You can change a single affiliate's campaign from /dashboard/affiliates/{id} (Manager role or higher). Bulk-reassignment is on the roadmap.

Does the importer create Clerk accounts on import?

No. We only create the Rekomi-side Affiliate row plus a default tracking link. The Clerk account is created when the affiliate signs up via their invite link. This keeps you in control of when your affiliate base appears in Clerk's user list and avoids surprise sign-up emails before you are ready.

Are sales or commissions imported too?

Yes. Use Step 2: history and earnings (see above) to upload your platform's referrals/commissions export. The import only records data; Rekomi never pays anyone automatically. Already-paid commissions import as locked history (never paid again); unpaid ones import as history too and only become payable (added to a payout run you start yourself) if you explicitly authorize it on the preview screen. Recurring commissions on existing customers continue when your export includes the Stripe customer/subscription ids and your Stripe account is connected.

My source platform's CSV has columns the importer doesn't recognize. Is that a problem?

No. The importer fuzzy-matches on header names and silently ignores unknown columns. As long as the required email column is present, the import proceeds. Unknown columns are NOT preserved in v1; if you need to retain custom fields or platform-specific metadata, contact support.

Where to go next

  • Sending domain: configure your own domain so migration notifications go out from you@yourbrand.com instead of the shared Rekomi sender.
  • Recruit affiliates: direct invite composer for one-off creator outreach beyond the bulk import path.
  • Plans and trials: see what each tier includes and how the 14-day free trial behaves.

Install on Django

Server-side S2S is the primary path. templates/base.html head install for click capture, services/rekomi.py for HMAC-signed conversion fires. Use Celery for async if firing from Stripe webhooks.

Migrating from Rewardful

Move your Rewardful affiliate roster onto Rekomi in an afternoon. Self-serve CSV import preserves every existing ?via= link, auto-notify rolls out fresh sign-in invites, and the 5-step cutover keeps active affiliates uninterrupted.

On this page

Dedicated migration guidesShared behavior across all 6 importersWhat gets importedImporting history and earnings (Step 2)Plan requirementsChoosing your destination campaignAuto-notify (Growth or higher)Affiliates sign in and claimSkip reasons and what they meanSecurity and deliverabilityImport via API or MCPFAQWhere to go next