Create Link
Create a new short link with platform-specific routing, attribution tracking, and UTM parameters.
Core and Cloud accept different fields. Core requires userId and originalUrl. Cloud requires either templateId or templateSlug, derives userId from your API key, and does not accept originalUrl — its web destination is webFallbackUrl. See examples for both below.
Endpoint
POST /api/links
Authentication
- Core (Self-Hosted): Include
userIdin the request body. See Authentication. - Cloud: Requires a valid API key in the Authorization header. See Authentication.
Request Body
Core Fields
| Field | Type | Required | Description |
|---|---|---|---|
userId | string (UUID) | Yes | User ID for link ownership |
originalUrl | string (URL) | Yes | Destination URL (fallback) |
templateId | string (UUID) | No | Template to use for default values |
customCode | string | No | Custom short code |
title | string | No | Internal title |
description | string | No | Internal description |
iosAppStoreUrl | string (URL) | No | iOS App Store URL |
androidAppStoreUrl | string (URL) | No | Android Play Store URL |
webFallbackUrl | string (URL) | No | Destination for web users |
appScheme | string | No | Custom URL scheme, without :// (e.g. myapp) |
iosUniversalLink | string (URL) | No | iOS Universal Link URL |
androidAppLink | string (URL) | No | Android App Link URL |
deepLinkPath | string | No | Deep link path within the app |
deepLinkParameters | object | No | Key-value pairs passed to the app |
attributionWindowHours | number | No | Attribution window (1-2160 hours). Default: 168 (7 days) |
utmParameters | object | No | UTM parameters to append |
targetingRules | object | No | Geographic/language/device targeting |
ogTitle | string | No | Open Graph title for social previews |
ogDescription | string | No | Open Graph description |
ogImageUrl | string (URL) | No | Open Graph image URL |
ogType | string | No | Open Graph type (e.g. website) |
expiresAt | string (ISO 8601) | No | Expiration timestamp |
Cloud Fields
| Field | Type | Required | Description |
|---|---|---|---|
templateId | string (UUID) | See note | Template to use for default values |
templateSlug | string | See note | Template slug, as an alternative to templateId |
title | string | No | Internal title for organization |
description | string | No | Internal description |
iosAppStoreUrl | string (URL) | No | Destination for iOS users |
androidAppStoreUrl | string (URL) | No | Destination for Android users |
webFallbackUrl | string (URL) | No | Destination for web users (http/https only) |
appScheme | string | No | Custom URL scheme, lowercase, without :// (e.g. myapp) |
iosUniversalLink | string (URL) | No | iOS Universal Link URL |
androidAppLink | string (URL) | No | Android App Link URL |
deepLinkPath | string | No | Deep link path within the app |
customSchemeUrl | string | No | Full custom-scheme destination (e.g. myapp://product/123) |
deepLinkParameters | object | No | Key-value pairs passed to the app |
customCode | string | No | Custom short code |
projectId | string (UUID) | null | No | Project to assign the link to. null clears the assignment |
domainId | string (UUID) | null | No | Custom domain to issue the link on. null uses the workspace default |
utmParameters | object | No | UTM parameters to append |
targetingRules | object | No | Geographic/language/device targeting |
attributionWindowHours | number | No | Install attribution window, 1-2160 hours |
eventAttributionWindowHours | number | No | In-app event attribution window, 1-2160 hours |
expiresAt | string (ISO 8601) | No | Expiration timestamp |
appendClickId | boolean | No | Append ?lf_click=<id> to web destinations. Defaults to true on Cloud |
ogTitle | string (max 255) | No | Open Graph title for this link's share preview |
ogDescription | string (max 500) | No | Open Graph description |
ogImageUrl | string (URL) | No | Open Graph image URL, http(s) only |
ogType | string | No | Open Graph type. Defaults to website |
The og* fields override the workspace and template share cards for that one link, so a link a user creates to share a specific item can unfurl with that item's own title and image. Leave them unset and the link uses the card configured in the dashboard. See Social Share Preview for the full resolution order.
Every Cloud link belongs to a template, but you may identify it with either templateId or templateSlug — one of the two is required. Templates define default settings for your links. See Link Templates.
The request schema discards field names it does not recognise instead of rejecting them, so a misspelled or non-existent field produces a successful response with that value dropped. If a link is created without a destination you set, check the field name against this table first.
In particular, Cloud does not accept originalUrl, iosUrl, or androidUrl. Those are Core field names — the Cloud equivalents are webFallbackUrl, iosAppStoreUrl, and androidAppStoreUrl.
UTM Parameters Object
{
source?: string; // Traffic source (e.g., "instagram")
medium?: string; // Marketing medium (e.g., "social")
campaign?: string; // Campaign name (e.g., "spring-sale-2024")
term?: string; // Paid keywords (e.g., "wireless-headphones")
content?: string; // Content variant (e.g., "carousel-ad-1")
}
Targeting Rules Object
{
countries?: string[]; // ISO 3166-1 alpha-2 codes (e.g., ["US", "CA", "GB"])
languages?: string[]; // ISO 639-1 codes (e.g., ["en", "es", "fr"])
devices?: string[]; // ["ios", "android", "web"]
}
Response
Success Response
Status Code: 201 Created
Core response:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"short_code": "abc123",
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"original_url": "https://example.com/products/wireless-headphones",
"title": "Wireless Headphones - Spring Sale",
"description": "Q2 2024 Instagram campaign",
"ios_app_store_url": "https://apps.apple.com/app/your-store/id123456789",
"android_app_store_url": "https://play.google.com/store/apps/details?id=com.yourstore",
"web_fallback_url": "https://example.com/products/wireless-headphones?platform=web",
"attribution_window_hours": 168,
"utm_parameters": {
"source": "instagram",
"medium": "social",
"campaign": "spring-sale-2024"
},
"targeting_rules": {
"countries": ["US", "CA", "GB"],
"languages": ["en"],
"devices": ["ios", "android"]
},
"is_active": true,
"expires_at": null,
"created_at": "2024-01-20T15:30:00.000Z",
"updated_at": "2024-01-20T15:30:00.000Z"
}
Cloud response includes additional fields:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"short_code": "abc123",
"short_url": "https://lnk.forty.com/abc123",
"user_id": "user_123",
"organization_id": "org_456",
"project_id": null,
"template_id": "template_789",
"original_url": null,
"title": "Wireless Headphones - Spring Sale",
"ios_app_store_url": "https://apps.apple.com/app/your-store/id123456789",
"android_app_store_url": "https://play.google.com/store/apps/details?id=com.yourstore",
"web_fallback_url": "https://example.com/products/wireless-headphones?platform=web",
"attribution_window_hours": 168,
"utm_parameters": {
"source": "instagram",
"medium": "social",
"campaign": "spring-sale-2024"
},
"is_active": true,
"expires_at": null,
"created_at": "2024-01-20T15:30:00.000Z",
"updated_at": "2024-01-20T15:30:00.000Z"
}
Error Responses
400 Bad Request - Invalid URL
{
"error": "Bad Request",
"message": "Invalid URL format",
"statusCode": 400,
"validation": {
"originalUrl": "Must be a valid URL"
}
}
400 Bad Request - Invalid Attribution Window
{
"error": "Bad Request",
"message": "Attribution window must be between 1 and 2160 hours",
"statusCode": 400,
"validation": {
"attributionWindowHours": "Attribution window must be at least 1 hour"
}
}
409 Conflict - Custom Code Already Exists
{
"error": "Conflict",
"message": "Short code 'spring-sale' is already in use",
"statusCode": 409
}
401 Unauthorized (Cloud)
{
"error": "Unauthorized",
"message": "Missing or invalid API key",
"statusCode": 401
}
404 Not Found - Template Not Found (Cloud)
{
"error": "Not Found",
"message": "Template not found",
"statusCode": 404
}
Examples
Core - Basic Link Creation
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123"
}'
Core - With Platform-Specific URLs
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123",
"title": "Product 123 Campaign",
"iosAppStoreUrl": "https://apps.apple.com/app/your-store/id123456789",
"androidAppStoreUrl": "https://play.google.com/store/apps/details?id=com.yourstore",
"deepLinkPath": "/product/123"
}'
Core - With Deep Linking
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123",
"appScheme": "myapp://",
"iosUniversalLink": "https://myapp.com/product/123",
"androidAppLink": "https://myapp.com/product/123",
"deepLinkPath": "/product/123",
"deepLinkParameters": {
"productId": "123",
"source": "campaign"
}
}'
Cloud - Basic Link Creation
curl -X POST https://api.linkforty.com/api/links \
-H "Authorization: Bearer dl_a1b2c3d4e5f6a7b8" \
-H "Content-Type: application/json" \
-d '{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"webFallbackUrl": "https://example.com/product/123"
}'
Cloud - With Platform-Specific URLs
curl -X POST https://api.linkforty.com/api/links \
-H "Authorization: Bearer dl_a1b2c3d4e5f6a7b8" \
-H "Content-Type: application/json" \
-d '{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"webFallbackUrl": "https://example.com/product/123",
"title": "Product 123 Campaign",
"iosAppStoreUrl": "https://apps.apple.com/app/your-store/id123456789",
"androidAppStoreUrl": "https://play.google.com/store/apps/details?id=com.yourstore"
}'
With UTM Parameters
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123",
"utmParameters": {
"source": "facebook",
"medium": "cpc",
"campaign": "summer-2024",
"term": "wireless-headphones",
"content": "image-ad-1"
}
}'
With Attribution Window
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123",
"attributionWindowHours": 336
}'
Attribution Window: 336 hours = 14 days
With Targeting Rules
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/product/123",
"targetingRules": {
"countries": ["US", "CA"],
"languages": ["en"],
"devices": ["ios", "android"]
}
}'
Behavior: Only users in US/Canada, with English language settings, on mobile devices will be redirected. Others see default URL.
With Expiration
curl -X POST https://your-domain.com/api/links \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/flash-sale",
"title": "24-Hour Flash Sale",
"expiresAt": "2024-12-31T23:59:59Z"
}'
Use Cases
E-commerce Product Link
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://shop.example.com/products/wireless-headphones",
"title": "Wireless Headphones Product Page",
"iosAppStoreUrl": "https://apps.apple.com/app/shop-app/id123",
"androidAppStoreUrl": "https://play.google.com/store/apps/details?id=com.shop",
"deepLinkPath": "/products/wireless-headphones",
"attributionWindowHours": 168,
"utmParameters": {
"source": "instagram",
"medium": "social",
"campaign": "product-launch",
"content": "product-123"
}
}
User Flow:
- User clicks link on Instagram
- Mobile user redirected to App Store/Google Play
- User installs app
- App opens and navigates to wireless headphones product page
- Install attributed to Instagram campaign
Referral Link
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/referral/john-doe",
"attributionWindowHours": 2160,
"utmParameters": {
"source": "referral",
"medium": "friend",
"campaign": "refer-a-friend",
"content": "john-doe"
}
}
Event Promotion
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/events/summer-concert",
"attributionWindowHours": 720,
"expiresAt": "2024-07-31T23:59:59Z",
"utmParameters": {
"source": "facebook",
"medium": "event",
"campaign": "summer-concert-2024"
}
}
Expires: July 31, 2024 (after event ends)
Best Practices
1. Always Provide Platform-Specific URLs
Bad:
{
"originalUrl": "https://example.com/product"
}
Good (Core):
{
"originalUrl": "https://example.com/product",
"iosAppStoreUrl": "https://apps.apple.com/app/id123",
"androidAppStoreUrl": "https://play.google.com/store/apps/details?id=com.app"
}
Good (Cloud):
{
"webFallbackUrl": "https://example.com/product",
"iosAppStoreUrl": "https://apps.apple.com/app/id123",
"androidAppStoreUrl": "https://play.google.com/store/apps/details?id=com.app"
}
Improves attribution accuracy by 3-5x.
2. Use Descriptive Titles
Bad:
{
"title": "Link 1"
}
Good:
{
"title": "Instagram Story - Spring Sale - Wireless Headphones"
}
Makes links easier to find and manage.
3. Set Attribution Window Based on Campaign
| Campaign Type | Window |
|---|---|
| Flash sale | 24-72 hours |
| Product launch | 7-14 days |
| Referral program | 30-90 days |
4. Include UTM Parameters
Always track campaign source:
{
"utmParameters": {
"source": "instagram",
"medium": "social",
"campaign": "spring-2024"
}
}
Rate Limiting
- Core: Rate limiting disabled by default (configurable via environment variables)
- Cloud: 100 requests/minute per API key
See Rate Limits for details.
Related Endpoints
- Get Link - Retrieve link details
- Update Link - Modify existing link
- Delete Link - Remove link
- Bulk Operations - Create multiple links at once
- Link Analytics - View link performance
Guides
- Creating Links - Complete guide with examples
- Attribution Windows - Choosing the right window
- Link Templates - Using templates for defaults (Cloud)
- UTM Parameters - Campaign tracking best practices