Skip to main content

Create Link

Create a new short link with platform-specific routing, attribution tracking, and UTM parameters.

Core vs Cloud

Core and Cloud have different required fields for creating links. Core requires userId and originalUrl. Cloud requires templateId (and derives userId from your API key). See examples for both below.

Endpoint

POST /api/links

Authentication

  • Core (Self-Hosted): Include userId in the request body. See Authentication.
  • Cloud: Requires a valid API key in the Authorization header. See Authentication.

Request Body

Core Fields

FieldTypeRequiredDescription
userIdstring (UUID)YesUser ID for link ownership
originalUrlstring (URL)YesDestination URL (fallback)
titlestringNoInternal title
descriptionstringNoInternal description
iosAppStoreUrlstring (URL)NoiOS App Store URL
androidAppStoreUrlstring (URL)NoAndroid Play Store URL
webFallbackUrlstring (URL)NoDestination for web users
appSchemestringNoCustom URL scheme (e.g., myapp://)
iosUniversalLinkstring (URL)NoiOS Universal Link URL
androidAppLinkstring (URL)NoAndroid App Link URL
deepLinkPathstringNoDeep link path within the app
deepLinkParametersobjectNoKey-value pairs passed to the app
attributionWindowHoursnumberNoAttribution window (1-2160 hours). Default: 168 (7 days)
utmParametersobjectNoUTM parameters to append
targetingRulesobjectNoGeographic/language/device targeting
ogTitlestringNoOpen Graph title for social previews
ogDescriptionstringNoOpen Graph description
ogImageUrlstring (URL)NoOpen Graph image URL
expiresAtstring (ISO 8601)NoExpiration timestamp

Cloud Fields

FieldTypeRequiredDescription
templateIdstring (UUID)YesTemplate to use for default values
originalUrlstring (URL)NoDestination URL (template provides default)
titlestringNoInternal title for organization
descriptionstringNoInternal description
iosUrlstring (URL)NoDestination for iOS users
androidUrlstring (URL)NoDestination for Android users
webFallbackUrlstring (URL)NoDestination for web users
customCodestringNoCustom short code (4-30 chars, alphanumeric)
projectIdstring (UUID)NoProject to assign link to
attributionWindowHoursnumberNoAttribution window (1-2160 hours). Default: 168 (7 days)
utmParametersobjectNoUTM parameters to append
targetingRulesobjectNoGeographic/language/device targeting
deepLinkParametersobjectNoKey-value pairs passed to the app
expiresAtstring (ISO 8601)NoExpiration timestamp
Cloud Templates

Cloud requires a templateId for every link. Templates define default settings for your links. See Link Templates for details on creating templates.

UTM Parameters Object

{
utm_source?: string; // Traffic source (e.g., "instagram")
utm_medium?: string; // Marketing medium (e.g., "social")
utm_campaign?: string; // Campaign name (e.g., "spring-sale-2024")
utm_term?: string; // Paid keywords (e.g., "wireless-headphones")
utm_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"])
platforms?: 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": {
"utm_source": "instagram",
"utm_medium": "social",
"utm_campaign": "spring-sale-2024"
},
"targeting_rules": {
"countries": ["US", "CA", "GB"],
"languages": ["en"],
"platforms": ["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": "https://example.com/products/wireless-headphones",
"title": "Wireless Headphones - Spring Sale",
"ios_url": "https://apps.apple.com/app/your-store/id123456789",
"android_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": {
"utm_source": "instagram",
"utm_medium": "social",
"utm_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

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"
}
}'
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",
"originalUrl": "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",
"originalUrl": "https://example.com/product/123",
"title": "Product 123 Campaign",
"iosUrl": "https://apps.apple.com/app/your-store/id123456789",
"androidUrl": "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": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "summer-2024",
"utm_term": "wireless-headphones",
"utm_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"],
"platforms": ["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

{
"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": {
"utm_source": "instagram",
"utm_medium": "social",
"utm_campaign": "product-launch",
"utm_content": "product-123"
}
}

User Flow:

  1. User clicks link on Instagram
  2. Mobile user redirected to App Store/Google Play
  3. User installs app
  4. App opens and navigates to wireless headphones product page
  5. Install attributed to Instagram campaign
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/referral/john-doe",
"attributionWindowHours": 2160,
"utmParameters": {
"utm_source": "referral",
"utm_medium": "friend",
"utm_campaign": "refer-a-friend",
"utm_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": {
"utm_source": "facebook",
"utm_medium": "event",
"utm_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):

{
"originalUrl": "https://example.com/product",
"iosUrl": "https://apps.apple.com/app/id123",
"androidUrl": "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 TypeWindow
Flash sale24-72 hours
Product launch7-14 days
Referral program30-90 days

4. Include UTM Parameters

Always track campaign source:

{
"utmParameters": {
"utm_source": "instagram",
"utm_medium": "social",
"utm_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.

Guides