Import short URLs

Since it’s quite possible that you are already using some other URL shortener, starting with v2.4.0, it is possible to import short URLs directly into Shlink.

Import is performed from the command line, by running the short-urls:import command.

This command will guide you through the import process, asking you to provide the source from which you want to import, together with all required information for this process to succeed.

$ bin/cli short-url:import

 What is the source you want to import from:
  [0] bitly
  [1] yourls
  [2] csv
  [3] shlink
  [4] kutt
 >

The import command can be run as many times as you want, as Shlink is smart enough to not import the same link from the same source more than once, ensuring data consistency.

However, there’s a couple considerations:

  • The process has been optimized as much as possible, trying to avoid memory leaks. However, it is recommended to reserve at least 512Mb to PHP when running this process.
  • The import process is transactional and all-or-nothing. If there’s an uncontrolled error, the import will be rolled-back.
  • In order to determine if a visit has already been imported, Shlink relies on their date, assuming you will usually import on top of an “empty” instance. If this is not the case, it could end up ignoring visits that are not actually imported yet, just because they are older than other existing visits.

Supported sources

These are the sources from which you can currently import:

Bitly

Bitly’s importing is done through their API. That means that, depending on how many URLs you need to import, you could hit some API limit.

However, they allow up to 150 requests per minute for free accounts, and the number is even higher for paid plans.

On every API call, 50 URLs are imported, which means you won’t hit the limit if you have less than 7500 URLs.

If you hit the limit, shlink will print a “continue token” that can be used to skip already imported URLs, and therefore, avoid the limit to be hit again.

When you have waited a couple of minutes for the limit to clear, you can run the import command again, but providing the “continue token” when requested.

Running the command will generate an output similar to this:

$ bin/cli short-url:import bitly

 What is your Bit.ly's API access token? (you can generate one here https://bitly.is/accesstoken):
 > ****************************

 Do you want to import short-codes/slugs as they are? Otherwise, new unique short-codes will be generated for every imported URL. (yes/no) [yes]:
 > y

 Do you want to import tags? (yes/no) [yes]:
 > y

 Do you want to import custom domains? (any domain other than bit.ly) (yes/no) [no]:
 > y

 Do you want to keep the original creation date? Otherwise, all imported URLs will have current date as its creation date (yes/no) [yes]:
 > n

 Do you want to ignore archived URLs? (yes/no) [no]:
 > n

 If you already run this command once and a warning was displayed, you might have been provided with a "continue token". If that's the case, paste it here. If this is the first time you run this command, ignore this:
 >

https://shlink.io/documentation: Imported
https://docs.mezzio.dev/: Skipped
https://www.example.com/foo/bar: Imported

YOURLS

Shlink allows importing short URLs, and optionally visits, from a YOURLS instance using its API.

There’s a couple of limitations on imported data, as YOURLS does not store by default visitors IP address or geoloaction.

Warning

YOURLS’ API does not expose enough actions for Shlink to fetch all data. Because of that, you first need to install the yourls-shlink-import-plugin in YOURLS itself. You can download it from its repository and follow the instructions there.

Running the command will generate an output similar to this:

$ bin/cli short-url:import yourls -v

 What is your YOURLS instance base URL?:
 > https://s.test

 What is your YOURLS instance username?:
 > user

 What is your YOURLS instance password?:
 > pass

 Do you want to import each short URL's visits too? (yes/no) [yes]:
 > y

https://shlink.io: Imported with 381 visits.
https://example.com: Imported with 68 visits.

Standard CSV

In order to simplify importing links from arbitrary sources, Shlink supports importing from a simple CSV file.

The only 2 required columns in the CSV file are Long URL and Short code, but it also accepts the optional Title, Domain and Tags columns.

The Tags one should contain a list of pipe-separated items, as in foo|bar|baz.

This is an example of a valid CSV file:

Long URL,Tags,Domain,Short code,Title
https://shlink.io,foo|bar|baz,,123,
https://example.com,,example.com,456,my title

Running the command will generate an output similar to this:

$ bin/cli short-url:import csv

 What's the path for the CSV file you want to import:
 > ./my_links.csv

 What's the delimiter used to separate values? [Comma]:
  [,] Comma
  [;] Semicolon
 > ,

https://shlink.io: Imported
https://example.com: Imported

Shlink instance

If at some point you need to migrate your Shlink instance, or you want to change the database engine for any reason, this will help you import your short URLs from another Shlink instance.

The importing will be done by making use of Shlink’s built-in REST API. It will import links, their tags and domains, and also their visits if you choose to.

In order for this to work, you need to keep your old Shlink instance publicly accessible, otherwise you will not be able to import.

Running the command will generate an output similar to this:

$ bin/cli short-url:import shlink

 What is your Shlink instance base URL?:
 > https://s.test

 What is your Shlink instance API key?:
 > 54d07c90-a45f-11eb-9d0d-0800200c9a66

 Do you want to import each short URL's visits too? (yes/no) [yes]:
 > y

https://shlink.io: Imported with 381 visits.
https://example.com: Imported with 68 visits.

Note

Starting with v3.4.0, Shlink also allows to import orphan visits from the original Shlink instance.

This importing source is available since Shlink 2.7.0, but it can import from older Shlink versions.

Kutt.it

Shlink allows importing short URLs, and optionally visits, from a self-hosted kutt instance, or the SaaS https://kutt.it, using its API.

$ bin/cli short-url:import kutt

 What is your Kutt.it instance base URL?:
 > https://kutt.it

 What is your Kutt.it instance API key?:
 > api_key

 Do you want to import URLs created anonymously? (yes/no) [no]:
 >

https://shlink.io: Imported with 381 visits.
https://example.com: Imported with 68 visits.