Skip to content

Migration from Keitaro

If you are coming from Keitaro, most of what you already know maps cleanly onto slimTDS — campaigns, streams, filters, and S2S postbacks all have direct equivalents. This page translates the vocabulary and walks through moving a campaign across. slimTDS is deliberately narrower than Keitaro: it is a single-tenant, self-hosted router for organic and SEO traffic, not a multi-user platform with a landing-page host and network integrations. Knowing what does not carry over up front saves surprises.

KeitaroslimTDSNotes
CampaignCampaignThe entry point; its slug is the live URL /<slug>.
StreamFlowOrdered rules inside a campaign; first match wins.
OfferOfferOffers are global and reused across campaigns via a flow’s target list.
Local landing page— (host it yourself)slimTDS does not host or edit landers. Point an offer/redirect at your own lander URL.
FiltersFlow filtersJSONB AND-within-group, OR-across-groups. Geo, device, bot, source, time/IP.
Actions / redirect typeResponse schema16 types: 301–308, meta refresh, iframe, HTML/JSON/text, curl proxy, JS redirect, etc.
Split testing / rotationOffer weights + {spin}Weighted, visitor-stable offer shares; {spin} for landing rotation inside one offer.
Traffic source tokensMacros{click_id}, {utm_source}, {country}, … substituted in URLs and postbacks.
{subid} / click id{click_id}The UUIDv7 click identifier you pass to partners and receive back on postbacks.
Bot filtering (ISP/UA)Bot detectionIP · CIDR · ASN · ISP · User-Agent layers, refreshed daily.
S2S postback (incoming)PostbacksGET/POST /postback; per-offer tokens and a campaign-level catch-all.
Outgoing postbackOutgoing deliveriesDecoupled outbox with exponential-backoff retry.
ReportsStatisticsPartitioned click/conversion tables + dashboards.
Bot / crawler cloakingTrash routingUnmatched traffic goes to trash_mode + trash_url (incl. an {offer:…} reference).
  • Offers are global. In Keitaro an offer belongs to a campaign; in slimTDS the core.offers table has no campaign_id. You attach existing offers to a flow by weight, and the same offer can serve many campaigns at once.
  • No built-in landing pages. slimTDS routes traffic; it does not host, edit, or A/B local landers the way Keitaro does. Keep your landers where they are and reference their URLs — use {spin} to rotate several.
  • Single-tenant. One operator or team per install, no user roles or multi-account panel.
  • No offer-network catalogue or click-API imports. Campaigns, flows, and offers are created in the admin (or seeded); there is no Keitaro-format importer.
  • Slug-based URLs. A campaign is reached at /<slug> (a 6-char Base58 string or a custom alias), not a per-domain campaign link.
  1. Re-create offers. Add each destination as a global offer with its URL and payout. Convert Keitaro tokens in the URL to slimTDS macros (e.g. Keitaro {subid}{click_id}).
  2. Create the campaign. Give it a name and, if you want to preserve inbound links, a custom alias matching ^[a-zA-Z0-9]{3,16}$ as the slug.
  3. Rebuild streams as flows. For each Keitaro stream, add a flow, translate its filters into filter groups, attach the target offers with weights, and pick a response schema. Order flows most-specific first; leave a catch-all flow with empty filters last.
  4. Set trash routing. Map Keitaro’s “no stream matched” behaviour to the campaign’s trash_mode/trash_url — optionally an {offer:…} reference to fall through to an existing offer.
  5. Wire postbacks. Configure your partner to call slimTDS’s /postback with the {click_id} you passed out. For outgoing S2S, set up the outbound postback template with macros.
  6. Repoint traffic. Update your SEO landers / sources to the new /<slug> URL (embed the pixel on landers to get events and session replays).
  7. Verify. Send test clicks per geo/device, confirm they land on the intended offer, then fire a test postback and check the conversion appears.

Because there is no bulk importer, migrate one campaign at a time and validate it end to end before moving the next.