Frequently Asked Questions

General

The database format is known as Comma Separated Values (CSV). All fields are separated by a comma and each individual line is a record by itself.

IP2Location is also available in binary format which works together with the IP2Location API in several programming languages.

The IP2Location will display the "-" in country field when the IP address range is still unallocated to any countries. It is also known as reserved IP address range.

You can purchase it from here. We will generate a unique login/password to allow you to download the database for one year after we have processed your order.

You will receive your login and password through email immediately after payment is authorized. You can use your credentials to download the database from our website at anytime. The database is in a ZIP compressed format to save your bandwidth and downloading time.

Ownership of IP addresses change hands from time to time. Therefore, a small percentage of IP address blocks needs to be updated every year. Our database is updated semi-monthly to ensure it is always accurate.

The IP2Location is supporting 249 countries as recognized in ISO 3166. The IP2Location database has over 99.5% accuracy in country level detection and >75% of accuracy in city level. The inaccuracy is due to the dynamic IP address allocation by large ISPs such as AOL, MSN TV and other proxies. Due to the fact that AOL uses a network that routes all of the company's Internet traffic through Reston, Virginia, all IP-based geo-location services, including IP2Location, are unable to determine the state and city for people who dial into the AOL network. You can get the complete accuracy and coverage from data accuracy report page.

We are monitoring all new IP address range assignments. We will scan through all new IP address ranges once reported for its network name and location. This is a manual process and requires actual usage from any IP address in order for us to determine the related ISP name and location. Therefore, there might be some update delays in the database for any newly assigned IP address ranges. We strive to provide information that is as accurate as possible.

Yes, we will deliver the notification via email when the update is available in the download area. We usually release the update on the first and fifteen day of the calendar month.

The IP2Location database is released on the 1st and 15th day of each calendar month, and it is uploaded to the customer download area for immediate access.

2024 2025 2026 2027
1st/15th January, 2024 1st/15th January, 2025 1st/15th January, 2026 1st/15th January, 2027
1st/15th February, 2024 1st/15th February, 2025 1st/15th February, 2026 1st/15th February, 2027
1st/15th March, 2024 1st/15th March, 2025 1st/15th March, 2026 1st/15th March, 2027
1st/15th April, 2024 1st/15th April, 2025 1st/15th April, 2026 1st/15th April, 2027
1st/15th May, 2024 1st/15th May, 2025 1st/15th May, 2026 1st/15th May, 2027
1st/15th June, 2024 1st/15th June, 2025 1st/15th June, 2026 1st/15th June, 2027
1st/15th July, 2024 1st/15th July, 2025 1st/15th July, 2026 1st/15th July, 2027
1st/15th August, 2024 1st/15th August, 2025 1st/15th August, 2026 1st/15th August, 2027
1st/15th September, 2024 1st/15th September, 2025 1st/15th September, 2026 1st/15th September, 2027
1st/15th October, 2024 1st/15th October, 2025 1st/15th October, 2026 1st/15th October, 2027
1st/15th November, 2024 1st/15th November, 2025 1st/15th November, 2026 1st/15th November, 2027
1st/15th December, 2024 1st/15th December, 2025 1st/15th December, 2026 1st/15th December, 2027

You need to have the right type of license if you want to redistribute IP2Location database in your application. If the number of client installations are less than 20 servers, you can purchase the standard server license for them under your account. If you redistribute the software with database to more than 20 users, please visit licensing and contact us for more information about Redistribution License (On Premise).

You need to have the right type of license if you want to redistribute IP2Location geolocation in your SaaS application. Please visit licensing and contact us for more information about Redistribution License (SaaS).

If you are an existing subscriber of IP2Location database, you can upgrade to a higher package. You just need to pay for the difference in price if your current subscription has more than 6 months validity. The subscription period will remain unchanged based on the old subscription package after the upgrade. Please login and select the upgrade option on the License page to perform the upgrade.

NOTE: If your current subscription has less than 6 months left, it will be renewed first before the upgrade is performed. In other words, your subscription period will be extended for another year.

IP2Location licensing is based on the number of physical machine installation. If you plan to install the IP2Location databases or software in more than one server, please acquire additional licenses during checkout. Please visit licensing https://www.ip2location.com/licensing for more information.

You can login to the account area and click on the "Add" button right beside the license. You will need to pay for any additional license (full year) by credit card to complete the transaction.

You can upgrade the web service package in your account area under the License page. You will be paying the full amount for the package that you are upgrading to. Upon completing the payment, we will top up the new credits (based on your upgraded package) and extend your expiry date for 1 year based on your payment date.

You can downgrade your web service package in your account under the License page. Your package will be downgraded immediately upon clicking the downgrade button. Please note that your previously purchased credits and expiry date will still remain the same. This action will only affect you if you enabled the auto-recharge feature, as the new downgraded package will be auto recharged/renewed on the next cycle.

No. Each account can only subscribe for one IP2Location Web Service and one IP2Proxy Web Service. You can upgrade or downgrade your package but you can't own more than one package for each service.

No, the API key will remain the same.

No, you can only top up the credits from the same package, which is WS10X.

