Base URL
Authentication
All API requests require authentication. Include your server key in the request headers.Error Responses
- 401 Unauthorized
"Unauthorized access."- Missing or invalid API key
- 429 Too Many Requests
- Message:
"Rate limit exceeded. Please try again later." - Cause: You’ve exceeded the rate limit of 30 requests per second.
- Message:
Rate Limit Details
- Rate: 30 requests per second
- Status code on limit exceeded: 429 (Too Many Requests)
Authentication
All API requests require authentication using an API key. You must include this key in the header of every request.API Key Header
Include the following header in all API requests:YOUR_API_KEY with your actual API key. (Refer instructions below)
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-keyheader for all API requests
Endpoints
1. List Campaigns
Retrieve a paginated list of campaigns with optional filtering by status or specific link.Request
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| filter | string | No | Filter campaigns by status. Options: ACTIVE, INACTIVE, ALL (default: ALL) |
| channel | string | No | Filter campaigns by advertising channel/network. Options: GOOGLE, META, TIKTOK, APPLE_SEARCH_ADS, or any affiliate name (case-insensitive). For affiliates, use underscores for spaces (e.g., AFFILIATE_EXAMPLE for “affiliate example”) |
| domain | string | No | Filter campaigns by domain name (e.g., app.example.com). Only returns campaigns associated with the specified domain. |
| link | string | No | Filter campaigns by a specific link URL. The system will extract the campaign from the provided link. |
| page | number | No | The page number to retrieve. Must be a positive integer. (default: 1) |
| limit | number | No | The number of campaigns to return per page. Must be between 1 and 1000. (default: 100, max: 1000) |
Channel Filter Behavior
| Value | Behavior |
|---|---|
GOOGLE | Returns campaigns where google = true |
META | Returns campaigns where meta = true |
TIKTOK | Returns campaigns linked to a TikTok ad network |
APPLE_SEARCH_ADS | Returns campaigns linked to Apple Search Ads ad network |
AFFILIATE_EXAMPLE | Returns campaigns linked to an affiliate named “affiliate example”. Replace spaces with underscores. |
| (empty/invalid) | No channel filter applied (returns all channels) |
- Affiliate names should use underscores instead of spaces
- Example: If the affiliate is named “affiliate example”, use
channel=AFFILIATE_EXAMPLE - Channel names are case-insensitive
Pagination
Pagination is automatically applied to all requests with the following defaults:- Default page: 1
- Default limit: 100 campaigns per page
- Maximum limit: 1000 campaigns per page
Example Requests
- Basic Request (returns first 100 campaigns):
- Filter Active Campaigns with Pagination:
- Get Campaign by Link:
- All Campaigns with Custom Limit:
- Filter by Channel (Google):
- Filter by Channel (Meta):
- Filter by Channel (TikTok):
- Combine Channel with Other Filters:
Response
Standard Response (no channel filter):Error Responses
| Status Code | Error Message | Description |
|---|---|---|
| 400 | ”Invalid request parameters.” | Invalid link, domain not found, or campaign not found |
| 400 | ”Invalid domain ''. Domain not found for this project.” | Specified domain does not exist or doesn’t belong to your project |
| 400 | ”Invalid channel ''. Channel not found.” | Specified channel/ad network does not exist |
| 401 | ”Unauthorized access.” | Missing or invalid API key |
| 422 | ”Invalid page number ''. Page must be a positive integer…” | Page parameter is not a positive integer |
| 422 | ”Invalid limit ''. Limit must be between 1 and 1000…” | Limit parameter is not between 1 and 1000 |
| 422 | ”Limit exceeds maximum allowed value of 1000…” | Limit exceeds 1000 |
TypeScript Types
2. Get Attributed Users
Retrieve a paginated list of users attributed to a specific campaign with optional time range filtering.Request
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| display_id | string | Yes | The display ID of the campaign to retrieve attributed users for |
| start_timestamp | string | No | Start time in ISO 8601 format (e.g., “2025-06-23T10:29:26.074”) |
| end_timestamp | string | No | End time in ISO 8601 format (e.g., “2025-06-23T10:29:26.074”) |
| timezone | string | No | IANA timezone identifier. See IANA Time Zone Database (default: UTC) |
| page | number | No | The page number to retrieve. Must be a positive integer. (default: 1) |
| limit | number | No | The number of users to return per page. Must be between 1 and 1000. (default: 50, max: 1000) |
Pagination
Pagination is automatically applied to all requests with the following defaults:- Default page: 1
- Default limit: 50 users per page
- Maximum limit: 1000 users per page
Time Format Details
- ISO 8601 Format: Use
YYYY-MM-DDThh:mm:ss.SSSformat (e.g.,2025-06-23T10:29:26.074) - IANA Timezone: Standard timezone identifiers like
America/New_York,Asia/Tokyo,Asia/Kolkata - Default Timezone: UTC is used when timezone parameter is not provided
- Time Range: Both start and end timestamps are optional; you can filter by start time only, end time only, or both
Example Requests
- Basic Request (returns first 50 users):
- With Time Range and Timezone:
- With Pagination:
- With All Parameters:
Response
Error Responses
| Status Code | Error Message | Description |
|---|---|---|
| 400 | ”Invalid timezone format.” | Invalid IANA timezone identifier provided |
| 400 | ”Invalid timestamp format.” | Invalid start or end timestamp format |
| 401 | ”Authentication failed.” | Invalid or missing API key |
| 404 | ”Resource not found.” | Campaign does not exist in the project |
| 422 | ”Required parameter missing.” | Missing required display_id parameter |
| 422 | ”Invalid page number ''. Page must be a positive integer…” | Page parameter is not a positive integer |
| 422 | ”Invalid limit ''. Limit must be between 1 and 1000…” | Limit parameter is not between 1 and 1000 |
| 422 | ”Limit exceeds maximum allowed value of 1000…” | Limit exceeds 1000 |
TypeScript Types
Campaign Domain and Store Listings
Domain Field
Each campaign response now includes adomain field that indicates which domain is being used for the campaign links:
- Type:
string | null - Description: The domain name used to generate campaign links
- Behavior: If the campaign has a specific domain assigned, it will be shown. Otherwise, it falls back to the project’s primary domain.
- Example:
"yourdomain.com"or"promo.example.com"
Store Listings Array
Campaigns can now include multiple store listings in the response. Each store listing represents a different App Store or Play Store configuration. Store Listing Object Structure:| Field | Type | Description |
|---|---|---|
store_listing_id | string | Unique identifier for the store listing |
name | string | Display name of the store listing |
platform | ”IOS” | “ANDROID” | Platform this store listing is for (iOS or Android) |
- Create and manage store listings in your Dashboard Settings
- Each store listing has a unique
store_listing_idthat you use when creating campaigns - Store listings allow you to configure different App Store/Play Store parameters per campaign
3. Get Attribution Result
Retrieve attribution data for a specific user or device. This endpoint returns campaign and ad network information for attributed installs.Request
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| device_identifier | string | Conditional | The unique device ID to look up. For Android, this is the GAID (Google Advertising ID). For iOS, this is the IDFA (Identifier for Advertisers). Required if user_id is not provided. |
| user_id | string | Conditional | The user ID to look up. Required if device_identifier is not provided. |
device_identifier or user_id must be provided. If both are provided and they match different installs, the user_id based result will be returned as it’s more reliable.
Example Requests
- Get Attribution by Device Identifier:
- Get Attribution by User ID:
- Get Attribution with Both Identifiers:
Response
Success Response (200):204 No Content status with an empty response body.
Response Properties
| Property | Type | Description |
|---|---|---|
campaign_name | string|null | The name of the campaign that the user was attributed to |
display_id | string|null | The campaign’s display identifier |
deeplink | string|null | The deeplink URL associated with the campaign |
domain_name | string|null | The domain name used for the campaign |
ad_set_id | string|null | The ad set ID from the advertising platform (e.g., Meta Ad Set ID) |
ad_set_name | string|null | The ad set name from the advertising platform |
ad_creative_id | string|null | The ad creative ID from the advertising platform |
ad_creative_name | string|null | The ad creative name from the advertising platform |
keyword_id | string|null | The keyword ID (primarily for Apple Search Ads campaigns) |
keyword_name | string|null | The keyword name (primarily for Apple Search Ads campaigns) |
ad_network | string|null | The advertising network. Can be GOOGLE, META, TIKTOK, APPLE_SEARCH_ADS, or other network codes |
attribution_type | ”ORGANIC”|“INORGANIC” |
Error Responses
| Status Code | Error Message | Description |
|---|---|---|
| 400 | ”Either device_identifier or user_id is required.” | Neither device_identifier nor user_id was provided |
| 401 | ”Unauthorized access.” | Missing or invalid API key |
| 204 | No Content | No attribution data found for the provided identifier |
TypeScript Types
Notes
- All timestamps are in ISO 8601 format.
- The
device_dataobject contains detailed information about the user’s device. - The
activefield in the campaign data indicates whether the campaign is currently active. - The
attributed_usersfield in the campaign data shows the number of users attributed to that campaign. - User data provided in this documentation is randomized for privacy reasons. Actual API responses will contain real user data.
- The TypeScript types provided are based on the example responses
- The
domainfield shows which domain is being used for campaign link generation - The
store_listingsarray contains store listing configurations associated with the campaign - Store listings can be created and managed in the Dashboard Settings
- The
get-attribution-resultendpoint returns a 204 status code with no body when no attribution data is found