Analytics Dashboard
Understand your link performance with comprehensive click tracking and analytics.
Overview
LinkForty's analytics dashboard provides real-time insights into:
- Click metrics - Total and unique clicks
- Geographic data - Country, city, region distribution
- Device breakdown - Mobile, desktop, tablet
- Platform analysis - iOS, Android, Windows
- Traffic sources - UTM tracking and referrers
- Time patterns - Clicks by hour and date
- Top performers - Best-performing links
Looking for event tracking and conversion analytics? See the Events & Conversions guide.
Dashboard Views
Organization Overview
View aggregated analytics across all links in your organization.
Access: Dashboard home page or Analytics → Overview
API Endpoint:
curl "https://api.linkforty.com/api/analytics/overview?days=30" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"
Key Metrics:
- Total Clicks
- Unique Visitors
- Top Performing Links
- Geographic Distribution
- Device & Platform Breakdown
Link-Specific Analytics
Deep-dive into individual link performance.
Access: Click any link → Analytics tab
API Endpoint:
curl "https://api.linkforty.com/api/analytics/links/{linkId}?days=30" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"
See: Link Analytics API Reference
Project Analytics
Aggregate analytics for all links in a project.
Access: Projects → Select project → Analytics tab
API Endpoint:
curl "https://api.linkforty.com/api/analytics/projects/{projectId}?days=30" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"
See: Projects Guide
Time Filtering
All analytics views support custom time ranges.
Available Ranges:
- Last 24 hours
- Last 7 days
- Last 30 days (default)
- Last 90 days
- Last 365 days
- Custom date range
API Parameter:
# Last 7 days
curl "https://api.linkforty.com/api/analytics/overview?days=7"
# Last 90 days
curl "https://api.linkforty.com/api/analytics/overview?days=90"
Analytics Metrics
Click Metrics
Total Clicks: Total number of times your links were clicked
Unique Clicks: Number of unique visitors (deduplicated by IP address)
Click-Through Rate (CTR):
CTR = (Unique Clicks / Total Clicks) × 100
Example:
- Total Clicks: 1,248
- Unique Clicks: 892
- CTR: 71.5%
This indicates 71.5% of clicks came from unique visitors.
Geographic Analytics
By Country:
{
"countryCode": "US",
"country": "United States",
"clicks": 523
}
By City:
{
"city": "New York",
"countryCode": "US",
"region": "NY",
"clicks": 142
}
By Region/State:
{
"region": "California",
"countryCode": "US",
"clicks": 256
}
By Timezone:
{
"timezone": "America/New_York",
"clicks": 312
}
Device & Platform Analytics
Device Type:
- Mobile - Smartphones
- Desktop - Laptop and desktop computers
- Tablet - iPads and Android tablets
Platform:
- iOS - iPhone, iPad
- Android - Android phones and tablets
- Windows - Windows PCs
- macOS - Mac computers
- Linux - Linux systems
Browser:
- Chrome, Safari, Firefox, Edge, etc.
Example:
{
"clicksByDevice": [
{ "device": "mobile", "clicks": 742 },
{ "device": "desktop", "clicks": 398 },
{ "device": "tablet", "clicks": 108 }
],
"clicksByPlatform": [
{ "platform": "iOS", "clicks": 623 },
{ "platform": "Android", "clicks": 425 },
{ "platform": "Windows", "clicks": 200 }
]
}
Traffic Source Analytics
UTM Parameters:
Track campaign performance with UTM parameters.
{
"clicksByUtmSource": [
{ "source": "instagram", "clicks": 523 },
{ "source": "email", "clicks": 312 },
{ "source": "Direct", "clicks": 187 }
],
"clicksByUtmMedium": [
{ "medium": "social", "clicks": 642 },
{ "medium": "email", "clicks": 312 },
{ "medium": "None", "clicks": 187 }
],
"clicksByUtmCampaign": [
{ "campaign": "spring-sale", "clicks": 823 },
{ "campaign": "product-launch", "clicks": 425 }
]
}
Referrer Analysis:
See where traffic is coming from.
{
"clicksByReferrer": [
{ "source": "Instagram", "clicks": 523 },
{ "source": "Facebook", "clicks": 312 },
{ "source": "Direct", "clicks": 187 },
{ "source": "Google", "clicks": 142 }
]
}
Time-Based Analytics
Clicks by Date:
{
"clicksByDate": [
{ "date": "2024-03-15", "clicks": 245 },
{ "date": "2024-03-14", "clicks": 198 },
{ "date": "2024-03-13", "clicks": 223 }
]
}
Clicks by Hour:
{
"clicksByHour": [
{ "hour": 14, "clicks": 145 }, // 2 PM
{ "hour": 15, "clicks": 132 }, // 3 PM
{ "hour": 10, "clicks": 118 } // 10 AM
]
}
Use this to identify peak traffic times.
Top Performing Links
See which links drive the most traffic.
{
"topLinks": [
{
"id": "link_abc123",
"shortCode": "spring24",
"title": "Spring Sale 2024",
"originalUrl": "https://shop.example.com/sale",
"totalClicks": 1248,
"uniqueClicks": 892
},
{
"id": "link_def456",
"shortCode": "newprod",
"title": "Product Launch",
"originalUrl": "https://shop.example.com/new",
"totalClicks": 823,
"uniqueClicks": 612
}
]
}
Recent Activity
View real-time click stream.
curl "https://api.linkforty.com/api/analytics/recent?limit=20" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"
Response:
[
{
"id": "click_xyz789",
"linkId": "link_abc123",
"shortCode": "spring24",
"linkTitle": "Spring Sale 2024",
"clickedAt": "2024-03-15T14:23:12Z",
"deviceType": "mobile",
"platform": "iOS",
"countryCode": "US",
"city": "New York",
"utmSource": "instagram",
"utmMedium": "social",
"utmCampaign": "spring-sale"
}
]
Weekly Report Email
Every Monday at 9 AM Eastern, LinkForty emails you a report on the week that just ended, for each workspace you belong to — in one email, not one per workspace. It covers:
- Clicks, unique visitors, app installs and site sessions, each against the previous week
- Clicks by day, with the best day called out
- Top links with their share of the week's traffic, and how many links got none
- Where clicks came from — source, country and device
- App installs by platform and how many were attributed to a click (when the SDK is reporting)
- Events and revenue (when your app or site sends them)
- One recommended action, chosen from the data — for example, turning on event tracking when installs are being counted but nothing after the install is visible
Workspaces with nothing to report that week are left out, and the demo workspace created at sign-up never gets one. Turn the report off or on under Settings → Notifications.
Monthly Report Email
On the 1st of each month at 9 AM Eastern you also get a monthly report covering the calendar month that just ended, in the same format at month scale: month-over-month changes, clicks by week, and — when your app or site sends them — events and revenue for the month. It is available on every plan, including plans whose dashboard shows a shorter history; the report is where a free workspace sees its full month. The same Settings → Notifications switch controls it.
The sentences above each section of the monthly report — the headline, the one-line reading of each chart, and the What to do next list — are written from the report's own numbers. Every figure in those sentences is checked against the report before it is sent; if any does not match, the report falls back to a plain rule-based reading of the same numbers. Nothing in the narrative is a number the report does not contain.
Reading the report in the dashboard
Every monthly report is also a page: Reports in the sidebar, or the View the full report button in the email. The page shows the same numbers the email carried — a finished month is stored the moment it is generated, so what you open later is what you were sent, not a re-count. The current month is shown live and updates as the month runs. Use Print / Save as PDF for a copy to forward; the dashboard chrome is left out of the print. Workspace owners can Regenerate a finished month if events arrived after the 1st, which replaces the stored copy.
Data Export
- Export CSV on the Analytics page downloads a summary of the link and time range you're viewing: totals, clicks per day, and clicks by country, device and platform.
- For one row per click, use
GET /api/analytics/exportwith an API key.
See Data Export for parameters, fields and paging.
TypeScript Examples
1. Display Dashboard Overview
interface AnalyticsOverview {
totalClicks: number;
uniqueClicks: number;
clicksByDate: Array<{ date: string; clicks: number }>;
clicksByCountry: Array<{ countryCode: string; country: string; clicks: number }>;
clicksByDevice: Array<{ device: string; clicks: number }>;
topLinks: Array<{
id: string;
shortCode: string;
title: string;
totalClicks: number;
uniqueClicks: number;
}>;
}
async function getDashboardOverview(days: number = 30): Promise<AnalyticsOverview> {
const response = await fetch(
`https://api.linkforty.com/api/analytics/overview?days=${days}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
return response.json();
}
// Usage
const overview = await getDashboardOverview(7);
console.log(`Last 7 Days Overview`);
console.log(`Total Clicks: ${overview.totalClicks.toLocaleString()}`);
console.log(`Unique Visitors: ${overview.uniqueClicks.toLocaleString()}`);
console.log(`\nTop Link: ${overview.topLinks[0].title}`);
console.log(` Clicks: ${overview.topLinks[0].totalClicks.toLocaleString()}`);
console.log(`\nTop Country: ${overview.clicksByCountry[0].country}`);
console.log(` Clicks: ${overview.clicksByCountry[0].clicks.toLocaleString()}`);
2. Calculate Growth Rate
async function calculateGrowthRate() {
const thisWeek = await fetch(
'https://api.linkforty.com/api/analytics/overview?days=7',
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
const lastWeek = await fetch(
'https://api.linkforty.com/api/analytics/overview?days=14',
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
const thisWeekClicks = thisWeek.totalClicks;
const lastWeekClicks = lastWeek.totalClicks - thisWeekClicks;
const growth = ((thisWeekClicks - lastWeekClicks) / lastWeekClicks) * 100;
return {
thisWeek: thisWeekClicks,
lastWeek: lastWeekClicks,
growth: growth.toFixed(1) + '%',
isGrowing: growth > 0,
trend: growth > 0 ? 'Growing' : 'Declining',
};
}
// Usage
const growth = await calculateGrowthRate();
console.log(`This week: ${growth.thisWeek} clicks`);
console.log(`Last week: ${growth.lastWeek} clicks`);
console.log(`Growth: ${growth.growth} ${growth.trend}`);
3. Export and Analyze Data
async function exportAndAnalyze(startDate: string, endDate: string) {
const response = await fetch(
`https://api.linkforty.com/api/analytics/export?startDate=${startDate}&endDate=${endDate}&format=json&limit=10000`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const { data, pagination } = await response.json();
// Analyze mobile vs desktop (deviceType is ios, android or web)
const mobile = data.filter(click => click.deviceType === 'ios' || click.deviceType === 'android').length;
const desktop = data.filter(click => click.deviceType === 'web').length;
const mobilePercentage = ((mobile / data.length) * 100).toFixed(1);
// Find peak hour
const hourCounts = data.reduce((acc, click) => {
const hour = new Date(click.clickedAt).getHours();
acc[hour] = (acc[hour] || 0) + 1;
return acc;
}, {} as Record<number, number>);
const peakHour = Object.entries(hourCounts)
.sort((a, b) => b[1] - a[1])[0];
return {
totalRecords: data.length,
mobilePercentage: mobilePercentage + '%',
desktopPercentage: ((desktop / data.length) * 100).toFixed(1) + '%',
peakHour: `${peakHour[0]}:00 (${peakHour[1]} clicks)`,
hasMore: pagination.hasMore,
};
}
4. Track Campaign Performance
interface CampaignMetrics {
campaign: string;
clicks: number;
uniqueClicks: number;
countries: number;
mobilePercentage: string;
}
async function getCampaignMetrics(linkId: string): Promise<CampaignMetrics> {
const analytics = await fetch(
`https://api.linkforty.com/api/analytics/links/${linkId}?days=30`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
const link = await fetch(
`https://api.linkforty.com/api/links/${linkId}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
const mobileClicks = analytics.clicksByDevice.find(d => d.device === 'mobile')?.clicks || 0;
const mobilePercentage = ((mobileClicks / analytics.totalClicks) * 100).toFixed(1);
return {
campaign: link.title || link.shortCode,
clicks: analytics.totalClicks,
uniqueClicks: analytics.uniqueClicks,
countries: analytics.clicksByCountry.length,
mobilePercentage: mobilePercentage + '%',
};
}
// Usage
const metrics = await getCampaignMetrics('link_abc123');
console.table([metrics]);
5. Generate Weekly Report
async function generateWeeklyReport() {
const overview = await getDashboardOverview(7);
const report = {
period: 'Last 7 Days',
summary: {
totalClicks: overview.totalClicks,
uniqueVisitors: overview.uniqueClicks,
avgClicksPerDay: (overview.totalClicks / 7).toFixed(1),
},
geographic: {
topCountry: overview.clicksByCountry[0],
countriesReached: overview.clicksByCountry.length,
},
devices: {
mobile: overview.clicksByDevice.find(d => d.device === 'mobile')?.clicks || 0,
desktop: overview.clicksByDevice.find(d => d.device === 'desktop')?.clicks || 0,
tablet: overview.clicksByDevice.find(d => d.device === 'tablet')?.clicks || 0,
},
topPerformers: overview.topLinks.slice(0, 5).map(link => ({
title: link.title,
clicks: link.totalClicks,
shortCode: link.shortCode,
})),
};
console.log(JSON.stringify(report, null, 2));
return report;
}
Understanding Your Data
What is a "Unique Click"?
A unique click is deduplicated by IP address. If the same IP clicks your link 5 times, it counts as:
- Total Clicks: 5
- Unique Clicks: 1
Note: This is an approximation. Multiple users behind the same router/proxy will share an IP.
Why do some clicks show "Unknown"?
Geographic data:
- VPN users hide their location
- Some IPs aren't in geolocation databases
- Privacy-focused browsers block location tracking
Device/Platform data:
- Rare or custom user-agents
- Browsers that spoof user-agent strings
- Bots and automated traffic
How accurate is geolocation?
Country: ~95% accurate City: ~70% accurate Coordinates: ~80% accurate
Accuracy depends on IP geolocation database quality. Mobile users on cellular networks may show as neighboring cities.
What counts as a "click"?
A click is logged when:
- User visits your short link
- Request reaches LinkForty servers
- User is redirected to destination
Not counted:
- Bots (filtered by user-agent)
- Prefetch requests from browsers
- Failed requests (404, errors)
Best Practices
1. Review Analytics Regularly
Recommended Schedule:
- Daily: Check recent activity and top links
- Weekly: Review growth trends and campaign performance
- Monthly: Export data and analyze patterns
2. Use UTM Parameters
Track campaign sources properly:
curl -X POST https://api.linkforty.com/api/links \
-d '{
"originalUrl": "https://shop.com/sale",
"utmParameters": {
"source": "instagram",
"medium": "social",
"campaign": "spring-sale",
"content": "story-1"
}
}'
See: UTM Parameters Guide
3. Set Up Projects
Organize links by campaign for better analytics:
Project: Spring Sale 2024
├── Instagram Story Link
├── Email Newsletter Link
├── Facebook Ad Link
└── Twitter Post Link
See: Projects Guide
4. Monitor Geographic Trends
If you notice unexpected geographic distribution:
- Check for bot traffic
- Verify campaign targeting
- Look for viral sharing patterns
5. Optimize for Peak Hours
Use "Clicks by Hour" data to schedule:
- Email sends
- Social media posts
- Ad campaigns
Troubleshooting
"No analytics data"
Possible causes:
- Link hasn't been clicked yet
- Time filter too narrow (try 30 days)
- Link created very recently
Fix:
- Share link to generate clicks
- Expand time range
- Wait 1-2 minutes for data processing
Analytics seem delayed
Cause: Analytics update in near real-time (1-2 minute delay)
Fix: Refresh dashboard after a minute
Duplicate clicks showing
Cause: Same user clicking multiple times
Solution: Use "Unique Clicks" metric instead of "Total Clicks"
Geographic data missing
Cause: VPNs, proxies, or missing IP data
Expected: 5-10% of clicks may have unknown location
Related Guides
- Link Analytics API - API reference
- Creating Links - Link setup
- UTM Parameters - Campaign tracking
- Projects - Organizing links
Next Steps
- Review your current analytics
- Set up UTM tracking for campaigns
- Organize links into projects
- Export data for external analysis
- Schedule regular analytics reviews