Skip to main content

Delete Link

Permanently remove a link and all its associated click event data.

Endpoint

DELETE /api/links/:id

Authentication

Requires authentication via:

  • Bearer token (user session)
  • API key in Authorization header

Path Parameters

ParameterTypeRequiredDescription
idstring (UUID)YesLink ID to delete

Response

{
"success": true
}

Example Request

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

Example Response

{
"success": true
}

What Gets Deleted

When you delete a link, the following data is permanently removed:

DataDeleted?Notes
Link record✅ YesComplete link configuration
Short code✅ Yesabc123 becomes available again
Click events✅ YesAll historical click analytics
QR code cache✅ YesCached QR code images
Install events⚠️ DependsIf cascade delete is configured

Warning: This action is irreversible. All analytics data for this link will be lost.

Before You Delete

Consider these alternatives:

1. Deactivate Instead

Preserve analytics while stopping new clicks:

curl -X PUT https://api.linkforty.com/api/links/abc123 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"isActive": false}'

Benefits:

  • ✅ Keeps historical data
  • ✅ Can be reactivated later
  • ✅ Analytics remain accessible

2. Set Expiration

Auto-expire on specific date:

curl -X PUT https://api.linkforty.com/api/links/abc123 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expiresAt": "2024-12-31T23:59:59Z"}'

Benefits:

  • ✅ Automatic deactivation
  • ✅ Data preserved
  • ✅ Clear lifecycle

3. Export Analytics First

Save analytics before deleting:

# 1. Export analytics
curl https://api.linkforty.com/api/analytics/links/abc123 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
> link_analytics.json

# 2. Then delete
curl -X DELETE https://api.linkforty.com/api/links/abc123 \
-H "Authorization: Bearer $LINKFORTY_API_KEY"

TypeScript Example

async function deleteLink(linkId: string): Promise<boolean> {
const response = await fetch(`https://api.linkforty.com/api/links/${linkId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${API_KEY}`,
},
});

if (!response.ok) {
throw new Error(`Failed to delete link: ${response.statusText}`);
}

const result = await response.json();
return result.success;
}

// Usage
try {
const success = await deleteLink('link_id');
console.log('Link deleted successfully');
} catch (error) {
console.error('Failed to delete:', error);
}

Safe Delete with Confirmation

async function safeDeleteLink(linkId: string, linkTitle: string) {
// Show confirmation
const confirmed = window.confirm(
`Are you sure you want to delete "${linkTitle}"?\n\n` +
`This will permanently remove:\n` +
`- Link configuration\n` +
`- All click analytics\n` +
`- Historical data\n\n` +
`This action cannot be undone.`
);

if (!confirmed) {
return false;
}

try {
await deleteLink(linkId);
return true;
} catch (error) {
alert('Failed to delete link. Please try again.');
return false;
}
}

Bulk Delete

To delete multiple links, use the Bulk Operations endpoint:

curl -X POST https://api.linkforty.com/api/links/bulk-delete \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"link_1",
"link_2",
"link_3"
]
}'

See Bulk Operations for details.

Error Responses

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

Possible causes:

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

Unauthorized

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

Possible causes:

  • Missing API key/bearer token
  • Invalid authentication
  • Insufficient permissions

Use Cases

Clean up after testing:

async function deleteTestLinks() {
const links = await getAllLinks();

const testLinks = links.filter(
link => link.title?.toLowerCase().includes('test')
);

for (const link of testLinks) {
await deleteLink(link.id);
console.log(`Deleted test link: ${link.shortCode}`);
}

console.log(`Deleted ${testLinks.length} test links`);
}

Remove links past expiration:

async function deleteExpiredLinks() {
const links = await getAllLinks();
const now = new Date();

const expiredLinks = links.filter(link => {
if (!link.expiresAt) return false;
return new Date(link.expiresAt) < now;
});

for (const link of expiredLinks) {
await deleteLink(link.id);
console.log(`Deleted expired link: ${link.shortCode}`);
}

return expiredLinks.length;
}

Remove links with no clicks after 30 days:

async function deleteInactiveLinks() {
const links = await getAllLinks();
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

const inactiveLinks = links.filter(link => {
const created = new Date(link.createdAt);
return created < thirtyDaysAgo && link.clickCount === 0;
});

console.log(`Found ${inactiveLinks.length} inactive links`);

for (const link of inactiveLinks) {
await deleteLink(link.id);
}
}

4. Delete with Backup

Export before deleting:

async function deleteWithBackup(linkId: string) {
// 1. Get link details
const link = await getLink(linkId);

// 2. Get analytics
const analytics = await getLinkAnalytics(linkId);

// 3. Create backup
const backup = {
link,
analytics,
deletedAt: new Date().toISOString(),
};

// 4. Save backup
await saveToFile(`backup_${link.shortCode}.json`, backup);

// 5. Delete link
await deleteLink(linkId);

console.log(`Link deleted. Backup saved to backup_${link.shortCode}.json`);
}

Best Practices

1. Always Confirm Before Deleting

function confirmDelete(linkTitle: string): boolean {
return window.confirm(
`Delete "${linkTitle}"? This action cannot be undone.`
);
}

if (confirmDelete(link.title)) {
await deleteLink(link.id);
}

2. Provide Undo Option (Soft Delete)

Instead of immediate deletion, mark for deletion:

// Mark for deletion
await updateLink(linkId, {
isActive: false,
title: `[DELETED] ${link.title}`,
});

// Show undo option for 30 seconds
showToast('Link deleted', {
action: 'Undo',
onAction: () => restoreLink(linkId),
duration: 30000,
});

// Actually delete after 30 days
setTimeout(() => deleteLink(linkId), 30 * 24 * 60 * 60 * 1000);

3. Rate Limit Bulk Deletes

Avoid overwhelming the server:

async function rateLimitedBulkDelete(linkIds: string[]) {
for (let i = 0; i < linkIds.length; i++) {
await deleteLink(linkIds[i]);

// Wait 100ms between deletes
await new Promise(resolve => setTimeout(resolve, 100));

console.log(`Deleted ${i + 1}/${linkIds.length}`);
}
}

4. Log Deletions

Audit trail for compliance:

async function loggedDelete(linkId: string, reason: string) {
const link = await getLink(linkId);

// Log deletion
await logAuditEvent({
action: 'link_deleted',
linkId: link.id,
shortCode: link.shortCode,
title: link.title,
clickCount: link.clickCount,
reason,
deletedBy: currentUser.id,
deletedAt: new Date(),
});

// Delete link
await deleteLink(linkId);
}

5. Handle Errors Gracefully

async function safeDelete(linkId: string) {
try {
await deleteLink(linkId);
showSuccess('Link deleted');
} catch (error) {
if (error.message.includes('not found')) {
showWarning('Link already deleted');
} else if (error.message.includes('unauthorized')) {
showError('You don't have permission to delete this link');
} else {
showError('Failed to delete link. Please try again.');
}
}
}

FAQ

No. Deletion is permanent. The short code becomes available for reuse, and all analytics data is lost.

Alternative: Use isActive: false instead of deleting.

Will the short code be available immediately?

Yes. After deletion, the short code (e.g., "abc123") can be used for a new link.

What happens to QR codes?

QR codes generated for the link will break - they'll redirect to a 404 page.

Yes, but this will break all links in your marketing materials. Consider deactivating instead.

Is there a limit on deletions?

No explicit limit, but follow rate limits (100 requests/minute).

Guides