Skip to main content

Get Link

Retrieve details for a single link or list all links.

GET /api/links/:id

Retrieve detailed information about a specific link, including click count.

Authentication

  • Core (Self-Hosted): Pass userId as a query parameter. See Authentication.
  • Cloud: Requires a valid API key in the Authorization header. See Authentication.

Path Parameters

ParameterTypeRequiredDescription
idstring (UUID)YesLink ID

Query Parameters

ParameterTypeRequiredDescription
userIdstring (UUID)Core onlyRequired for Core to identify link ownership

Response

Core response:

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"short_code": "abc123",
"original_url": "https://example.com/products/123",
"title": "Wireless Headphones Product Page",
"description": "Premium noise-cancelling headphones",
"ios_app_store_url": "https://apps.apple.com/app/id123456789",
"android_app_store_url": "https://play.google.com/store/apps/details?id=com.example.app",
"web_fallback_url": null,
"utm_parameters": {
"utm_source": "instagram",
"utm_medium": "social",
"utm_campaign": "spring-sale-2024"
},
"targeting_rules": {
"countries": ["US", "CA"],
"platforms": ["ios", "android"],
"languages": ["en"]
},
"attribution_window_hours": 168,
"expires_at": null,
"is_active": true,
"click_count": 1248,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-20T14:22:00Z"
}

Cloud response includes additional fields (organization_id, project_id, template_id, template_slug):

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"userId": "user_123",
"organizationId": "org_456",
"projectId": "proj_789",
"templateId": "tmpl_abc",
"templateSlug": "instagram-campaign",
"shortCode": "abc123",
"originalUrl": "https://example.com/products/123",
"title": "Wireless Headphones Product Page",
"description": "Premium noise-cancelling headphones",
"iosUrl": "https://apps.apple.com/app/id123456789",
"androidUrl": "https://play.google.com/store/apps/details?id=com.example.app",
"webFallbackUrl": null,
"utmParameters": {
"source": "instagram",
"medium": "social",
"campaign": "spring-sale-2024",
"content": "story-swipe-up"
},
"targetingRules": {
"countries": ["US", "CA"],
"devices": ["ios", "android"],
"languages": ["en"]
},
"attributionWindowHours": 168,
"expiresAt": null,
"isActive": true,
"clickCount": 1248,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:22:00Z"
}

Example Requests

Core:

curl "https://your-domain.com/api/links/a1b2c3d4-e5f6-7890-abcd-ef1234567890?userId=550e8400-e29b-41d4-a716-446655440000"

Cloud:

curl https://api.linkforty.com/api/links/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $LINKFORTY_API_KEY"

GET /api/links

Retrieve all links belonging to a user (Core) or organization (Cloud).

Authentication

  • Core (Self-Hosted): Pass userId as a query parameter.
  • Cloud: Requires a valid API key in the Authorization header.

Query Parameters

ParameterTypeRequiredDescription
userIdstring (UUID)Core onlyRequired for Core to filter by user
projectIdstring (UUID)NoFilter links by project (Cloud only)

Response

Returns an array of link objects with click counts.

[
{
"id": "link_1",
"shortCode": "abc123",
"title": "Product A",
"originalUrl": "https://example.com/products/a",
"clickCount": 1248,
"templateSlug": "instagram-campaign",
"createdAt": "2024-01-15T10:30:00Z"
},
{
"id": "link_2",
"shortCode": "def456",
"title": "Product B",
"originalUrl": "https://example.com/products/b",
"clickCount": 892,
"templateSlug": "facebook-ads",
"createdAt": "2024-01-16T14:20:00Z"
}
]

Example Requests

Core - Get all links for a user:

curl "https://your-domain.com/api/links?userId=550e8400-e29b-41d4-a716-446655440000"

Cloud - Get all links:

curl https://api.linkforty.com/api/links \
-H "Authorization: Bearer $LINKFORTY_API_KEY"

Cloud - Filter by project:

curl "https://api.linkforty.com/api/links?projectId=proj_789" \
-H "Authorization: Bearer $LINKFORTY_API_KEY"

Sorting

Links are returned in descending order by creation date (newest first).

Error Responses

{
"statusCode": 404,
"error": "Not Found",
"message": "Link not found"
}

Possible causes:

  • Link ID doesn't exist
  • Link belongs to different organization
  • Link was deleted

Unauthorized

{
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required"
}

Possible causes:

  • Missing API key/bearer token
  • Invalid API key
  • Expired session token

Use Cases

const link = await fetch('https://api.linkforty.com/api/links/abc123', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
}).then(r => r.json());

console.log(`Link: ${link.shortCode}`);
console.log(`Clicks: ${link.clickCount}`);
console.log(`Created: ${new Date(link.createdAt).toLocaleDateString()}`);

Since the endpoint requires UUID, you'll need to list all links and filter:

const links = await fetch('https://api.linkforty.com/api/links', {
headers: { 'Authorization': `Bearer ${apiKey}` }
}).then(r => r.json());

const link = links.find(l => l.shortCode === 'abc123');
const link = await getLinkById('link_id');

if (link.clickCount > 1000) {
console.log('High-performing link!');
}

if (link.expiresAt && new Date(link.expiresAt) < new Date()) {
console.log('Link expired - needs renewal');
}
const links = await getAllLinks();

const recentLinks = links.filter(link => {
const createdDate = new Date(link.createdAt);
const weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
return createdDate > weekAgo;
});

console.log(`${recentLinks.length} links created in last 7 days`);

Best Practices

Link details rarely change, so cache them:

const linkCache = new Map();

async function getLinkWithCache(linkId: string) {
if (linkCache.has(linkId)) {
return linkCache.get(linkId);
}

const link = await fetch(`/api/links/${linkId}`, {
headers: { 'Authorization': `Bearer ${apiKey}` }
}).then(r => r.json());

linkCache.set(linkId, link);
return link;
}

2. Handle Pagination (Future)

While the current API returns all links, plan for pagination:

// Future-proof for when pagination is added
async function getAllLinksWithPagination() {
let allLinks = [];
let page = 1;
let hasMore = true;

while (hasMore) {
const response = await fetch(
`/api/links?page=${page}&limit=100`,
{ headers: { 'Authorization': `Bearer ${apiKey}` } }
);
const data = await response.json();

allLinks = allLinks.concat(data.links || data);
hasMore = data.hasMore || false;
page++;
}

return allLinks;
}

3. Filter Client-Side

For small datasets, filter in your application:

const links = await getAllLinks();

// Active links only
const activeLinks = links.filter(l => l.isActive);

// High-performing links
const topLinks = links
.filter(l => l.clickCount > 100)
.sort((a, b) => b.clickCount - a.clickCount);

// Links by campaign
const campaignLinks = links.filter(
l => l.utmParameters?.campaign === 'spring-sale-2024'
);

Guides