API Reference
All authenticated endpoints accept either a Firebase ID token or an API key in the Authorization header.
Authorization: Bearer <firebase_id_token>
Authorization: Bearer flk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxGet your API key from your project Settings in the dashboard.
Links API
POST /api/links
Create a new short link.
| 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 |
// Response
{
"success": true,
"slug": "abc123",
"shortUrl": "https://yourapp.flku.dev/abc123",
"link": {
"projectId": "YOUR_PROJECT_ID",
"title": "Spring Sale",
"deepLink": "yourapp://promo/spring"
}
}POST /api/links/bulk
Create multiple links in a single JSON request. Maximum 100 links per request.
| 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 |
// Response
{
"created": 2,
"links": [
{ "slug": "abc123", "shortUrl": "https://myapp.flku.dev/abc123" },
{ "slug": "def456", "shortUrl": "https://myapp.flku.dev/def456" }
]
}POST /api/links/bulk-csv
Import links from a CSV or XLSX file. Maximum 500 rows per upload.
| Field | Type | Description |
|---|---|---|
| file | file (required) | CSV or XLSX upload |
| projectId | string (required) | Target project id |
// Response
{
"created": 120,
"skipped": 3,
"errors": [{ "row": 45, "message": "Invalid slug" }],
"links": []
}GET /api/links
List all links for the authenticated project.
// Response
[
{
"slug": "abc123",
"title": "Spring Sale",
"shortUrl": "https://yourapp.flku.dev/abc123"
}
]GET /api/links/:slug
Fetch one link by slug within the current project.
// Response
{
"slug": "abc123",
"title": "Spring Sale",
"fallbackUrl": "https://www.flinku.dev",
"deepLink": "yourapp://promo/spring"
}GET /api/links/:id/history
Returns the last 20 clicks for the link, including redirect chain details.
// Response
[
{
"clickedAt": "2026-03-01T12:00:00.000Z",
"country": "US",
"redirectChain": ["https://yourapp.flku.dev/x", "https://apps.apple.com/..."]
}
]POST /api/links/:id/clone
Clone a link with all settings (tags, campaigns, routing, etc.).
// Response
{
"success": true,
"link": {
"slug": "cloned-abc",
"shortUrl": "https://yourapp.flku.dev/cloned-abc",
"title": "Spring Sale (copy)"
}
}GET /api/links/:id/qr
Get the QR code for a link as a base64 data URL.
// Response
{
"qrCode": "data:image/png;base64,...",
"shortUrl": "https://myapp.flku.dev/abc123"
}GET /api/links/:id/qr/png
Download QR code as a PNG image file.
HTTP/1.1 200 OK
Content-Type: image/png
Content-Disposition: attachment; filename="abc123.png"PUT /api/links/:slug
Update mutable fields for an existing link. Accepts any fields from the create API.
// Response
{
"success": true,
"link": {
"slug": "abc123",
"title": "Spring Sale Extended"
}
}DELETE /api/links/:slug
Delete an existing link.
// Response
{ "success": true }GET /:slug
Resolves the slug on your project host (yourapp.flku.dev) and redirects to the App Store, Play Store, or in-app destination. No auth required.
HTTP/1.1 302 Found
Location: https://apps.apple.com/...POST /api/match
Resolve pending deferred deep links for SDK clients. No auth required.
| Field | Type | Description |
|---|---|---|
| deviceInfo | object | { userAgent, timestamp } |
// Response
{
"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"
}Creating links from the SDK
Flutter SDK 0.3.2+ and native SDKs 0.3.0+ can create short links in-app.
final flinku = Flinku(
userId: user.uid,
baseUrl: 'https://yourapp.flku.dev',
apiKey: 'flk_live_your_api_key',
);
final 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-campaignvar options = FlinkuLinkOptions(title: "Summer Campaign")
options.deepLink = "yourapp://promo"
options.params = ["ref": "instagram"]
flinku.createLink(options) { result in
switch result {
case .success(let link):
print(link.shortUrl)
case .failure(let error):
print(error)
}
}val link = flinku.createLink(FlinkuLinkOptions(
title = "Summer Campaign",
deepLink = "yourapp://promo",
params = mapOf("ref" to "instagram")
))
println(link.shortUrl)Campaigns API
GET /api/campaigns?projectId=X
List campaigns for the given project.
// Response
[
{
"id": "camp_abc123",
"projectId": "YOUR_PROJECT_ID",
"name": "Summer 2026",
"description": "Paid social"
}
]POST /api/campaigns
Create a campaign container for grouping links.
| Field | Type | Description |
|---|---|---|
| projectId | string (required) | Owning project |
| name | string (required) | Campaign name |
| description | string (optional) | Internal notes |
// Response
{
"success": true,
"campaign": {
"id": "camp_new",
"projectId": "YOUR_PROJECT_ID",
"name": "Spring Launch",
"description": "EU + US paid social"
}
}Analytics API
GET /api/analytics/influencers?projectId=X
Aggregated clicks, installs, and unique users per influencerId.
// Response
[
{
"influencerId": "john_doe",
"clicks": 1200,
"installs": 80,
"uniqueUsers": 950
}
]Projects API
GET /health
Health check endpoint. No auth required.
// Response
{
"status": "ok",
"timestamp": 1710012345678,
"uptime": 15423.22
}GET /api/projects/:id/journey.js
Public JavaScript bundle for the Journeys web banner. No auth required.
HTTP/1.1 200 OK
Content-Type: application/javascriptPATCH /api/projects/:id/members/:uid
Update a team member's role.
| Field | Type | Description |
|---|---|---|
| role | 'editor' or 'viewer' | New role for the user |
// Response
{
"success": true,
"member": {
"uid": "firebase_uid",
"role": "editor"
}
}Referrals API
POST /api/referrals/track
Record that a new user installed from a referral link. No auth required. Call this from the app after first open when referrerId was present in link params.
| Field | Type | Description |
|---|---|---|
| referrerId | string (required) | The referrer's user or influencer ID |
| projectId | string (required) | Project the referral belongs to |
// Response
{ "success": true }GET /api/referrals?projectId=X
Referral leaderboard for the project.
// Response
[
{
"referrerId": "user_abc",
"referrals": 42
}
]Firebase Migration API
POST /api/migration/preview
Parse a Firebase Dynamic Link URL and preview how it maps to Flinku fields. No links are created.
| Field | Type | Description |
|---|---|---|
| firebaseLink | string (required) | Full Firebase Dynamic Link URL |
// Response
{
"deepLink": "yourapp://screen",
"ogTitle": "Promo",
"ogDescription": "Summer sale",
"utmSource": "email",
"utmMedium": "newsletter",
"utmCampaign": "june"
}POST /api/migration/convert
Bulk-create Flinku short links from an array of Firebase Dynamic Link URLs.
| Field | Type | Description |
|---|---|---|
| firebaseLinks | string[] (required) | List of Firebase Dynamic Link URLs |
| projectId | string (required) | Target Flinku project |
// Response
{
"converted": 48,
"failed": 2,
"links": []
}Retargeting Pixel
GET /api/pixel/:projectId
Returns a 1×1 transparent GIF and records that the device visited the embedding website. No cookies, no personal data. Use for matching link clickers to prior site visits. No auth required.
HTTP/1.1 200 OK
Content-Type: image/gifPublic URL pattern: https://flku.dev/api/pixel/YOUR_PROJECT_ID