API Reference
Base URL: https://flku.dev
Link management and match APIs are scoped to a project. Public short links and well-known files (Universal Links / App Links) are served on https://<subdomain>.flku.dev.
Authentication
Flinku supports two authentication methods:
1. Firebase ID Token (dashboard users)
Authorization: Bearer <firebase-id-token>
2. API Key (programmatic access)
Authorization: Bearer flk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Get your API key from your project Settings in the dashboard.
Links API
Create a link (example)
Example against the public API host. Replace flk_live_your_api_key with your key.
POST https://flku.dev/api/linksAuthorization: Bearer flk_live_your_api_keyContent-Type: application/json
Request body
{"projectId": "YOUR_PROJECT_ID","title": "Summer Campaign","deepLink": "yourapp://promo","params": { "ref": "instagram", "promo": "SAVE20" },"utmSource": "instagram","utmMedium": "social","utmCampaign": "summer_sale","desktopUrl": "https://yourwebsite.com/promo","expiresAt": "2026-12-31T00:00:00Z","maxClicks": 1000}
Bulk link creation (JSON)
POST https://flku.dev/api/links/bulkAuthorization: Bearer flk_live_your_api_keyContent-Type: application/json
{"projectId": "your_project_id","links": [{ "title": "Link 1", "deepLink": "yourapp://screen1" },{ "title": "Link 2", "deepLink": "yourapp://screen2" }]}
Bulk import (CSV)
POST https://flku.dev/api/links/bulk-csvAuthorization: Bearer flk_live_your_api_keyContent-Type: multipart/form-data
Form fields: file (CSV), projectId. Response includes created, skipped, errors, and links.
Creating links from the SDK
Flutter SDK 0.7.0+ and native mobile SDKs (iOS 0.7.0+, Android 0.7.0+, React Native 0.7.1+, Capacitor 0.7.1+, Unity 0.7.0+) can create short links in-app using your project baseUrl and API key.
Correct architecture: Keep the API key on your own backend. Your app calls your backend, your backend calls Flinku, your backend returns the short URL to your app.
App → Your Backend → Flinku API → short URL → App shares itFlutter
// Configure once at app startup with your API keyFlinku.configure(baseUrl: 'https://yourapp.flku.dev',apiKey: 'flk_live_your_api_key',);// Then create links anywhere using the static methodfinal link = await Flinku.createLink(FlinkuLinkOptions(title: 'Summer Campaign',deepLink: 'yourapp://promo',params: {'ref': 'instagram', 'promo': 'SAVE20'},utmSource: 'instagram',utmMedium: 'social',));print(link.shortUrl); // https://yourapp.flku.dev/summer-campaign
iOS (Swift)
var options = FlinkuLinkOptions(title: "Summer Campaign")options.deepLink = "yourapp://promo"options.params = ["ref": "instagram"]flinku.createLink(options) { result inswitch result {case .success(let link):print(link.shortUrl)case .failure(let error):print(error)}}
Android (Kotlin)
val link = flinku.createLink(FlinkuLinkOptions(title = "Summer Campaign",deepLink = "yourapp://promo",params = mapOf("ref" to "instagram")))println(link.shortUrl)
createLinkInstant() returns the short URL instantly without waiting for the server. The link is saved in the background. Use this for share buttons where speed matters.
Flutter
import 'package:share_plus/share_plus.dart';final link = Flinku.createLinkInstant(FlinkuLinkOptions(title: 'Summer Campaign',deepLink: 'yourapp://promo',));await Share.share(link.shortUrl);
iOS (Swift)
let link = try Flinku.createLinkInstant(options)let activityVC = UIActivityViewController(activityItems: [link.shortUrl], applicationActivities: nil)
Android (Kotlin)
val link = Flinku.createLinkInstant(FlinkuLinkOptions(title = "Summer Campaign"))val sendIntent = Intent(Intent.ACTION_SEND).apply {type = "text/plain"putExtra(Intent.EXTRA_TEXT, link.shortUrl)}startActivity(Intent.createChooser(sendIntent, null))
/api/linksCreate a new short link in the authenticated project. Supports attribution, expiry limits, passwords, geo routing, scheduled activation, smart fallback chain, and social preview metadata.
Auth: Required
| Field | Type | Description |
|---|---|---|
| projectId | string (required) | Project ID that owns this link |
| title | string (required) | Human-readable link title |
| deepLink | string (optional) | In-app route like yourapp://product/42 |
| params | object (optional) | Custom key-value payload |
| slug | string (optional) | Custom slug for short URL |
| desktopUrl | string (optional) | Desktop redirect URL |
| utmSource | string (optional) | UTM source value |
| utmMedium | string (optional) | UTM medium value |
| utmCampaign | string (optional) | UTM campaign value |
| utmContent | string (optional) | UTM content value |
| utmTerm | string (optional) | UTM term value |
| expiresAt | ISO date string (optional) | Link expiration datetime |
| maxClicks | number (optional) | Maximum click count before expiry |
| password | string (optional) | Password required before redirect |
| scheduledAt | ISO date string (optional) | When the link becomes active |
| geoRouting | array (optional) | Up to 10 rules: { countries, url } |
| fallbackChain | string[] (optional) | Up to 3 HTTPS URLs for HEAD probe chain |
| influencerId | string (optional) | Attribution id for influencer reporting |
| ogTitle | string (optional) | Open Graph title override |
| ogDescription | string (optional) | Open Graph description override |
| ogImageUrl | string (optional) | Open Graph image URL override |
{"success": true,"slug": "abc123","shortUrl": "https://yourapp.flku.dev/abc123","link": {"projectId": "YOUR_PROJECT_ID","title": "Spring Sale","deepLink": "yourapp://promo/spring"}}
/api/links/bulkCreate multiple links in a single JSON request. Maximum 100 links per request.
Auth: Required
| Field | Type | Description |
|---|---|---|
| projectId | string | Project ID for all links in this request |
| links[] | array | Array of up to 100 link definitions |
| links[].title | string | Link title |
| links[].deepLink | string (optional) | Deep link URI |
| links[].params | object (optional) | Custom key-value params |
| links[].desktopUrl | string (optional) | Desktop redirect URL |
| links[].utmSource | string (optional) | UTM source value |
| links[].utmMedium | string (optional) | UTM medium value |
| links[].utmCampaign | string (optional) | UTM campaign value |
| links[].expiresAt | ISO date string (optional) | Link expiration datetime |
| links[].maxClicks | number (optional) | Maximum click count |
| links[].password | string (optional) | Password protection |
{"created": 2,"links": [{ "slug": "abc123", "shortUrl": "https://myapp.flku.dev/abc123" },{ "slug": "def456", "shortUrl": "https://myapp.flku.dev/def456" }]}
/api/links/bulk-csvImport links from a CSV file. Maximum 400 rows and 1MB per upload. See Bulk Import (CSV) in the docs for column definitions.
Auth: Required
| Field | Type | Description |
|---|---|---|
| file | file (required) | CSV upload |
| projectId | string (required) | Target project id |
{"created": 120,"skipped": 3,"errors": [{ "row": 45, "message": "Invalid slug" }],"links": []}
/api/linksList all links for the authenticated project.
Auth: Required
[{"slug": "abc123","title": "Spring Sale","shortUrl": "https://yourapp.flku.dev/abc123"}]
/api/links/:slugFetch one link by slug within the current project.
Auth: Required
{"slug": "abc123","title": "Spring Sale","fallbackUrl": "https://www.flinku.dev","deepLink": "yourapp://promo/spring"}
/api/links/:id/historyReturns the last 20 clicks for the link, including redirect chain details when available.
Auth: Required
[{"clickedAt": "2026-03-01T12:00:00.000Z","country": "US","redirectChain": ["https://yourapp.flku.dev/x", "https://apps.apple.com/..."]}]
/api/links/:id/cloneClone a link with all settings (tags, campaigns, routing, etc.). Returns the new link record.
Auth: Required
{"success": true,"link": {"slug": "cloned-abc","shortUrl": "https://yourapp.flku.dev/cloned-abc","title": "Spring Sale (copy)"}}
/api/links/:id/qrGet the QR code payload for a link as base64 data URL.
Auth: Required
{"qrCode": "data:image/png;base64,...","shortUrl": "https://myapp.flku.dev/abc123"}
/api/links/:id/qr/pngDownload QR code as a PNG image file.
Auth: Required
HTTP/1.1 200 OKContent-Type: image/pngContent-Disposition: attachment; filename="abc123.png"
/api/links/:slugUpdate mutable fields for an existing link.
Auth: Required
| Field | Type | Description |
|---|---|---|
| updatable fields | object | Any fields accepted by create API |
{"success": true,"link": {"slug": "abc123","title": "Spring Sale Extended"}}
/api/links/:slugDelete an existing link.
Auth: Required
{"success": true}
/api/links/resolve/:slug?subdomain=...Public JSON lookup for an already-installed app that received a Flinku short URL over Universal Links or App Links. Returns the slug, deepLink, params, and title without redirecting. No authentication required. Distinct from POST /api/match, which resolves deferred install attribution.
Auth: None
| Field | Type | Description |
|---|---|---|
| slug | path (required) | Short link slug, e.g. abc123 from https://yourapp.flku.dev/abc123 |
| subdomain | query (required) | Project subdomain, e.g. yourapp |
// 200 OK{"slug": "abc123","deepLink": "yourapp://product/42","params": { "ref": "instagram", "promo": "SAVE20" },"title": "Spring Sale"}// 400 Bad Request — missing slug or subdomain{ "error": "slug and subdomain are required" }// 404 Not Found — no link for that slug + subdomain{ "error": "Link not found" }
/:slugOn the project host (yourapp.flku.dev), resolves the slug and redirects, typically to the App Store, Play Store, or in-app destination.
Auth: None
HTTP/1.1 302 FoundLocation: https://apps.apple.com/...
/api/matchResolve pending deferred deep links for SDK clients scoped to the project behind the request host or device session.
Auth: None
| Field | Type | Description |
|---|---|---|
| deviceInfo | object | { userAgent, timestamp } |
{"matched": true,"deepLink": "yourapp://product/42","params": { "ref": "instagram", "promo": "SAVE20" },"slug": "abc123","subdomain": "yourapp","title": "Spring Sale","projectId": "YOUR_PROJECT_ID","clickedAt": "2026-03-25T12:00:00.000Z"}
Campaigns API
/api/campaigns?projectId=XList campaigns for the given project.
Auth: Required
[{"id": "camp_abc123","projectId": "YOUR_PROJECT_ID","name": "Summer 2026","description": "Paid social"}]
/api/campaignsCreate a campaign container for grouping links.
Auth: Required
| Field | Type | Description |
|---|---|---|
| projectId | string (required) | Owning project |
| name | string (required) | Campaign name |
| description | string (optional) | Internal notes |
{"success": true,"campaign": {"id": "camp_new","projectId": "YOUR_PROJECT_ID","name": "Spring Launch","description": "EU + US paid social"}}
Analytics API
/api/analytics/influencers?projectId=XAggregated clicks, installs, and unique users per influencerId for the project.
Auth: Required
[{"influencerId": "john_doe","clicks": 1200,"installs": 80,"uniqueUsers": 950}]
Projects API
/healthHealth check endpoint for uptime monitoring.
Auth: None
{"status": "ok","timestamp": 1710012345678,"uptime": 15423.22}
/api/projects/:id/journey.jsPublic JavaScript bundle for the Journeys web banner. Embed the snippet from the dashboard or load this URL directly.
Auth: None
HTTP/1.1 200 OKContent-Type: application/javascript/* Hosted Journeys bootstrap */
/api/projects/:id/members/:uidUpdate a team member's role (project owner / admin actions).
Auth: Required
| Field | Type | Description |
|---|---|---|
| role | 'editor' | 'viewer' | New role for the Firebase uid |
{"success": true,"member": {"uid": "firebase_uid","role": "editor"}}
Referrals API
/api/referrals/trackRecord that a new user came from a referral link. Flinku.setUserId calls this automatically when a pending referrerId exists. Do not call this by hand from the app.
Auth: API key or Firebase ID token
| Field | Type | Description |
|---|---|---|
| projectId | string (required) | Flinku project id |
| referrerId | string (required) | User id of the referrer (matches params.referrerId on the link) |
| newUserId | string (required for API key auth) | Id of the new user |
| referrerLabel | string (optional) | Readable referrer name |
| linkId | string (optional) | Matched link id |
{"status": "attributed","flagReason": null}
/api/referrals/qualifyMark a referred user as qualified. Prefer Flinku.qualifyReferral.
Auth: API key or Firebase ID token
| Field | Type | Description |
|---|---|---|
| projectId | string (required) | Flinku project id |
| newUserId | string (required for API key auth) | Id of the new user |
| event | string (optional) | Defaults to default |
{"status": "qualified","flagReason": null,"qualifyEvent": "purchase"}
/api/referrals?projectId=X&range=7d|30d|allFunnel and referrer table for the project.
Auth: Required
{"range": "30d","funnel": { "clicks": 1200, "installs": 340, "qualified": 95, "clickToInstallRate": 0.28 },"flaggedCount": 12,"referrers": [{ "referrerId": "user_123", "referrerLabel": "Alice", "clicks": 40, "installs": 10, "qualified": 4, "flagged": 0 }]}
/api/referrals/stats?projectId=XAggregate referral statistics for the project.
Auth: Required
{"totalReferrals": 500,"uniqueReferrers": 120,"topReferrer": "user_123"}
Firebase migration API
/api/migration/previewParse a legacy Firebase Dynamic Link URL and preview how it maps to Flinku fields (no links created).
Auth: None
| Field | Type | Description |
|---|---|---|
| firebaseLink | string (required) | Full Firebase Dynamic Link URL to inspect |
{"deepLink": "yourapp://screen","ogTitle": "Promo","ogDescription": "Summer sale","utmSource": "email","utmMedium": "newsletter","utmCampaign": "june"}
/api/migration/convertBulk-create Flinku short links from an array of Firebase Dynamic Link URLs for the given project.
Auth: Required
| Field | Type | Description |
|---|---|---|
| firebaseLinks | string[] (required) | List of Firebase Dynamic Link URLs to convert |
| projectId | string (required) | Target Flinku project |
{"converted": 48,"failed": 2,"links": []}
Retargeting pixel
/api/pixel/:projectIdRetargeting pixel: returns a 1×1 transparent GIF and records that the device visited the embedding website (no cookies, no personal data in the pixel itself). Use for matching link clickers to prior site visits.
Auth: None
HTTP/1.1 200 OKContent-Type: image/gifGIF89a… (1×1 transparent)
Public URL pattern: https://flku.dev/api/pixel/YOUR_PROJECT_ID (same path on your API host when self-hosting).
Authorization: Bearer header, depending on your integration.