Links
Create links from your server. Read their details and lifetime metrics.
These endpoints live on the SDK host: https://sdk.sqd.link on grovs Cloud, https://sdk.<SERVER_HOST> when you self-host. Send your project key in the PROJECT-KEY header. Send production or test in the ENVIRONMENT header.
Each environment has its own links. A link created in test is not visible in production.
Generate a link
/api /v1 /sdk /generate_linkCreates a link with your own data, per-platform redirects and tracking parameters, and returns its URL.
PROJECT-KEYstringRequiredYour project key. Find it in Developers › API Key in the dashboard.
ENVIRONMENTstringRequiredproduction or test. Any other value returns 400.
Content-TypestringRequiredapplication/json.
titlestringOptionalTitle shown in the link preview.
subtitlestringOptionalSubtitle shown in the link preview.
datastringOptionalStringified JSON object delivered to your app by the SDK when the link opens it. Example: "{\"screen\":\"booking\"}". A string that is not valid JSON returns 400.
tagsstringOptionalStringified JSON array of tags. Example: "[\"clinics\",\"autumn\"]". The reserved tag smart_banner is removed.
ios_custom_redirectobjectOptionaliOS redirect with url (string) and open_app_if_installed (boolean, required). Without open_app_if_installed the whole redirect is ignored. With true, the app opens if it is installed and url is used otherwise. With false, url is always used and deferred deep linking is off for this link on iOS. You can also send the object as stringified JSON.
android_custom_redirectobjectOptionalAndroid redirect. Same shape and rules as ios_custom_redirect.
desktop_custom_redirectobjectOptionalDesktop browser fallback with url (string). open_app_if_installed is ignored and always stored as false.
show_preview_iosboolean | nullOptionalShow the preview page on iOS. Omit it, or send null, to use the project's redirect rule. true or false overrides the rule for this link.
show_preview_androidboolean | nullOptionalShow the preview page on Android. Same rules.
show_previewbooleanOptionalShorthand for both platforms. It applies to each platform whose own field you did not send.
copy_to_clipboard_iosboolean | nullOptionalCopy the link to the clipboard from the iOS preview page, so the SDK can match the install to this tap. Omit it or send null to use the project setting. Only works when the preview page is shown on iOS. See Copy to clipboard.
copy_to_clipboard_androidboolean | nullOptionalSame, for Android.
tracking_campaignstringOptionalCampaign name, for example autumn_checkups.
tracking_sourcestringOptionalTraffic source, for example newsletter or instagram.
tracking_mediumstringOptionalMedium, for example email, cpc or social.
Returns
The new link's URL, with status 200.
linkstringThe link URL, ready to share.
data and tags must be strings that contain JSON. If you send a raw object or array instead, it is dropped without an error and the link is created without it.
Links created through this endpoint are marked as SDK-generated. They are kept out of the default link list in the dashboard; the link search shows them with its SDK filter.
Keep your PROJECT-KEY on your server. If it leaks, contact [email protected] to replace it.
Errors
See Errors for the shared error format.
curl -X POST "https://sdk.sqd.link/api/v1/sdk/generate_link" \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production" \
-H "Content-Type: application/json" \
-d '{
"title": "Book a check-up",
"subtitle": "Same-week appointments at Medly clinics",
"data": "{\"screen\":\"booking\",\"clinic_id\":\"42\"}",
"tags": "[\"clinics\",\"autumn\"]",
"ios_custom_redirect": {
"url": "https://medly.health/ios",
"open_app_if_installed": true
},
"android_custom_redirect": {
"url": "https://medly.health/android",
"open_app_if_installed": true
},
"desktop_custom_redirect": { "url": "https://medly.health/book" },
"show_preview_ios": true,
"show_preview_android": false,
"tracking_campaign": "autumn_checkups",
"tracking_source": "newsletter",
"tracking_medium": "email"
}'{
"link": "https://medly.sqd.link/2c1e79"
}{
"error": "Invalid credentials"
}Get link details
/api /v1 /sdk /link /{link_path}Returns a link by its path, looked up in the environment named by the ENVIRONMENT header. Use it to read a link's data for reporting, routing or validation on your server.
PROJECT-KEYstringRequiredYour project key. Find it in Developers › API Key in the dashboard.
ENVIRONMENTstringRequiredproduction or test. Any other value returns 400.
link_pathstringRequiredThe part of the link URL after the last /, for example 2c1e79. Links created in the test environment carry a -test suffix (2c1e79-test); send it as is.
The request has no body.
Returns
{ "link": { … } } with the fields below.
idintegerNumeric link ID.
namestring | nullName set in the dashboard. Usually null for links created through the API.
pathstringPath of the link URL.
access_pathstringFull link URL.
titlestring | nullPreview title.
subtitlestring | nullPreview subtitle.
imagestring | nullPreview image URL, if one is set.
dataobject | nullYour custom data, parsed into an object.
tagsarrayTags of the link.
activebooleanWhether the link is active.
sdk_generatedbooleantrue for links created through the API or an SDK.
generated_from_platformstring | nullWhere the link was created, for example API, iOS or Android.
ads_platformstring | nullAds platform the link was made for, if any.
campaign_idinteger | nullNumeric ID of the dashboard campaign the link belongs to, if any.
visitor_idinteger | nullNumeric ID of the app user who created the link, for links created from your app.
updated_atstringISO 8601 time of the last change.
show_preview_iosboolean | nullWhether the preview page shows on iOS. null means the project's redirect rule applies.
show_preview_androidboolean | nullSame, for Android.
copy_to_clipboard_iosboolean | nullWhether the iOS preview page copies the link to the clipboard. null means the project setting applies. See Copy to clipboard.
copy_to_clipboard_androidboolean | nullSame, for Android.
ios_custom_redirectobject | nullurl and open_app_if_installed, or null when none is set.
android_custom_redirectobject | nullurl and open_app_if_installed, or null when none is set.
desktop_custom_redirectobject | nullurl, and open_app_if_installed which is always false, or null when none is set.
tracking_campaignstring | nullCampaign name.
tracking_sourcestring | nullTraffic source.
tracking_mediumstring | nullMedium.
Errors
A link created in one environment is not visible in the other. If you get 404 for a link you know exists, check that ENVIRONMENT matches the environment the link was created in.
curl -X GET "https://sdk.sqd.link/api/v1/sdk/link/{link_path}" \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production"{
"link": {
"id": 50510,
"name": null,
"path": "2c1e79",
"title": "Book a check-up",
"subtitle": "Same-week appointments at Medly clinics",
"active": true,
"sdk_generated": true,
"data": {
"screen": "booking",
"clinic_id": "42"
},
"tags": ["clinics", "autumn"],
"updated_at": "2026-10-02T12:43:53.604Z",
"show_preview_ios": true,
"show_preview_android": false,
"copy_to_clipboard_ios": null,
"copy_to_clipboard_android": null,
"ads_platform": null,
"generated_from_platform": "API",
"tracking_source": "newsletter",
"tracking_medium": "email",
"tracking_campaign": "autumn_checkups",
"visitor_id": null,
"campaign_id": null,
"image": null,
"access_path": "https://medly.sqd.link/2c1e79",
"ios_custom_redirect": {
"url": "https://medly.health/ios",
"open_app_if_installed": true
},
"android_custom_redirect": {
"url": "https://medly.health/android",
"open_app_if_installed": true
},
"desktop_custom_redirect": {
"url": "https://medly.health/book",
"open_app_if_installed": false
}
}
}{
"error": "Link not found"
}Get link metrics
/api /v1 /sdk /metrics_for_link /{link_path}Returns one link's descriptive fields and its lifetime totals. The path is looked up in the environment named by the ENVIRONMENT header. Deactivated links are returned too.
PROJECT-KEYstringRequiredYour project key. Find it in Developers › API Key in the dashboard.
ENVIRONMENTstringRequiredproduction or test. Any other value returns 400.
link_pathstringRequiredThe link's path, for example 2c1e79, or 2c1e79-test in the test environment.
Returns
{ "metrics": { … } }. The object has the same descriptive fields as Get link details, without image, access_path and the custom redirects, plus the totals below.
total_viewsintegerTimes the link was opened in a browser.
total_opensintegerTimes the link opened the app, including deferred opens after an install.
total_installsintegerInstalls attributed to the link.
total_reinstallsintegerReinstalls attributed to the link.
total_time_spentintegerTotal time in the app of users attributed to the link, in seconds.
total_reactivationsintegerUsers attributed to the link who came back after at least seven days away.
total_app_opensintegerApp opens by users attributed to the link.
total_user_referredintegerInstalls referred by the link's creator, for links created by a user in your app.
total_revenueintegerRevenue attributed to the link, in cents. 0 unless revenue collection is on.
Totals cover the link's whole life, limited by your plan's analytics retention. On grovs Cloud, events older than the retention period are not counted.
Errors
See Errors for the shared error format.
curl -X GET "https://sdk.sqd.link/api/v1/sdk/metrics_for_link/{link_path}" \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production"{
"metrics": {
"id": 50510,
"name": null,
"path": "2c1e79",
"title": "Book a check-up",
"subtitle": "Same-week appointments at Medly clinics",
"active": true,
"sdk_generated": true,
"data": { "screen": "booking", "clinic_id": "42" },
"tags": ["clinics", "autumn"],
"updated_at": "2026-10-02T12:43:53.604Z",
"show_preview_ios": true,
"show_preview_android": false,
"copy_to_clipboard_ios": null,
"copy_to_clipboard_android": null,
"ads_platform": null,
"generated_from_platform": "API",
"tracking_source": "newsletter",
"tracking_medium": "email",
"tracking_campaign": "autumn_checkups",
"visitor_id": null,
"campaign_id": null,
"total_views": 1250,
"total_opens": 840,
"total_installs": 312,
"total_reinstalls": 18,
"total_time_spent": 96420,
"total_reactivations": 41,
"total_app_opens": 2210,
"total_user_referred": 0,
"total_revenue": 149900
}
}{
"error": "Link not found"
}Get project metrics
/api /v1 /sdk /metrics_for_projectReturns every active link in the environment named by the ENVIRONMENT header, with its lifetime totals, sorted by views from most to least. Everything comes back in one response; there is no pagination.
PROJECT-KEYstringRequiredYour project key. Find it in Developers › API Key in the dashboard.
ENVIRONMENTstringRequiredproduction or test. Any other value returns 400.
The endpoint takes no query parameters and no body.
Returns
A JSON array. Each item has the same shape as the metrics object of Get link metrics: the link's descriptive fields plus total_views, total_opens, total_installs, total_reinstalls, total_time_spent, total_reactivations, total_app_opens, total_user_referred and total_revenue.
Links deactivated in the dashboard are left out, and so are the links smart banners create. Totals cover each link's whole life, limited by your plan's analytics retention.
A project with many links gets a large response. Cache it on your side instead of polling it often.
Errors
See Errors for the shared error format.
curl -X GET "https://sdk.sqd.link/api/v1/sdk/metrics_for_project" \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production"[
{
"id": 50510,
"name": null,
"path": "2c1e79",
"title": "Book a check-up",
"subtitle": "Same-week appointments at Medly clinics",
"active": true,
"sdk_generated": true,
"data": { "screen": "booking", "clinic_id": "42" },
"tags": ["clinics", "autumn"],
"updated_at": "2026-10-02T12:43:53.604Z",
"show_preview_ios": true,
"show_preview_android": false,
"copy_to_clipboard_ios": null,
"copy_to_clipboard_android": null,
"ads_platform": null,
"generated_from_platform": "API",
"tracking_source": "newsletter",
"tracking_medium": "email",
"tracking_campaign": "autumn_checkups",
"visitor_id": null,
"campaign_id": null,
"total_views": 1250,
"total_opens": 840,
"total_installs": 312,
"total_reinstalls": 18,
"total_time_spent": 96420,
"total_reactivations": 41,
"total_app_opens": 2210,
"total_user_referred": 0,
"total_revenue": 149900
},
{
"id": 50488,
"name": "Flu shot reminder",
"path": "8f21ac",
"title": "Flu shots are open",
"subtitle": null,
"active": true,
"sdk_generated": false,
"data": { "screen": "vaccines" },
"tags": [],
"updated_at": "2026-09-28T08:10:02.117Z",
"show_preview_ios": null,
"show_preview_android": null,
"copy_to_clipboard_ios": null,
"copy_to_clipboard_android": null,
"ads_platform": null,
"generated_from_platform": null,
"tracking_source": "email",
"tracking_medium": "newsletter",
"tracking_campaign": "flu_2026",
"visitor_id": null,
"campaign_id": 41,
"total_views": 630,
"total_opens": 402,
"total_installs": 95,
"total_reinstalls": 3,
"total_time_spent": 31877,
"total_reactivations": 12,
"total_app_opens": 1104,
"total_user_referred": 0,
"total_revenue": 0
}
]