POST https://dynalink.app/api/links
Requires x-project-key header. See Installation for authentication details.
| Parameter | Type | Required | Description |
|---|---|---|---|
actual_url |
string | Yes | The destination URL |
name |
string | No | Human-readable label for the link |
campaign_id |
integer | No | ID of the campaign to associate this link with |
ios_url |
string | No | Direct link to iOS App Store |
android_url |
string | No | Direct link to Google Play Store |
ios_bundle_id |
string | No | iOS Bundle ID — auto-resolves the App Store URL via the iTunes API |
android_package_name |
string | No | Android package name — auto-resolves the Play Store URL |
fallback_url |
string | No | Fallback URL when no store or deep link applies |
is_deeplink |
boolean | No | Whether the link should open the app via deep link |
should_open_store |
boolean | No | Whether to open the store when the app is not installed |
social_title |
string | No | Title for social media link previews |
social_description |
string | No | Description for social media link previews (max 160 chars) |
social_image |
string | No | Image URL for social media link previews |
{
"actual_url": "https://yourapp.io",
"fallback_url": "https://yourapp.io"
}
{
"actual_url": "yourapp://screen/offer?id=99",
"is_deeplink": true,
"should_open_store": true,
"ios_bundle_id": "com.yourapp.ios",
"android_package_name": "com.yourapp.android",
"fallback_url": "https://yourapp.io"
}
{
"actual_url": "yourapp://screen/offer?id=99",
"name": "Summer promo",
"campaign_id": 4,
"is_deeplink": true,
"should_open_store": true,
"ios_bundle_id": "com.yourapp.ios",
"android_package_name": "com.yourapp.android"
}
{
"actual_url": "https://yourapp.io/product/99",
"social_title": "Check this out",
"social_description": "Exclusive summer deal — 40% off",
"social_image": "https://yourapp.io/og-summer.jpg"
}
curl -X POST https://dynalink.app/api/links \
-H "Content-Type: application/json" \
-H "x-project-key: YOUR_PROJECT_KEY" \
-d '{
"actual_url": "https://yourapp.io?screen=offer&id=99",
"name": "Summer promo deep link",
"campaign_id": 4,
"is_deeplink": true,
"should_open_store": true,
"ios_bundle_id": "com.yourapp.ios",
"android_package_name": "com.yourapp.android",
"fallback_url": "https://yourapp.io"
}'
{
"id": 42,
"code": "SUMR99",
"actual_url": "https://yourapp.io?screen=offer&id=99",
"name": "Summer promo deep link",
"campaign_id": 4,
"fallback_url": "https://yourapp.io",
"ios_url": "https://apps.apple.com/app/id123456789",
"android_url": "https://play.google.com/store/apps/details?id=com.yourapp.android",
"is_deeplink": true,
"should_open_store": true,
"clicked_count": 0,
"project_id": "9dfbcaf4-052b-4093-92fb-5781a2baa243",
"created_at": "2026-05-21T10:00:00.000000Z",
"updated_at": "2026-05-21T10:00:00.000000Z"
}
fallback_url for the best cross-platform experience. When ios_bundle_id or android_package_name is provided, the corresponding store URL is resolved automatically via the iTunes / Play Store APIs.
GET https://dynalink.app/api/links/{code}
Returns the link, its campaign context and its click counters. This is what the SDK calls when the OS opens the app directly through a verified App Link or Universal Link: the loading page never runs on that path, so the destination has to be fetched.
Accepts the short code or the numeric id, scoped to the project the
x-project-key header belongs to. Returns 404 when the code belongs to another
project.
curl https://dynalink.app/api/links/SUMR99 \
-H "x-project-key: YOUR_PROJECT_KEY"
{
"id": 42,
"code": "SUMR99",
"actual_url": "https://yourapp.io?screen=offer&id=99",
"fallback_url": "https://yourapp.io",
"clicked_count": 128,
"unique_clicks": 91,
"campaign_id": 4,
"campaign_name": "Summer 2026",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "summer_2026",
"project_id": "9dfbcaf4-052b-4093-92fb-5781a2baa243",
"created_at": "2026-05-21T10:00:00.000000Z",
"updated_at": "2026-05-21T10:00:00.000000Z"
}
clicked_count is a raw hit counter — every request, repeat visits included.
unique_clicks counts one per distinct device fingerprint, which is the number to
use when you pay or attribute per click.
POST https://dynalink.app/api/links/{code}/click
Records a click that never reached the loading page. When App Links or Universal Links are verified, the OS hands the link straight to the app, so nothing is counted server-side unless the app reports it. The Flutter SDK calls this automatically — you only need this endpoint if you handle links yourself.
| Parameter | Type | Required | Description |
|---|---|---|---|
fingerprint |
string | No | Device fingerprint, {IP}-{OS}-{Version}-{ScreenResolution} |
source |
string | No | Where the click came from, e.g. app_link |
click_ids |
object | No | Click IDs and URL-level UTM parameters to store on first capture |
Passing fingerprint in the same format the loading page builds makes the click
land on the same device row as browser clicks, so unique visitors and geo data
stay consistent. Without it, only the link counter moves.
curl -X POST https://dynalink.app/api/links/SUMR99/click \
-H "Content-Type: application/json" \
-H "x-project-key: YOUR_PROJECT_KEY" \
-d '{
"fingerprint": "102.244.220.125-Android-14-420x920",
"source": "app_link",
"click_ids": { "gclid": "Cj0KCQj...", "utm_source": "google" }
}'
{ "success": true, "clicked_count": 129, "fingerprint_id": 5120 }
{"success": true, "duplicate": true}.