Links


Create a Link

POST https://dynalink.app/api/links

Requires x-project-key header. See Installation for authentication details.

Request Parameters

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

Link Types

Standard Web Link

{
  "actual_url": "https://yourapp.io",
  "fallback_url": "https://yourapp.io"
}

Deep Link with Store Fallback

{
  "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"
}

Linked to a Campaign

{
  "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"
}

Social Preview Enabled

{
  "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"
}

Example Request

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"
  }'

Example Response

{
  "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"
}
Tip — Always include a 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.

Resolve a Link

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.

Register a 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 }
Tip — The same device and link is counted once per minute — the OS can deliver the same intent twice (cold start, then resume). Ignored calls answer {"success": true, "duplicate": true}.