Skip to content
Tolinku
Tolinku
Sign In Start Free
Comparisons · · 6 min read

Link Format Mapping: Converting Links Between Platforms

By Tolinku Staff
|
Tolinku platform comparisons dashboard screenshot for comparisons blog posts

Every deep linking platform uses a different URL structure for its links. When you migrate between platforms, you need to map the old link format to the new one so that redirects work correctly and new links follow the same conventions your team expects.

This guide covers the structural differences between common deep link formats and provides practical mapping strategies. For the migration timeline, see migration timeline planning. For redirect setup, see link redirects during migration.

A deep link URL consists of several components, each carrying different information:

https://links.yourapp.com/campaign/summer-sale?utm_source=email&utm_medium=newsletter&deep_link=products/123

Breaking this down:

Component Value Purpose
Domain links.yourapp.com Your custom link domain
Path /campaign/summer-sale Route identifier
Query: utm_source email Campaign tracking
Query: utm_medium newsletter Campaign tracking
Query: deep_link products/123 In-app destination

Each platform structures these components differently. The mapping challenge is converting between these structures while preserving all the information.

Some platforms encode all link data in a short hash:

https://platform.link/AbCd123

The hash (AbCd123) maps to a database record on the platform's servers. The actual deep link data (destination URL, campaign parameters, fallback behavior) is stored server-side and not visible in the URL.

Migration challenge: You cannot parse these URLs to extract the deep link data. You need to use the old platform's API to export the link configurations, then recreate them on the new platform.

// Export link data from hash-based links
async function exportShortLinks(oldPlatformApi) {
  const links = await oldPlatformApi.getLinks({ limit: 1000 });
  return links.map(link => ({
    shortUrl: link.url,
    deepLinkPath: link.deepLink,
    campaign: link.campaign,
    fallbackUrl: link.fallbackUrl,
    createdAt: link.createdAt,
  }));
}

Some platforms encode the deep link destination in the URL path:

https://links.yourapp.com/products/123
https://links.yourapp.com/profile/user456

The path directly maps to the in-app destination. This format is the most URL-friendly and the easiest to migrate because the intent is visible in the URL itself.

Migration strategy: Create the same routes on the new platform. If your custom domain stays the same, users never see a difference.

Some platforms pass deep link data as query parameters:

https://platform.link/open?link=https://yourapp.com/products/123&apn=com.yourapp.android&isi=123456789
Parameter Purpose
link The deep link destination
apn Android package name
isi iOS App Store ID
ibi iOS bundle ID
efr Disable interstitial page

Migration challenge: The parameter names differ between platforms. You need a parameter mapping table.

Some platforms encode link data as a base64 or JSON payload in the URL:

https://platform.link/open?data=eyJkZWVwX2xpbmsiOiJwcm9kdWN0cy8xMjMiLCJjYW1wYWlnbiI6InN1bW1lcl9zYWxlIn0=

Migration challenge: You need to decode the payload to extract link data, then re-encode it in the new platform's format.

For each link you need to migrate, create a mapping entry:

// Link mapping entry
const linkMapping = {
  oldUrl: 'https://old-platform.link/AbCd123',
  oldFormat: {
    deepLink: 'products/123',
    campaign: 'summer_sale',
    source: 'email',
    medium: 'newsletter',
    fallbackUrl: 'https://yourapp.com/products/123',
    iosAppStoreId: '123456789',
    androidPackage: 'com.yourapp.android',
  },
  newUrl: 'https://links.yourapp.com/products/123',
  newFormat: {
    route: '/products/:id',
    params: { id: '123' },
    campaign: 'summer_sale',
    source: 'email',
    medium: 'newsletter',
    fallbackUrl: 'https://yourapp.com/products/123',
  },
};

Bulk Export from Old Platform

Most platforms provide an API for bulk link export:

async function exportAllLinks(oldPlatformApi) {
  let page = 1;
  const allLinks = [];

  while (true) {
    const response = await oldPlatformApi.getLinks({
      page,
      limit: 100,
      orderBy: 'clicks',
      direction: 'desc',
    });

    if (response.links.length === 0) break;
    allLinks.push(...response.links);
    page++;
  }

  return allLinks;
}

Export links ordered by click count (descending). Migrate the highest-traffic links first.

Route Mapping Patterns

Direct Path Mapping

The simplest case: the path structure is identical on both platforms.

Old: https://links.yourapp.com/products/123
New: https://links.yourapp.com/products/123

No conversion needed. Configure the same routes on the new platform.

Path Transformation

The path structure changes between platforms:

Old: https://old.link/open/products?id=123
New: https://links.yourapp.com/products/123