IP2Location reports location of VPN or GRE tunnel based on their last known point of presence (PoP). We do not entertain any requests to update location based on private tunnel.

Database watermarking for copyright protection is essential to protect our customers and to prevent abuses by 3rd parties. Our download servers are concealing a rights holder identity "signature" (watermark) within the databases for effective rights assessment and protection. Customers can ignore this watermark because it does not impact either the usage or the accuracy of database.

 

Technical

IP address (IPv4) is divided into 4 sub-blocks. Each sub-block has a different weight number each powered by 256. IP number is being used in the database because it is more efficient to search between a range of numbers in a database.

The Beginning IP number and Ending IP Number are calculated based on the following formula:

IP Number = 16777216*w + 65536*x + 256*y + z     (1)

where

IP Address = w.x.y.z


For example, if the IP address is "202.186.13.4", then its IP Number will be "3401190660", based on the formula (1).

IP Address = 202.186.13.4

So, w = 202, x = 186, y = 13 and z = 4

IP Number = 16777216*202 + 65536*186 + 256*13 + 4
          = 3388997632 + 12189696 + 3328 + 4
          = 3401190660

Function Dot2LongIP (ByVal DottedIP)
Dim i, pos
Dim PrevPos, num
If DottedIP = "" Then
    Dot2LongIP = 0
Else
    For i = 1 To 4
        pos = InStr(PrevPos + 1, DottedIP, ".", 1)
        If i = 4 Then
            pos = Len(DottedIP) + 1
        End If
        num = Int(Mid(DottedIP, PrevPos + 1, pos - PrevPos - 1))
        PrevPos = pos
        Dot2LongIP = ((num Mod 256) * (256 ^ (4 - i))) + Dot2LongIP
    Next
End If
End Function
function Dot2LongIP ($IPaddr) {
	if ($IPaddr == "") {
		return 0;
	}
	else {
		$ips = explode(".", "$IPaddr");
		return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 * 256);
	}
}
long Dot2LongIP(String ipstring) {
	String[] ipAddressInArray = ipstring.split("\\.");
	long result = 0;
	long ip = 0;
	for (int x = 3; x >= 0; x--) {
		ip = Long.parseLong(ipAddressInArray[3 - x]);
		result |= ip << (x << 3);
	}
	return result;
}
<cfscript>
function Dot2LongIP(ipAddress) {
	if(arguments.ipAddress EQ "") {
		return 0;
	}
	else {
		ips = ListToArray( arguments.ipAddress, "." );
		return( ( 16777216 * ips[1] ) + ( 65536 * ips[2] ) + ( 256 * ips[3] ) + ips[4] );
	}
}
</cfscript>
public double Dot2LongIP(string DottedIP)
{
    int i;
    string [] arrDec;
    double num = 0;
    if (DottedIP == "")
    {
       return 0;
    }
    else
    {
       arrDec = DottedIP.Split(".");
       for(i = arrDec.Length - 1; i >= 0 ; i --)
       {
          num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
       }
       return num;
    }
}
Public Function Dot2LongIP(ByVal DottedIP As String) As Double
    Dim arrDec() As String
    Dim i As Integer
    Dim intResult As Long
    If DottedIP = "" then
       Dot2LongIP = 0
    Else
       arrDec = DottedIP.Split(".")
       For i = arrDec.Length - 1 To 0 Step -1
          intResult = intResult + ((Int(arrDec(i)) Mod 256) * Math.Pow(256, 3 -i))
       Next
       Dot2LongIP = intResult
    End If
End Function
use Socket;

sub dot2LongIP {
	my $ip_address = shift(@_);
	return unpack("N",inet_aton($ip_address));
}
require 'ipaddr'

def dot2LongIP(ip)
	ipnum = IPAddr.new(ip)
	return ipnum.to_i
end
import ipaddress

def dot2LongIP(ip):
	return int(ipaddress.IPv4Address(ip))
uint32_t Dot2LongIP(char* ipstring)
{
	uint32_t ip = inet_addr(ipstring);
	uint8_t *ptr = (uint8_t *) &ip;
	uint32_t a = 0;

	if (ipstring != NULL) {
		a =  (uint8_t)(ptr[3]);
		a += (uint8_t)(ptr[2]) * 256;
		a += (uint8_t)(ptr[1]) * 256 * 256;
		a += (uint8_t)(ptr[0]) * 256 * 256 * 256;
	}
	return a;
}
CREATE FUNCTION Dot2LongIP (ip text)
RETURNS bigint
BEGIN
	DECLARE ipnum bigint;
	SET ipnum = (SELECT INET_ATON(ip));
	RETURN ipnum;
END
CREATE FUNCTION [dbo].[Dot2LongIP]( @IP VarChar(15) )
RETURNS BigInt
AS
BEGIN
   DECLARE @ipA BigInt,
         @ipB BigInt,
         @ipC BigInt,
         @ipD BigInt,
         @ipE BigInt
   SELECT @ipA = LEFT(@ip, PATINDEX('%.%', @ip) - 1 )
   SELECT @ip = RIGHT(@ip, LEN(@ip) - LEN(@ipA) - 1 )

   SELECT @ipB = LEFT(@ip, PATINDEX('%.%', @ip) - 1 )
   SELECT @ip = RIGHT(@ip, LEN(@ip) - LEN(@ipB) - 1 )

   SELECT @ipC = LEFT(@ip, PATINDEX('%.%', @ip) - 1 )
   SELECT @ip = RIGHT(@ip, LEN(@ip) - LEN(@ipC) - 1 )

   SELECT @ipD = @ip
   SELECT @ipE = ( @ipA * 256*256*256 ) + ( @ipB * 256*256 ) + ( @ipC * 256 ) + @ipD

   RETURN @ipE
