Skip to main content

Data Export

Export your analytics for reporting, spreadsheets, BI tools or your own records.

What you can export​

WhatWhereFormat
Your whole workspaceDashboard: Settings → ExportLinkForty bundle
A summary of a link's analyticsDashboard: Analytics → Export CSVCSV
In-app eventsDashboard: Events → Export CSV, or the APICSV, JSON
Raw click eventsAPI: GET /api/analytics/exportJSON, CSV
Your linksAPI: GET /api/linksJSON

Exports contain the data your plan retains: 7 days of raw clicks on Free, 90 on Pro, 180 on Business and 365 on Unlimited. Owners, admins and members can export; viewers can't. API requests use an API key and count toward your plan's rate limits.

Your whole workspace​

Settings → Export → Download export downloads the workspace's links, templates, clicks, installs, in-app events and webhooks in one file, for the period your plan keeps. Owners and admins can download it.

The file is a LinkForty bundle: gzipped, newline-delimited JSON with a checksum. A self-hosted LinkForty server imports it whole:

DATABASE_URL=postgres://... npx linkforty import linkforty-acme-2026-10-15.lfbundle --dry-run   # check first
DATABASE_URL=postgres://... npx linkforty import linkforty-acme-2026-10-15.lfbundle
  • Ids are kept, so links, clicks and installs stay connected, and your apps keep the install ids they already have.
  • Webhook signing secrets aren't included. The import issues new ones and prints them.
  • Some workspace data isn't in the bundle, because it has no equivalent on a self-hosted server:
    • team members and roles;
    • projects and custom domains;
    • brand kit and social preview cards;
    • web pixel events;
    • billing.
  • The file contains every click's IP address and user agent. Store it with the same care as your database.

From the dashboard​

Analytics summary​

On the Analytics page, pick a link (or all links) and a time range, then click Export CSV. The file holds what the page shows:

  • summary metrics: total clicks, unique clicks, unique rate and average daily clicks;
  • clicks per day;
  • clicks by country, device and platform.

It is a report, not raw data. For one row per click, use the API.

In-app events​

On the Events page, click Export CSV to download the events your apps have tracked, filtered as the page is.

Raw click events​

GET /api/analytics/export returns one row per click, newest first, a page at a time.

curl "https://api.linkforty.com/api/analytics/export?startDate=2026-03-01&endDate=2026-03-31&limit=1000" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"

Query parameters

ParameterTypeDefaultDescription
startDateISO date or date-timenoneClicks at or after this time
endDateISO date or date-timenoneClicks at or before this time
linkIdUUIDall linksOnly this link's clicks
formatjson or csvjsonResponse format
limit1–10,0001,000Clicks per page
offsetnumber0Clicks to skip, for the next page

Without startDate and endDate, the export covers all the clicks your plan retains. The export includes links created in the dashboard and through the links API; links created by the mobile SDKs aren't included.

JSON response

{
"data": [
{
"id": "0b9d7c1e-5f3a-4c2b-9a8e-1d2c3b4a5f60",
"linkId": "6a1f0c2e-3b4d-4e5f-8a9b-0c1d2e3f4a5b",
"shortCode": "spring24",
"linkTitle": "Spring Sale",
"clickedAt": "2026-03-15T14:23:12.000Z",
"ipAddress": "203.0.113.24",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) ...",
"deviceType": "ios",
"platform": "iOS",
"countryCode": "US",
"countryName": "United States",
"region": "California",
"city": "San Francisco",
"timezone": "America/Los_Angeles",
"latitude": 37.7749,
"longitude": -122.4194,
"utmSource": "instagram",
"utmMedium": "social",
"utmCampaign": "spring-sale",
"referrer": "https://www.instagram.com/",
"linkParams": { "fbclid": "IwAR..." },
"isBot": false
}
],
"pagination": { "total": 5432, "limit": 1000, "offset": 0, "hasMore": true }
}

CSV response. With format=csv, the response is a file download with one header row and one row per click, using the same field names. linkParams is written as JSON, and values containing commas, quotes or line breaks are quoted.

Fields​

FieldDescription
idClick ID
linkId, shortCode, linkTitleThe link that was clicked
clickedAtWhen the click happened (UTC)
ipAddress, userAgentThe visitor's IP address and browser user agent
deviceType, platformDevice and platform detected from the user agent
countryCode, countryName, region, city, timezone, latitude, longitudeLocation from the IP address
utmSource, utmMedium, utmCampaignUTM parameters on the click
referrerThe referring page, when the browser sent one
linkParamsOther query parameters the click arrived with, such as fbclid or gclid, or null
isBotWhether the click came from a bot or link previewer

Fetching every page​

async function exportAllClicks(startDate: string, endDate: string) {
const clicks = [];
let offset = 0;
const limit = 10000;

while (true) {
const response = await fetch(
`https://api.linkforty.com/api/analytics/export?startDate=${startDate}&endDate=${endDate}&limit=${limit}&offset=${offset}`,
{ headers: { Authorization: `Bearer ${process.env.LINKFORTY_API_KEY}` } }
);
const page = await response.json();
clicks.push(...page.data);
if (!page.pagination.hasMore) return clicks;
offset += limit;
}
}

New clicks arrive while you page, and pages are newest first, so for a stable export pass an endDate in the past.

In-app events​

GET /api/analytics/events/export returns the events your apps tracked through the SDK, newest first.

ParameterDefaultDescription
days30How many days back to include
eventNameall eventsOnly this event
formatjsonjson or csv
limit, offset1,000, 0Paging, as for clicks

Each event has id, eventName, eventData, eventTimestamp, installId, linkId, linkShortCode and linkTitle.

GET /api/links lists your workspace's links, 100 per page at most. See List All Links for parameters and fields.

Troubleshooting​

The export is empty. Check that the link has clicks in the date range and that the range falls within your plan's retention. Dates are compared in UTC.

Fewer rows than total. total counts every matching click; each response holds at most limit of them. Keep requesting with a larger offset until hasMore is false.

Garbled characters in a spreadsheet. The CSV is UTF-8. In Excel, use Data → From Text/CSV and choose UTF-8.