Update Link
Modify an existing link's properties including URLs, UTM parameters, targeting rules, and activation status.
Endpoint
PUT /api/links/:id
Authentication
Requires authentication via:
- Bearer token (user session)
- API key in
Authorizationheader
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Link ID to update |
Request Body
All fields are optional - only include the fields you want to update.
| Field | Type | Description |
|---|---|---|
originalUrl | string (URL) | Default destination URL |
title | string | Link title/name |
description | string | Link description |
iosUrl | string (URL) | iOS-specific redirect URL |
androidUrl | string (URL) | Android-specific redirect URL |
webFallbackUrl | string (URL) | Web fallback URL |
utmParameters | object | UTM tracking parameters |
utmParameters.source | string | UTM source |
utmParameters.medium | string | UTM medium |
utmParameters.campaign | string | UTM campaign |
utmParameters.term | string | UTM term |
utmParameters.content | string | UTM content |
targetingRules | object | Geographic/device targeting |
targetingRules.countries | string[] | ISO country codes (e.g., ["US", "CA"]) |
targetingRules.devices | string[] | Device types: "ios", "android", "web" |
targetingRules.languages | string[] | Language codes (e.g., ["en", "es"]) |
attributionWindowHours | number | Hours for install attribution (1-2160) |
expiresAt | string (ISO 8601) | Expiration timestamp |
isActive | boolean | Whether link is active |
templateId | string (UUID) | Link template to use |
projectId | string (UUID) | Project ID |
Note: You cannot update the shortCode - it's immutable after creation.
Response
Returns the updated link object:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"shortCode": "abc123",
"originalUrl": "https://example.com/products/new-headphones",
"title": "Updated: Wireless Headphones",
"iosUrl": "https://apps.apple.com/app/id123456789",
"androidUrl": "https://play.google.com/store/apps/details?id=com.app",
"utmParameters": {
"source": "facebook",
"medium": "cpc",
"campaign": "summer-sale-2024"
},
"attributionWindowHours": 336,
"isActive": true,
"updatedAt": "2024-03-15T14:30:00Z"
}
Examples
1. Update Destination URL
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"originalUrl": "https://example.com/new-product-page"
}'
Use case: Product link changed to different product.
2. Update UTM Parameters
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"utmParameters": {
"source": "twitter",
"medium": "social",
"campaign": "summer-sale-2024",
"content": "tweet-1"
}
}'
Use case: Change campaign tracking for different channel.
3. Extend Attribution Window
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"attributionWindowHours": 720
}'
Use case: Extend attribution from 7 days (168h) to 30 days (720h) for longer consideration purchases.
4. Update Platform URLs
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"iosUrl": "https://apps.apple.com/app/id999999",
"androidUrl": "https://play.google.com/store/apps/details?id=com.newapp"
}'
Use case: App store URLs changed after app relaunch.
5. Deactivate Link
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"isActive": false
}'
Use case: Temporarily disable link without deleting (campaign ended).
6. Add Expiration Date
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"expiresAt": "2024-12-31T23:59:59Z"
}'
Use case: Set expiration for limited-time offer.
7. Update Multiple Fields
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Black Friday Sale - Wireless Headphones",
"originalUrl": "https://example.com/black-friday/headphones",
"utmParameters": {
"campaign": "black-friday-2024",
"content": "hero-banner"
},
"expiresAt": "2024-11-30T23:59:59Z"
}'
Use case: Update link for seasonal campaign.
8. Update Targeting Rules
curl -X PUT https://api.linkforty.com/api/links/abc123-def456 \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"targetingRules": {
"countries": ["US", "CA", "GB"],
"devices": ["ios", "android"]
}
}'
Use case: Expand campaign to additional countries.
TypeScript Example
interface UpdateLinkRequest {
originalUrl?: string;
title?: string;
description?: string;
iosUrl?: string;
androidUrl?: string;
webFallbackUrl?: string;
utmParameters?: {
source?: string;
medium?: string;
campaign?: string;
term?: string;
content?: string;
};
targetingRules?: {
countries?: string[];
devices?: ('ios' | 'android' | 'web')[];
languages?: string[];
};
attributionWindowHours?: number;
expiresAt?: string;
isActive?: boolean;
templateId?: string;
projectId?: string;
}
async function updateLink(linkId: string, updates: UpdateLinkRequest) {
const response = await fetch(`https://api.linkforty.com/api/links/${linkId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(updates),
});
if (!response.ok) {
throw new Error(`Failed to update link: ${response.statusText}`);
}
return response.json();
}
// Usage
const updated = await updateLink('link_id', {
title: 'New Product Launch',
utmParameters: {
campaign: 'product-launch-2024',
},
});
console.log('Updated:', updated.shortCode);
Common Use Cases
1. Seasonal Campaign Updates
Update links when campaigns change:
// Summer → Fall transition
await updateLink(linkId, {
title: 'Fall Sale - Wireless Headphones',
utmParameters: {
campaign: 'fall-sale-2024',
},
expiresAt: '2024-11-30T23:59:59Z',
});
2. A/B Test Different Destinations
Test different landing pages:
// Variant A
await updateLink('link_a', {
originalUrl: 'https://example.com/landing-page-a',
utmParameters: { content: 'variant-a' },
});
// Variant B
await updateLink('link_b', {
originalUrl: 'https://example.com/landing-page-b',
utmParameters: { content: 'variant-b' },
});
// After 1 week, check analytics and update losing variant
3. Update App Store URLs After Release
When new app version releases:
await updateLink(linkId, {
iosUrl: 'https://apps.apple.com/app/id123456789',
androidUrl: 'https://play.google.com/store/apps/details?id=com.app.v2',
});
4. Pause Campaign
Temporarily disable without deleting:
// Pause
await updateLink(linkId, { isActive: false });
// Resume later
await updateLink(linkId, { isActive: true });
Error Responses
Link Not Found
{
"statusCode": 404,
"error": "Not Found",
"message": "Link not found"
}
Possible causes:
- Link ID doesn't exist
- Link belongs to different organization
No Updates Provided
{
"statusCode": 400,
"error": "Bad Request",
"message": "No updates provided"
}
Cause: Empty request body with no fields to update.
Invalid URL
{
"statusCode": 400,
"error": "Bad Request",
"message": "Validation error: Invalid URL format"
}
Cause: originalUrl, iosUrl, androidUrl, or webFallbackUrl is not a valid URL.
Invalid Attribution Window
{
"statusCode": 400,
"error": "Bad Request",
"message": "Attribution window must be between 1 and 2160 hours"
}
Cause: attributionWindowHours outside valid range (1-2160 hours = 1 hour to 90 days).
Best Practices
1. Update Only What Changed
Don't send entire object - only changed fields:
✅ Good:
await updateLink(linkId, {
title: 'New Title',
});
❌ Bad:
// Don't re-send unchanged fields
await updateLink(linkId, {
title: 'New Title',
originalUrl: link.originalUrl, // unchanged
iosUrl: link.iosUrl, // unchanged
androidUrl: link.androidUrl, // unchanged
// etc...
});
2. Validate Before Updating
function validateUrl(url: string): boolean {
try {
new URL(url);
return true;
} catch {
return false;
}
}
async function safeUpdateLink(linkId: string, updates: UpdateLinkRequest) {
// Validate URLs before sending
if (updates.originalUrl && !validateUrl(updates.originalUrl)) {
throw new Error('Invalid originalUrl');
}
return updateLink(linkId, updates);
}
3. Handle Optimistic Updates
Update UI immediately, rollback on error:
async function optimisticUpdate(link: Link, updates: UpdateLinkRequest) {
const originalLink = { ...link };
const updatedLink = { ...link, ...updates };
try {
// Update UI immediately
setLink(updatedLink);
// Send to server
const result = await updateLink(link.id, updates);
// Sync with server response
setLink(result);
} catch (error) {
// Rollback on error
setLink(originalLink);
showError('Failed to update link');
}
}
4. Batch Updates
If updating multiple fields, send one request:
✅ Good:
await updateLink(linkId, {
title: 'New Title',
originalUrl: 'https://example.com/new',
utmParameters: { campaign: 'new-campaign' },
});
❌ Bad:
await updateLink(linkId, { title: 'New Title' });
await updateLink(linkId, { originalUrl: 'https://example.com/new' });
await updateLink(linkId, { utmParameters: { campaign: 'new-campaign' } });
5. Track Update History
Log updates for audit trail:
async function updateLinkWithHistory(
linkId: string,
updates: UpdateLinkRequest,
reason: string
) {
const updatedLink = await updateLink(linkId, updates);
// Log update
await logUpdate({
linkId,
updates,
reason,
timestamp: new Date(),
updatedBy: currentUser.id,
});
return updatedLink;
}
Limitations
- Short code cannot be changed - It's immutable after creation
- Template change - Changing
templateIddoesn't retroactively apply template defaults - Click count - Cannot be manually modified (read-only)
- Timestamps -
createdAtcannot be changed,updatedAtis automatic
Related Endpoints
- Get Link - Retrieve current link details
- Create Link - Create new link
- Delete Link - Remove link
- Bulk Operations - Update multiple links
Guides
- Creating Links - Complete guide
- UTM Parameters - Campaign tracking
- Link Templates - Using templates