END
CREATE OR REPLACE FUNCTION Dot2LongIP(text) RETURNS BIGINT AS '
SELECT
split_part($1,''.'',1)::int8*(256*256*256)+
split_part($1,''.'',2)::int8*(256*256)+
split_part($1,''.'',3)::int8*256+
split_part($1,''.'',4)::int8;'
LANGUAGE SQL;
Convert IPv4 IP Address to IP Number in Decimal Integer (IPv4 IP Address is in cell A1):
=((VALUE(LEFT(A1, FIND(".", A1)-1)))*256^3)+((VALUE(MID(A1, FIND(".", A1)+1, FIND(".", A1, FIND(".", A1)+1)-FIND(".", A1)-1)))*256^2)+((VALUE(MID(A1, FIND(".", A1, FIND(".", A1)+1)+1, FIND(".", A1, FIND(".", A1, FIND(".", A1)+1)+1)-FIND(".", A1, FIND(".", A1)+1)-1)))*256)+(VALUE(RIGHT(A1, LEN(A1)-FIND(".", A1, FIND(".", A1, FIND(".", A1)+1)+1))))

IP Address = w.x.y.z

To reverse IP number to IP address,

w = int ( IP Number / 16777216 ) % 256
x = int ( IP Number / 65536    ) % 256
y = int ( IP Number / 256      ) % 256
z = int ( IP Number            ) % 256


where
%
is the modulus operator and
int
returns the integer part of the division.

Function Modulus(Value1, Value2)
    Modulus = Value1 - (Int(Value1 / Value2) * Value2)
End Function

Function Long2DotIP (ByVal IPNum)
    Long2DotIP = Modulus(Int(IPNum / 16777216), 256) & "." & Modulus(Int(IPNum / 65536), 256) & "." & Modulus(Int(IPNum / 256), 256) & "." & Modulus(IPNum, 256)
End Function
function Long2DotIP ($IPNum) {
	if ($IPNum == "") {
		return "0.0.0.0";
	}
	else {
		return (($IPNum / 16777216) % 256) . "." . (($IPNum / 65536) % 256) . "." . (($IPNum / 256) % 256) . "." . ($IPNum % 256);
	}
}
String Long2DotIP(long ipnum) {
	String result = "";
	result = ((ipnum / 16777216) % 256) + "." + ((ipnum / 65536) % 256) + "." + ((ipnum / 256) % 256) + "." + (ipnum % 256);
	return result;
}
<cfscript>
function Modulus(value1, value2) {
	return arguments.value1 - (floor(arguments.value1 / arguments.value2) * arguments.value2);
}

function Long2DotIP(ipNum) {
	return (Modulus(floor(arguments.ipNum / 16777216), 256)) & "." & (Modulus(floor(arguments.ipNum / 65536), 256)) & "." & (Modulus(floor(arguments.ipNum / 256), 256)) & "." & (Modulus(floor(arguments.ipNum), 256));
}
</cfscript>
public string Long2DotIP(long IPNum)
{
	string result = "";
	result = ((IPNum / 16777216) % 256) + "." + ((IPNum / 65536) % 256) + "." + ((IPNum / 256) % 256) + "." + (IPNum % 256);
	return result;
}
Public Function Long2DotIP(ByVal IPNum As Long) As String
	Dim result As String = ""
	result = (Int(IPNum / 16777216) Mod 256) & "." & (Int(IPNum / 65536) Mod 256) & "." & (Int(IPNum / 256) Mod 256) & "." & (IPNum Mod 256)
	Return result
End Function
use Socket;

sub long2DotIP {
	my $ip_number = shift(@_);
	return inet_ntoa(pack("N*", $ip_number));
}
def long2DotIP(ipnum)
	return ((ipnum / 16777216) % 256).to_s + "." + ((ipnum / 65536) % 256).to_s + "." + ((ipnum / 256) % 256).to_s + "." + (ipnum % 256).to_s
end
def long2DotIP(ipnum):
	return str(int(ipnum / 16777216) % 256) + "." + str(int(ipnum / 65536) % 256) + "." + str(int(ipnum / 256) % 256) + "." + str(ipnum % 256)
