self-hosted deep linking · install attribution
from the click to the right screen. on your own server.
a replacement for Branch, AppsFlyer OneLink and Firebase Dynamic Links: short links, deferred deep linking, install and revenue attribution. one Go binary and PostgreSQL — the data never leaves your infrastructure.
01 {source}
where the person came from
a campaign, a blogger, a referral, a QR code at the checkout. every source gets its own link with UTM, campaign and tags. a month later you see who brought installs and purchases, not just clicks.
02 {path}
a short link that thinks
your own domain or a subdomain. rules by platform, language, country, query and time, cookie-less A/B. messengers and bots get an OG preview, desktop gets a QR code.
03 {bridge}
through the store, straight to the right screen
app installed — a Universal Link or App Link opens it right away. not installed — the person goes to App Store, Google Play or RuStore, and the first launch lands on deep_link_path, not the home screen.
04 {signal}
recognise the install without IDFA
Install Referrer on Google Play and RuStore, a clipboard token on iOS. probabilistic matching is only the fallback, with per-app weights and thresholds. every match attempt is logged.
05 {event}
revenue tied to the link
purchases and in-app events with idempotency and last-link attribution. D1/D7/D30 retention, signed webhooks to your backend, fraud flags for datacenters, bots and bursts.
→ {how it works}
one click, five steps, zero lost context
- linkclick recorded, signed token issued
- landingios: token to clipboard · android: referrer in the store link
- storeapp store · google play · rustore
- first launchsdk: referrer → clipboard → fingerprint → organic
- right screenonLink delivers path, payload and utm
→ {for developers}
one init in Flutter, three lines in the terminal
await DeepLinks.init(
baseUrl: 'https://sdk.spbse.online',
appKey: 'dl_pk_…',
linkDomains: ['go.example.com'],
);
DeepLinks.onLink.listen((link) => router.go(link.path!));
curl https://api.spbse.online/v1/links \
-H "Authorization: Bearer $DM_KEY" \
-d '{"app_id":"…","code":"spring","deep_link_path":"/item/7"}'
our own package on pub.dev
new_deeplinks v0.1.2
deep links, deferred deep links and install attribution for Flutter. open source, tested end to end on iOS and Android.
the SDK is Flutter only. there are no native SDKs yet, and we say so upfront.
→ {AI agents · mcp}
ask Claude where the installs came from
a built-in MCP server: Claude, ChatGPT and Cursor create links, read analytics and explain why an install was matched the way it was. API key or OAuth 2.1, read and write scopes, no destructive tools, every call goes to the audit log.
claude mcp add --transport http spbse \
https://api.spbse.online/mcp \
--header "Authorization: Bearer dl_sk_…"
> why did this install count as organic?
↳ explain_install · match_whatif
→ {privacy}
we store less than we could
- ∅ idfa / gaidno advertising identifiers collected, no App Tracking Transparency prompt needed
- ip → hmacraw IPs never reach the database or the logs — only HMAC-SHA256 with a secret pepper
- 72hclick fingerprints are wiped after 72 hours, only aggregates remain
- your postgreseverything lives in your database. no vendor between you and your users
06 {migrating from branch / appsflyer}
old links keep working
move your domain over: Branch links are imported lazily on first click, an AppsFlyer OneLink export is imported in one go. QR codes, newsletters and posts from years ago don't break.
07 {manifesto}
manifesto
- 01your data stays with you
clicks, installs and revenue live in your PostgreSQL. nobody trains on your traffic.
- 02accuracy over reach
deterministic signals first. a probabilistic match comes last, with a threshold and an explanation.
- 03honest about the limits
spbse is not an MMP: no SKAdNetwork, no ad network postbacks, no multi-touch. your own traffic — yes, paid acquisition — no.
- 04one binary beats ten services
Go and PostgreSQL. no queues or caches to deploy and monitor separately.
- 05a link should not die
Firebase Dynamic Links shut down in 2025. links on your own domain outlive any vendor, including us.
→ {contact}
run spbse next to your backend
we'll walk you through the dashboard, help with the domain and the move off your old vendor.
this form is a request. it goes straight to the team's Telegram: no CRM, no newsletters, no sales reps.