Create a mapping function:

function mapPath(oldPath, oldQuery) {
  // Old format: /open/products?id=123
  // New format: /products/123
  if (oldPath.startsWith('/open/')) {
    const resource = oldPath.replace('/open/', '');
    const id = oldQuery.id;
    return `/${resource}/${id}`;
  }
  return oldPath;
}

Wildcard Routes

If the old platform uses specific link IDs but your new platform uses path-based routes, set up a wildcard redirect:

Old: https://old.link/xK3mP → resolves to products/123
Old: https://old.link/yN7qR → resolves to profile/user456

New: https://links.yourapp.com/products/:id
New: https://links.yourapp.com/profile/:userId

You cannot set up wildcard redirects for hash-based short links. Each one needs an individual redirect entry or a redirect service that maps old hashes to new URLs.

Campaign Parameter Mapping

Different platforms use different parameter names for the same concepts:

Concept Platform A Platform B Platform C Tolinku
Campaign name campaign ~campaign c campaign
Traffic source source ~channel pid source
Medium medium ~feature af_adset medium
Ad creative ad ~ad_name af_ad ad
Custom data 1 data ~tags af_sub1 custom

Conversion Script

Write a script that converts parameter names:

function mapCampaignParams(oldParams, platformType) {
  const mapping = {
    platformA: {
      campaign: 'campaign',
      source: 'source',
      medium: 'medium',
    },
    platformB: {
      '~campaign': 'campaign',
      '~channel': 'source',
      '~feature': 'medium',
    },
    platformC: {
      c: 'campaign',
      pid: 'source',
      af_adset: 'medium',
    },
  };

  const map = mapping[platformType];
  const newParams = {};

  for (const [oldKey, value] of Object.entries(oldParams)) {
    const newKey = map[oldKey] || oldKey;
    newParams[newKey] = value;
  }

  return newParams;
}

After mapping link formats, you need to redirect old links to their new equivalents.

Individual Redirects

For high-traffic links, set up individual 301 redirects:

// Generate redirect rules from mapping table
function generateRedirects(mappings) {
  return mappings.map(m => ({
    source: new URL(m.oldUrl).pathname,
    destination: m.newUrl,
    statusCode: 301,
  }));
}

Pattern-Based Redirects

If the path structure follows a consistent pattern, use regex-based redirects:

# Nginx: redirect old format to new format
rewrite ^/open/(.+)\?id=(.+)$ /$1/$2 permanent;

Redirect Service

For large-scale migrations with thousands of hash-based short links, consider a lightweight redirect service:

// Simple redirect service
import express from 'express';

const app = express();
const redirectMap = loadRedirectMap(); // Load from database or JSON

app.get('/:hash', (req, res) => {
  const newUrl = redirectMap.get(req.params.hash);
  if (newUrl) {
    res.redirect(301, newUrl);
  } else {
    // Fallback: redirect to app homepage
    res.redirect(302, 'https://yourapp.com');
  }
});

This service runs on the old domain and redirects to the new platform's URLs.

Validation

After mapping and configuring redirects, validate:

Automated Testing

async function validateRedirects(mappings) {
  const results = [];

  for (const mapping of mappings) {
    const response = await fetch(mapping.oldUrl, { redirect: 'manual' });
    const location = response.headers.get('location');

    results.push({
      oldUrl: mapping.oldUrl,
      expectedNewUrl: mapping.newUrl,
      actualRedirect: location,
      status: response.status,
      pass: location === mapping.newUrl && response.status === 301,
    });
  }

  const passed = results.filter(r => r.pass).length;
  console.log(`Passed: ${passed}/${results.length}`);

  const failed = results.filter(r => !r.pass);
  if (failed.length > 0) {
    console.log('Failed redirects:');
    failed.forEach(f => console.log(`  ${f.oldUrl} → ${f.actualRedirect} (expected ${f.expectedNewUrl})`));
  }

  return results;
}

Manual Spot-Check

For the top 20 links by traffic, manually verify:

  1. Click the old link on a mobile device.
  2. Verify it redirects to the new platform.
  3. Verify the app opens to the correct screen.
  4. Verify campaign parameters are preserved in the new platform's analytics.

Tolinku uses path-based routing. Routes are configured in the Tolinku dashboard with pattern matching:

Route: /products/:productId
  → iOS: yourapp://products/{productId}
  → Android: yourapp://products/{productId}
  → Fallback: https://yourapp.com/products/{productId}

Campaign parameters are passed as query parameters using standard names (campaign, source, medium). For migration from other platforms, see migrating to Tolinku. For the migration checklist, see deep linking migration checklist.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.