char* Long2DotIP(uint32_t ipnum)
{
	uint8_t bytes[4];
	char* buf = malloc (sizeof (char) * 16);
	bytes[0] = (ipnum >> 24) & 0xFF;
	bytes[1] = (ipnum >> 16) & 0xFF;
	bytes[2] = (ipnum >> 8) & 0xFF;
	bytes[3] = ipnum & 0xFF;
	snprintf(buf, (sizeof (char) * 16), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
	return buf;
}
CREATE FUNCTION Long2DotIP (ipnum bigint)
RETURNS text
BEGIN
	DECLARE ip text;
	SET ip = (SELECT INET_NTOA(ipnum));
	RETURN ip;
END
CREATE FUNCTION [dbo].[Long2DotIP]( @IPNum BigInt )
RETURNS VARCHAR(15)
AS
BEGIN
   RETURN CAST(((@IPNum / 16777216) % 256) AS VARCHAR(3)) +  + CAST(((@IPNum / 65536) % 256) AS VARCHAR(3)) +  + CAST(((@IPNum / 256) % 256) AS VARCHAR(3)) +  + CAST((@IPNum % 256) AS VARCHAR(3))
END
CREATE OR REPLACE FUNCTION Long2DotIP(BIGINT) RETURNS TEXT AS '
SELECT
CONCAT(($1 >> 24) % 256, ''.'', ($1 >> 16) % 256, ''.'', ($1 >> 8) % 256, ''.'', $1 % 256);'
LANGUAGE SQL;
Convert IP Number in Decimal Integer to IPv4 IP Address (Decimal Integer is in cell A1):
=IF(A1<>"", CONCATENATE(MOD(BITRSHIFT(A1, 24), 256), ".", MOD(BITRSHIFT(A1, 16), 256), ".", MOD(BITRSHIFT(A1, 8), 256), ".", MOD(A1, 256)), "")

IP address (IPv6) is divided into 8 groups of four hexadecimal digits with a colon as a group separator. Each group has a different weight number each powered by 65536. IP number is being used in the database because it is more efficient to search between a range of numbers in a database.

The Beginning IP number and Ending IP Number are calculated based on the following formula:

IP Number = (65536^7)*a + (65536^6)*b + (65536^5)*c + (65536^4)*d + (65536^3)*e + (65536^2)*f + 65536*g + h     (1)

where

IP Address = a:b:c:d:e:f:g:h


For example, if the IP address is "2001:0db8:0000:0042:0000:8a2e:0370:7334", then its IP Number will be "42540766411282594074389245746715063092", based on the formula (1).

IP Address (in hexadecimal) = 2001:0db8:0000:0042:0000:8a2e:0370:7334
IP Address (in decimal)     = 8193:3512:0:66:0:35374:880:29492

IP Number = (65536^7)*8193 + (65536^6)*3512 + (65536^5)*0 + (65536^4)*66 + (65536^3)*0 + (65536^2)*35374 + 65536*880 + 29492
          = 5192296858534827628530496329220096*8193 + 79228162514264337593543950336*3512 + 1208925819614629174706176*0 + 18446744073709551616*66 + 281474976710656*0 + 4294967296*35374 + 57671680 + 29492
          = 42540488161975842760550356425300246528 + 278249306750096353628526353580032 + 0 + 1217485108864830406656 + 0 + 151930173128704 + 57671680 + 29492
          = 42540766411282594074389245746715063092

function Dot2LongIP($ipv6) {
	return (string) gmp_import(inet_pton($ipv6));
}
java.math.BigInteger Dot2LongIP(String ipv6) {
	java.net.InetAddress ia = java.net.InetAddress.getByName(ipv6);
	byte byteArr[] = ia.getAddress();

	if (ia instanceof java.net.Inet6Address) {
		java.math.BigInteger ipnumber = new java.math.BigInteger(1, byteArr);
		return ipnumber;
	}
}
<cfscript>
function Dot2LongIP(ipv6) {
	if (arguments.ipv6 eq "") {
		return 0;
	}
	else {
		IPV6Long = CreateObject("java","java.math.BigInteger");
		IPV6NetAddress = CreateObject("java","java.net.InetAddress");
		newIp = IPV6NetAddress.getByName(arguments.ipv6);
		bytes = newIp.getAddress();
		bigInt = IPV6Long.init(1, bytes).toString();
		return bigInt;
	}
}
</cfscript>
public System.Numerics.BigInteger Dot2LongIP(string ipv6)
{
	System.Net.IPAddress address;
	System.Numerics.BigInteger ipnum;

	if (System.Net.IPAddress.TryParse(ipv6, out address)) {
		byte[] addrBytes = address.GetAddressBytes();

		if (System.BitConverter.IsLittleEndian) {
			System.Collections.Generic.List<byte> byteList = new System.Collections.Generic.List<byte>(addrBytes);
			byteList.Reverse();
			addrBytes = byteList.ToArray();
		}

		if (addrBytes.Length > 8) {
			//IPv6
			ipnum = System.BitConverter.ToUInt64(addrBytes, 8);
			ipnum <<= 64;
			ipnum += System.BitConverter.ToUInt64(addrBytes, 0);
		} else {
			//IPv4
			ipnum = System.BitConverter.ToUInt32(addrBytes, 0);
		}
		return ipnum;
	}
}
Public Function Dot2LongIP(ByVal ipv6 As String) As System.Numerics.BigInteger
	Dim address As System.Net.IPAddress
	Dim ipnum As System.Numerics.BigInteger

	If System.Net.IPAddress.TryParse(ipv6, address) Then
		Dim addrBytes() As Byte = address.GetAddressBytes()

		If System.BitConverter.IsLittleEndian Then
			Dim byteList As New System.Collections.Generic.List(Of Byte)(addrBytes)
			byteList.Reverse()
			addrBytes = byteList.ToArray()
		End If

		If addrBytes.Length > 8 Then
			'IPv6
			ipnum = System.BitConverter.ToUInt64(addrBytes, 8)
			ipnum <<= 64
			ipnum += System.BitConverter.ToUInt64(addrBytes, 0)
		Else
			'IPv4
			ipnum = System.BitConverter.ToUInt32(addrBytes, 0)
		End If
	End If
	Dot2LongIP = ipnum
End Function
use NetAddr::IP;

sub dot2LongIP {
	my $ip_address = shift(@_);
	my $ip_number = NetAddr::IP->new($ip_address) or die;
	return $ip_number->bigint;
}
require 'ipaddr'

def dot2LongIP(ipv6)
	ipnum = IPAddr.new(ipv6)
	return ipnum.to_i
end
import ipaddress

def dot2LongIP(ipv6):
	return int(ipaddress.IPv6Address(ipv6))
#include <arpa/inet.h>
#include <inttypes.h>

typedef unsigned __int128 uint128_t;

uint128_t Dot2LongIP(const char* ipv6) {
	struct sockaddr_in6 sa;
	inet_pton(AF_INET6, ipv6, &(sa.sin6_addr));
	uint128_t ipnum = 0;
	uint128_t octet = 0;
	int i;
	for (i = 0; i < (sizeof(sa.sin6_addr.s6_addr) / sizeof(sa.sin6_addr.s6_addr[0])); i++) {
		octet = ((uint128_t)sa.sin6_addr.s6_addr[i] << ((uint128_t)(15 - i) * 8));
		ipnum = ipnum + octet;
	}
	return ipnum;
}

IP Address = a:b:c:d:e:f:g:h

To reverse IP number to IP address,

a = int ( IP Number / (65536^7) ) % 65536
b = int ( IP Number / (65536^6) ) % 65536
c = int ( IP Number / (65536^5) ) % 65536
d = int ( IP Number / (65536^4) ) % 65536
e = int ( IP Number / (65536^3) ) % 65536
f = int ( IP Number / (65536^2) ) % 65536
g = int ( IP Number / 65536 ) % 65536
h = IP Number % 65536


where
%
is the modulus operator and
int
returns the integer part of the division.

NOTE: All parts need to be converted into hexadecimal to be part of the IPv6 address.

function Long2DotIP($integer) {
	return inet_ntop(str_pad(gmp_export($integer), 16, "\0", STR_PAD_LEFT));
}
String Long2DotIP(String integer)
{
	String ipstr = new java.math.BigInteger(integer).toString(16);
	String padding = new String(new char[32 - ipstr.length()]).replace("\0", "0");
	String retval = padding + ipstr;
	retval = retval.replaceAll("(.{4})", "$1:").substring(0, 39);
	return retval;
}
<cfscript>
function Long2DotIP(integer) {
	if (arguments.integer eq "") {
		return 0;
	}
	else {
		retval = "";
		bigobj = CreateObject("java","java.math.BigInteger");
		intval = bigobj.init(integer).toString(16);
		padding = repeatstring("0", 32 - len(intval));
		retval = padding & intval;
		retval = rereplace(rereplace(retval, "(.{4})", "\1:", "ALL"), ":$", "");
		return retval;
	}
}
</cfscript>
public string Long2DotIP(string bigint)
{
	string retval = "";
	System.Numerics.BigInteger intval = System.Numerics.BigInteger.Zero;
	if (System.Numerics.BigInteger.TryParse(bigint, out intval))
	{
		retval = intval.ToString("x").PadLeft(32, '0');
		char[] trimme = new[] { ':' };
		retval = System.Text.RegularExpressions.Regex.Replace(retval, "(.{4})", "$1:").TrimEnd(trimme);
	}
	return retval;
}
Public Function Long2DotIP(ByVal bigint As String) As String
	Dim retval As String = ""
	Dim intval As System.Numerics.BigInteger = System.Numerics.BigInteger.Zero

	If System.Numerics.BigInteger.TryParse(bigint, intval) Then
		retval = intval.ToString("x").PadLeft(32, "0"c)
		Dim trimme As Char() = {":"c}
		retval = System.Text.RegularExpressions.Regex.Replace(retval, "(.{4})", "$1:").TrimEnd(trimme)
	End If

	Return retval
End Function
use Math::BigInt;

sub long2DotIP {
	my $ipnumstr = shift(@_);
	my $ipnum = Math::BigInt->new($ipnumstr);
	my $iphex = $ipnum->as_hex();
	$iphex =~ s/^0x//;
	my $ipv6 = ('0' x (32 - length($iphex))) . $iphex;
	$ipv6 =~ s/(.{4})/$1:/g;
	$ipv6 =~ s/:$//;
	return $ipv6;
}
def long2DotIP(integer)
	return integer.to_s(16).rjust(32, '0').gsub(/(.{4})/, "\1:").sub(/:$/, "")
end
import re

def long2DotIP(integer):
        retval = format(integer, 'x')
        retval = retval.zfill(32)
        retval = re.sub(r"(.{4})", r"\1:", retval)
        retval = re.sub(r":$", "", retval)
        return retval
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gmp.h>

char* Long2DotIP(char* ipnum)
{
	mpz_t bigint;
	char* buf = malloc (sizeof (char) * 33);
	char* buf2 = malloc (sizeof (char) * 40);
	int i = 0;
	int parts = 8;
	int partsize = 5;
	char **arr;
	arr = calloc(parts, sizeof *arr);

	for (i = 0; i < parts; i++)
	{
		arr[i] = calloc(partsize, sizeof *arr[i]);
	}
	mpz_init_set_str(bigint, ipnum, 10);
	gmp_snprintf(buf, (sizeof (char) * 33), "%032Zx", bigint);

	for (i = 0; i < parts; i++)
	{
		memcpy(arr[i], buf + (i * 4), 4);
	}

	snprintf(buf2, (sizeof (char) * 40), "%s:%s:%s:%s:%s:%s:%s:%s", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]);
	free(buf);
	free(arr);
	return buf2;
}

