Base URL
Authentication
Pass your project’s server key in thelinkrunner-key header. This is the same key used by other /api/v1 endpoints. Find it under Settings → Data APIs:
Postman collection
Download the Postman collection. Import it into Postman, set thelinkrunner_key collection variable to your key, and run any request.
Rate limit and freshness
- 1 request per minute per API key (
429withRetry-After: 60when exceeded). - 30 req/sec per source IP (shared across all
/api/v1endpoints). - Underlying analytics refresh on roughly the same cadence, so cache responses for at least 60 seconds.
Endpoint
Example request
- cURL
- Google Apps Script
Response
pagination.total is the number of campaigns matching your filters, and pages is total / limit rounded up.
Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
from, to | string | (none) | YYYY-MM-DD, inclusive, in your project’s timezone. start_date / end_date are accepted aliases. Sets the metrics window; never filters the campaign list (see note below). |
active | string | (all) | true or false. |
network | string | (all) | meta, google, apple_search_ads, tiktok, snapchat, sandbox_ads, etc. |
meta_account_id | number | (none) | Restrict to a single Meta network account. |
platform | string | (both) | ios or android. |
search | string | (none) | Matches name, display ID, domain, deeplink, or full tracking URL. |
view | string | user_acquisition | user_acquisition (new users: installs, cost_per_install) or retargeting (re-engaged users: reinstalls, reengagements, cost_per_reinstall). |
sort_field | string | installs | clicks, installs, signups, revenue, spend, created_at, uninstalls, conversion, suspicious_installs, roas. |
sort_order | string | descending | ascending or descending. |
page | number | 1 | 1-indexed. |
limit | number | 10 | Max 100. Larger values return 422. |
from and to choose the window over which metrics (clicks, installs, revenue, spend) are computed. They do not filter which campaigns are returned: a campaign created after to still appears, with zeros for the window. This matches the dashboard campaign table, where the date picker changes the numbers, not the list. To fetch only campaigns created in a range, see Troubleshooting.events, payment_events, unique_user_events, cost_per_event, and active_users.
Configurable columns
By default the response includes:- All custom events your project tracks (under
custom_events), each as a total occurrence count. - All payment events (under
payment_events), each as a total count and total amount. active_userswith a 7-day window.
| Parameter | Effect | Example |
|---|---|---|
events | Whitelist custom_events to only these names. Smaller payload, faster query. | events=Purchase,AddToCart |
payment_events | Whitelist payment_events to only these types. | payment_events=PURCHASE |
unique_user_events | Count distinct users (unique_count) for these events instead of total occurrences. Works for both custom and payment events. | unique_user_events=Purchase |
cost_per_event | Include cost_per_custom_events / cost_per_payment_events for these event names. Off by default. | cost_per_event=Purchase,PURCHASE |
active_users | Override the active-users window (in days). | active_users=14 |
Example: revenue events with cost-per and 14-day active users
custom_events.Purchasecontaining aunique_count(distinct paying users) instead ofcount.custom_events.AddToCartwith the standard totalcount.cost_per_custom_events.Purchase(spend ÷ Purchase count).active_userscomputed over a 14-day window.
Errors
| Status | When |
|---|---|
401 | Missing or invalid linkrunner-key. |
402 | Billing account suspended. Body includes payment_link. |
422 | limit is non-numeric, less than 1, or greater than 100. |
429 | Rate limit exceeded. |
500 | Unexpected server error. Retry after a short backoff. |
Troubleshooting
Campaigns created outside my from/to range are in the response
Campaigns created outside my from/to range are in the response
This is expected.
from and to set the metrics window; they never remove campaigns from the list. To keep only campaigns created in a range, request sort_field=created_at&sort_order=descending, then drop rows client-side once created_at falls before from.429 Too Many Requests on the second call
429 Too Many Requests on the second call
The limit is 1 request per minute per API key. Honor the
Retry-After: 60 header and cache responses for at least 60 seconds. The underlying analytics refresh on roughly the same cadence, so polling faster returns the same data.Numbers don't match the dashboard
Numbers don't match the dashboard
Compare the same date range and the same
view (user_acquisition vs retargeting). The API interprets from and to in your project’s timezone, exactly like the dashboard date picker. If you are doing math on the values, remember they are formatted strings (see the warning under Response).