Documentation Index
Fetch the complete documentation index at: https://docs.linkrunner.io/llms.txt
Use this file to discover all available pages before exploring further.
Base URL
https://api.linkrunner.io/api/v1
Authentication
All API requests require authentication using an API key. You must include this key in the header of every request.
Include the following header in all API requests:
linkrunner-key: YOUR_API_KEY
Replace YOUR_API_KEY with your actual API key.
Obtaining Your API Key
You can find your API key on the Linkrunner settings page:
- Go to https://dashboard.linkrunner.io/settings?s=data-apis
- Locate your Server key on this page
- Use this key in the
linkrunner-key header for all API requests
Keep your API key confidential. Do not share it or expose it in client-side code. Always make API requests from a secure server-side environment.
Error Responses
- 401 Unauthorized
"Server key missing!"
"Server key invalid!"
- 429 Too Many Requests
- Message:
"Rate limit exceeded. Please try again later."
- Cause: You’ve exceeded the rate limit of 10 requests per second.
Rate Limit Details
- Rate: 10 requests per second
- Status code on limit exceeded: 429 (Too Many Requests)
Endpoints
1. List Campaigns
For getting/listing existing campaigns, please refer to the List Campaigns API documentation.
2. Create Campaign
Create a new campaign. You can optionally create a short link by including the is_shortlink: true parameter.
Request
Request Body Examples
Creating Campaign:
{
"name": "Summer Sale 2023",
"deeplink": "https://app.domain.com/promo/summer25",
"link_for_desktop_users": "https://www.your-website.com",
"custom_display_id": "summer-sale-2025",
"is_shortlink": false //pass this as true to create a shortened campaign link
}
Request Parameters
| Parameter | Type | Required | Description |
|---|
name | string | Yes | The display name of your campaign. This helps you identify the campaign in your dashboard. |
deeplink | string | No | The URL that mobile app users will be directed to when they click your campaign link. Should be a valid deep link URL for your mobile application. |
link_for_desktop_users | string | No | The fallback URL for desktop users who click your campaign link. Typically points to your website or web application. |
android_web_redirect | string | No | Provide this only if you want the user to be explicitly redirected to a specific web URL on Android. |
ios_web_redirect | string | No | Provide this only if you want the user to be explicitly redirected to a specific web URL on iOS. |
custom_display_id | string | No | A custom identifier for your campaign. Must be unique across your account. If not provided, a random ID will be generated. |
is_shortlink | boolean | No | Set to true to create a shortened campaign link. When enabled, creates a compact URL format suitable for sharing. |
domain | string | No | The domain name to use for this campaign (e.g., “app.example.com”). Must belong to your project. If not provided, the project’s primary domain will be used. |
store_listing_ids | string[] | No | Array of store listing IDs to associate with this campaign. Get store listing IDs from your dashboard settings. Allows targeting different store URLs per platform (iOS/Android). |
Note: If android_web_redirect or ios_web_redirect is provided, it will override the default store listing link for that platform within the campaign and redirect users to the specified URL instead.
Domain and Store Listing Features
Domain (domain)
The domain parameter allows you to specify which domain should be used for generating campaign links. This is useful when you have multiple domains configured for your project.
Parameter Type: string (domain name)
Behavior:
- If provided and valid: Campaign will use the specified domain for all link generation
- If not provided: Campaign will automatically use the project’s primary domain
- Must be a valid domain name that belongs to your project
Examples:
// Valid domain names
{ "domain": "app.example.com" }
{ "domain": "promo.yourapp.io" }
{ "domain": "track.mysite.com" }
// Invalid - will return error
{ "domain": "other-company.com" } // Error: Domain doesn't belong to your project
Multiple Store Listings (store_listing_ids)
The store_listing_ids parameter allows you to associate multiple store listings with a single campaign.
Parameter Type: string[] (array of store listing ID strings)
Getting Store Listing IDs:
- Navigate to your Store Listings Dashboard
- View or create store listings for your project
- Copy the store listing IDs to use in your API requests
Behavior:
- Accepts an array of store listing ID strings
- Each ID must be a non-empty string
- All store listings must belong to your project
- Cannot have multiple store listings for the same platform (only one iOS and one Android listing per campaign)
Validation:
// Valid store listing IDs
{ "store_listing_ids": ["ios-main-v1", "android-promo-v2"] }
{ "store_listing_ids": ["my-custom-listing-id"] }
// Invalid - will return errors
{ "store_listing_ids": "ios-main-v1" } // Error: "store_listing_ids must be an array of non-empty strings!"
{ "store_listing_ids": ["", "android-promo-v2"] } // Error: "store_listing_ids must be an array of non-empty strings!"
{ "store_listing_ids": ["non-existent-id"] } // Error: "Store listing(s) not found for this project"
{ "store_listing_ids": ["ios-v1", "ios-v2"] } // Error: "Cannot assign multiple store listings with the same platform to a campaign!"
Response
Standard Campaign Response:
{
"msg": "Campaign created successfully!",
"status": 201,
"data": {
"id": 123,
"name": "Summer Sale 2023",
"link": "https://app.domain.com/promo/summer25?c=summer-sale-2025",
"website": "https://www.your-website.com",
"display_id": "summer-sale-2025",
"created_at": "2023-05-01T12:00:00Z",
"android_web_redirect": null,
"ios_web_redirect": null,
"domain": "app.domain.com",
"store_listings": [
{
"store_listing_id": "android-store-v1",
"name": "Android Main Store",
"platform": "ANDROID"
}
]
}
}
Short Link Campaign Response:
{
"msg": "Campaign created successfully!",
"status": 201,
"data": {
"id": 124,
"name": "Spring Launch 2024",
"link": "https://app.domain.com/?c=spring-launch-2024",
"website": null,
"display_id": "spring-launch-2024",
"created_at": "2023-05-01T12:00:00Z",
"android_web_redirect": null,
"ios_web_redirect": null,
"domain": "app.domain.com",
"store_listings": []
}
}
Response Properties
| Property | Type | Description |
|---|
id | number | Unique numerical identifier for the campaign in the system. |
name | string | The campaign name as provided in the request. |
link | string | The generated shareable campaign URL. For short links, this will be in format https://app.domain.com/?c={display_id}. |
website | string|null | The desktop fallback URL. Will be null for short link campaigns. |
display_id | string | The campaign’s display identifier (custom or auto-generated). |
created_at | string | ISO 8601 timestamp of when the campaign was created. |
domain | string|null | The domain name used for this campaign. |
store_listings | StoreListing[] | Array of store listings associated with this campaign. Each object contains store_listing_id (string), name (string), and platform (“IOS” | “ANDROID”). |
android_web_redirect | string|null | The Android web redirect URL if specified, otherwise null. |
ios_web_redirect | string|null | The iOS web redirect URL if specified, otherwise null. |
3. Edit Campaign
Update an existing campaign.
Request
PATCH /api/v1/campaigns/:display_id
Request Body
{
"name": "campaign name",
"active": false
}
| Parameter | Type | Description |
|---|
| name | string | Optional. Name of the campaign |
| active | boolean | Optional. Campaign status |
Responses
- 200 Campaign updated successfully
- 400 Invalid request parameters
- 404 Campaign not found
- 500 Internal server error
Success Response
{
"msg": "Campaign updated successfully!",
"status": 200,
"data": {
"display_id": "TOhmGM",
"name": "campaign name",
"created_at": "2025-07-09T17:18:41.912Z",
"update_at": "2025-07-17T08:58:26.740Z",
"google": false,
"meta": false,
"meta_campaign_id": "",
"meta_web_to_app": false,
"active": false,
"default_link": true,
"attributed_users": 0
}
}
Error Responses
| HTTP Status | Message | When/Why |
|---|
| 400 | ”Campaign display ID is required!” | If the display_id param is missing |
| 400 | ”At least one field (name or active) is required for update!” | If both name and active are missing in the request body |
| 400 | ”Campaign name cannot be empty!” | If name is provided but is empty or only whitespace |
| 400 | ”Active field must be a boolean!” | If active is provided but is not a boolean |
| 404 | ”Campaign not found!” | If the campaign with the given display_id does not exist |
| 500 | ”Internal server error” | |
4. Delete Campaign
Delete an existing campaign.
Request
DELETE /api/v1/campaigns/:display_id
Responses
- 204 Campaign deleted successfully
- 400 Invalid request parameters
- 404 Campaign not found
- 500 Internal server error
Success Response
{
"msg": "Campaign deleted successfully!",
"status": 204
}
Error Responses
| HTTP Status | Message | When/Why |
|---|
| 400 | ”Campaign display ID is required!” | If the display_id param is missing |
| 404 | ”Campaign not found!” | If the campaign with the given display_id does not exist |
| 500 | ”Internal server error” | |
Best Practices
- Campaign naming: Use descriptive names that identify the purpose of the campaign
- Deep links: Ensure your deep links are properly formatted and lead to valid destinations
- Custom IDs: Use meaningful custom display IDs that are easy to recognize and remember. Duplicate ids are not allowed!
- Desktop links: Provide a
link_for_desktop_users URL to ensure desktop visitors are redirected to a relevant webpage instead of app stores.
Examples
Creating a New Campaign
fetch("https://api.linkrunner.io/api/v1/create-campaign", {
method: "POST",
headers: {
"Content-Type": "application/json",
"linkrunner-key": "YOUR-SERVER-KEY",
},
body: JSON.stringify({
name: "Product Launch 2023",
deeplink: "https://app.domain.com/promo/summer25",
link_for_desktop_users: "https://www.your-website.com",
custom_display_id: "summer-sale-2025",
}),
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
Editing a Campaign
fetch("https://api.linkrunner.io/api/v1/campaigns/TOhmGM", {
method: "PUT",
headers: {
"Content-Type": "application/json",
"linkrunner-key": "YOUR-SERVER-KEY",
},
body: JSON.stringify({
name: "Updated Campaign Name",
active: true,
}),
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
Deleting a Campaign
fetch("https://api.linkrunner.io/api/v1/campaigns/TOhmGM", {
method: "DELETE",
headers: {
"linkrunner-key": "YOUR-SERVER-KEY",
},
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
Error Handling
The API will return appropriate HTTP status codes along with error messages when issues occur. Common errors across all endpoints include:
- 400 Bad Request: Missing required parameters or invalid input
- 401 Unauthorized: API key is required or invalid
- 404 Not Found: Campaign not found
- 429 Too Many Requests: You’ve exceeded the rate limit, please try again later
- 500 Internal Server Error: Contact support if this persists
Specific error responses for each endpoint are detailed in their respective sections above.
Domain and Store Listing Specific Errors
| Status Code | Error Message | Description |
|---|
| 400 | ”Domain not found in project” | The specified domain name doesn’t exist or isn’t in your project |
| 400 | ”store_listing_ids must be an array of non-empty strings!“ | store_listing_ids parameter is not an array or contains empty strings |
| 400 | ”Store listing(s) not found for this project: “ | One or more store listing IDs don’t exist in your project |
| 400 | ”Cannot assign multiple store listings with the same platform to a campaign!” | Attempting to add more than one iOS or Android store listing |
For any help please reach out to support@linkrunner.io