Firstly, convert the IP address to IP number format. Search using IP number to match a record that has the IP Number between the Beginning IP Number and the Ending IP Number.

For example, IP Address "72.77.138.60" is "1213041212" in IP Number. It matched the following recordset in the database.

Without Proxy Detection
<%
    ipaddress = Request.ServerVariables("REMOTE_ADDR")
%>
<?php
    $ipaddress = getenv("REMOTE_ADDR");
?>
<%
    String ipaddress = request.getRemoteAddr();
%>
<CFCOMPONENT>
<CFSET ipaddress="#CGI.Remote_Addr#">
</CFCOMPONENT>
public string IpAddress()
{
    return Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
}
Public Function IpAddress()
    IpAddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
End Function
With Proxy Detection
<%
    ipaddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    if ipaddress = "" then
        ipaddress = Request.ServerVariables("REMOTE_ADDR")
    end if
%>
<?php
    if (getenv("HTTP_X_FORWARDED_FOR")) {
        $ipaddress = getenv("HTTP_X_FORWARDED_FOR");
    } else {
        $ipaddress = getenv("REMOTE_ADDR");
    }
?>
<%
    if (request.getHeader("X_FORWARDED_FOR") == null) {
        String ipaddress = request.getRemoteAddr();
    } else {
        String ipaddress = request.getHeader("X_FORWARDED_FOR");
    }
%>
<CFCOMPONENT>
<CFIF #CGI.HTTP_X_Forwarded_For# EQ "">
<CFSET ipaddress="#CGI.Remote_Addr#">
<CFELSE>
<CFSET ipaddress="#CGI.HTTP_X_Forwarded_For#">
</CFIF>
</CFCOMPONENT>
public string IpAddress()
{
    string strIp;
    strIp = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (strIp == null)
    {
       strIp = Request.ServerVariables["REMOTE_ADDR"];
    }
    return strIp;
}
Public Function IpAddress()
    Dim strIp As String
    strIp = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    If strIp = "" Then
       strIp = Request.ServerVariables("REMOTE_ADDR")
    End If
    IpAddress = strIp
End Function

You need to download the latest semi-monthly database from our server using your subscription account and password. The database is available in complete format. Therefore, you just need to drop the old database and replace it with the new one.

Our subscribers can automate the download process using the free command-line script written in Perl which can be downloaded from our Web site. Please visit the following Web page for more information such as command syntax.
https://www.ip2location.com/free/downloader

Since the database is being updated every month at the beginning of the month, please download the database only once a month.

Yes. If you already have an AWS account, you can simply set up the database in just a few steps.

Yes. You may download the image at the below link:

Yes. You may refer to the following:

LocaProxy.com. It provides multi-location HTTP proxies to help businesses test geolocation applications. This solution reduces the total cost of testing by supplying the Distributed Infrastructure as a Service.

The IP2Location databases supply the nearest Weather Station Codes and Names only. It does NOT provide live weather data or forecast data feed. However, it is possible to collect the weather information by using paid subscription from 3rd-party Web sites such as Weather.com. Please refer to their license agreement and contact them if you have any questions regarding XML weather data feed.

Weather.com XML Data Feed (Free for Personal Use or Paid for Commercial use)
For example, if the nearest Weather Station Code for one IP address is AAXX0001 in Aruba. The following are some sample sites with custom URL to retrieve the weather information and forecast.

Web-based Weather Information from Other Sites
https://weather.com/weather/today/l/AAXX0001
https://www.theweathernetwork.com/aw/weather/-/oranjestad

 

Database

First, import IP2Location database into MySQLm MS-SQL, MS-ACCESS, PL/SQL or other RDMS. Use an SQL query to get the matching recordset.

Sample Code
SELECT `ip_from`, `ip_to`, `country_code`, `country_name`, `region_name`, `city_name`, `latitude`, `longitude`, `zip_code`, `time_zone`, `idd_code`, `area_code`
FROM `ip2location_db15`
WHERE INET_ATON([IP ADDRESS]) <= ip_to LIMIT 1
SELECT TOP 1 [ip_from], [ip_to], [country_code], [country_name], [region_name], [city_name], [latitude], [longitude], [zip_code], [time_zone], [idd_code], [area_code]
FROM [ip2location_db15]
WHERE [SEARCH IP NO] <= ip_to

First, import IP2Location database into MySQL, MS-SQL, MS-ACCESS, PL/SQL or other RDMS. Use an SQL query to get the matching recordset. The IPv4 address is in IPv4-mapped IPv6 address form in IPv6 database. Learn more at https://blog.ip2location.com/knowledge-base/ipv4-mapped-ipv6-address/.

Sample Code
SELECT `ip_from`, `ip_to`, `country_code`, `country_name`, `region_name`, `city_name`, `latitude`, `longitude`, `zip_code`, `time_zone`, `idd_code`, `area_code`
FROM `ip2location_db15`
WHERE [SEARCH IP NO] <= ip_to LIMIT 1
SELECT TOP 1 [ip_from], [ip_to], [country_code], [country_name], [region_name], [city_name], [latitude], [longitude], [zip_code], [time_zone], [idd_code], [area_code]
FROM [ip2location_db15]
WHERE [SEARCH IP NO] <= ip_to

Sample Code
CREATE DATABASE ip2location;
USE ip2location;
CREATE TABLE `ip2location_db15`(
	`ip_from` INT(10) UNSIGNED,
	`ip_to` INT(10) UNSIGNED,
	`country_code` CHAR(2),
	`country_name` VARCHAR(64),
	`region_name` VARCHAR(128),
	`city_name` VARCHAR(128),
	`latitude` DOUBLE,
	`longitude` DOUBLE,
	`zip_code` VARCHAR(30),
	`time_zone` VARCHAR(8),
	`idd_code` VARCHAR(5),
	`area_code` VARCHAR(30),
	PRIMARY KEY (`ip_to`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE DATABASE ip2location
GO

USE ip2location
GO

CREATE TABLE [ip2location].[dbo].[ip2location_db15](
	[ip_from] bigint NOT NULL,
	[ip_to] bigint NOT NULL,
	[country_code] nvarchar(2) NOT NULL,
	[country_name] nvarchar(64) NOT NULL,
	[region_name] nvarchar(128) NOT NULL,
	[city_name] nvarchar(128) NOT NULL,
	[latitude] float NOT NULL,
	[longitude] float NOT NULL,
	[zip_code] nvarchar(30) NOT NULL,
	[time_zone] nvarchar(8) NOT NULL,
	[idd_code] nvarchar(5) NOT NULL,
	[area_code] nvarchar(30) NOT NULL
) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [ip_to] ON [ip2location].[dbo].[ip2location_db15]([ip_to]) ON [PRIMARY]
GO 
CREATE DATABASE ip2location WITH ENCODING 'UTF8';
\c ip2location
CREATE TABLE ip2location_db15(
	ip_from bigint NOT NULL,
	ip_to bigint NOT NULL,
	country_code character(2) NOT NULL,
	country_name character varying(64) NOT NULL,
	region_name character varying(128) NOT NULL,
	city_name character varying(128) NOT NULL,
	latitude real NOT NULL,
	longitude real NOT NULL,
	zip_code character varying(30) NOT NULL,
	time_zone character varying(8) NOT NULL,
	idd_code character varying(5) NOT NULL,
	area_code character varying(30) NOT NULL,
	CONSTRAINT ip2location_db15_pkey PRIMARY KEY (ip_to)
);

Sample Code
CREATE DATABASE ip2location;
USE ip2location;
CREATE TABLE `ip2location_db15`(
	`ip_from` DECIMAL(39,0) UNSIGNED,
	`ip_to` DECIMAL(39,0) UNSIGNED,
	`country_code` CHAR(2),
	`country_name` VARCHAR(64),
	`region_name` VARCHAR(128),
	`city_name` VARCHAR(128),
	`latitude` DOUBLE,
	`longitude` DOUBLE,
	`zip_code` VARCHAR(30),
	`time_zone` VARCHAR(8),
	`idd_code` VARCHAR(5),
	`area_code` VARCHAR(30),
	PRIMARY KEY (`ip_to`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE DATABASE ip2location
GO

USE ip2location
GO

CREATE TABLE [ip2location].[dbo].[ip2location_db15](
	[ip_from] char(39) NOT NULL,
	[ip_to] char(39) NOT NULL,
	[country_code] nvarchar(2) NOT NULL,
	[country_name] nvarchar(64) NOT NULL,
	[region_name] nvarchar(128) NOT NULL,
	[city_name] nvarchar(128) NOT NULL,
	[latitude] float NOT NULL,
	[longitude] float NOT NULL,
	[zip_code] nvarchar(30) NOT NULL,
	[time_zone] nvarchar(8) NOT NULL,
	[idd_code] nvarchar(5) NOT NULL,
	[area_code] nvarchar(30) NOT NULL
) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [ip_to] ON [ip2location].[dbo].[ip2location_db15]([ip_to]) ON [PRIMARY]
GO 
CREATE DATABASE ip2location WITH ENCODING 'UTF8';
\c ip2location
CREATE TABLE ip2location_db15(
	ip_from decimal(39,0) NOT NULL,
	ip_to decimal(39,0) NOT NULL,
	country_code character(2) NOT NULL,
	country_name character varying(64) NOT NULL,
	region_name character varying(128) NOT NULL,
	city_name character varying(128) NOT NULL,
	latitude real NOT NULL,
	longitude real NOT NULL,
	zip_code character varying(30) NOT NULL,
	time_zone character varying(8) NOT NULL,
	idd_code character varying(5) NOT NULL,
	area_code character varying(30) NOT NULL,
	CONSTRAINT ip2location_db15_pkey PRIMARY KEY (ip_to)
);

LOAD DATA LOCAL
	INFILE 'IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-AREACODE.CSV'
INTO TABLE
	`ip2location_db15`
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';
BULK INSERT [ip2location].[dbo].[ip2location_db15]
    FROM 'C:\[path to your CSV file]\IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-AREACODE.CSV'
    WITH
    (
        FORMATFILE = 'C:\[path to your DB15.FMT file]\DB15.FMT'
    )
GO
SQL Server 2017 or later (IPv6) can import without FMT. Read more. NOTE: You will need to copy the FMT code below and save it as a file named DB15.FMT on your computer. The first line of the FMT code indicates the version of bcp. Please change the version as according to your MS-SQL installed.
SQL Server 201612.0
SQL Server 201412.0
SQL Server 201211.0
Azure SQL10.0
SQL Server 2008/2008R210.0
SQL Server 20059.0
SQL Server 20008.0
SQL Server 7.07.0
SQL Server 6.56.5

IPv4 database

10.0
13
1 SQLCHAR 0 1 "\"" 0 first_double_quote  Latin1_General_CI_AI
2 SQLCHAR 0 20 "\",\"" 1 ip_from ""
3 SQLCHAR 0 20 "\",\"" 2 ip_to ""
4 SQLCHAR 0 2 "\",\"" 3 country_code Latin1_General_CI_AI
5 SQLCHAR 0 64 "\",\"" 4 country_name Latin1_General_CI_AI
6 SQLCHAR 0 128 "\",\"" 5 region_name Latin1_General_CI_AI
7 SQLCHAR 0 128 "\",\"" 6 city_name Latin1_General_CI_AI
8 SQLCHAR 0 20 "\",\"" 7 latitude ""
9 SQLCHAR 0 20 "\",\"" 8 longitude ""
10 SQLCHAR 0 30 "\",\"" 9 zip_code Latin1_General_CI_AI
11 SQLCHAR 0 8 "\",\"" 10 time_zone Latin1_General_CI_AI
12 SQLCHAR 0 5 "\",\"" 11 idd_code Latin1_General_CI_AI
13 SQLCHAR 0 30 "\"\r\n" 12 area_code Latin1_General_CI_AI

IPv6 database

10.0
13
1 SQLCHAR 0 1 "\"" 0 first_double_quote  Latin1_General_CI_AI
2 SQLCHAR 0 39 "\",\"" 1 ip_from ""
3 SQLCHAR 0 39 "\",\"" 2 ip_to ""
4 SQLCHAR 0 2 "\",\"" 3 country_code Latin1_General_CI_AI
5 SQLCHAR 0 64 "\",\"" 4 country_name Latin1_General_CI_AI
6 SQLCHAR 0 128 "\",\"" 5 region_name Latin1_General_CI_AI
7 SQLCHAR 0 128 "\",\"" 6 city_name Latin1_General_CI_AI
8 SQLCHAR 0 20 "\",\"" 7 latitude ""
9 SQLCHAR 0 20 "\",\"" 8 longitude ""
10 SQLCHAR 0 30 "\",\"" 9 zip_code Latin1_General_CI_AI
11 SQLCHAR 0 8 "\",\"" 10 time_zone Latin1_General_CI_AI
12 SQLCHAR 0 5 "\",\"" 11 idd_code Latin1_General_CI_AI
13 SQLCHAR 0 30 "\"\r\n" 12 area_code Latin1_General_CI_AI

NOTE: Due to the fact that SQL Server does not support a number with more than 38 digits, we have to store the IP From and IP To fields as zero padded strings to enable sorting. Please visit this tutorial on how to add the padding, enable cluster index and make the query.

COPY ip2location_db15 FROM 'IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-AREACODE.CSV' WITH CSV QUOTE AS '"';

Click here to view the step-by-step tutorials.

Sample Code
mongoimport -u USERNAME -p PASSWORD --authenticationDatabase admin --drop --db ip2location --collection db15 --type csv --file "IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-AREACODE.CSV" --fields ip_from,ip_to,country_code,country_name,region_name,city_name,latitude,longitude,zip_code,time_zone,idd_code,area_code
docker pull ip2location/mongodb
docker run --name ip2location -d -e TOKEN={DOWNLOAD_TOKEN} -e CODE=DB15 -e MONGODB_PASSWORD={MONGODB_PASSWORD} ip2location/mongodb

We also provide tutorials on how to import the database into MongoDB, Redis, Amazon SimpleDB and CouchDB at https://blog.ip2location.com.