Ipdata.co provides a RESTful API that allows you to lookup the location of any IP address, both IPv4 and IPv6.

Getting Started

The simplest call you can make would be a parameter-less GET call to the API endpoint at https://api.ipdata.co. This would return the location of the calling IP address.

https://api.ipdata.co

https://api.ipdata.co/8.8.8.8

curl https://api.ipdata.co
curl https://api.ipdata.co/8.8.8.8
Here are examples in more languages;
Pick a language
curl --header "Accept: application/json" https://api.ipdata.co

// Maven : Add these dependecies to your pom.xml (java6+)
// 
//     org.glassfish.jersey.core
//     jersey-client
//     2.8
// 
// 
//     org.glassfish.jersey.media
//     jersey-media-json-jackson
//     2.8
// 

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.ipdata.co")
  .request(MediaType.TEXT_PLAIN_TYPE)
  .header("Accept", "application/json")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
                

var request = require('request');

request({
  method: 'GET',
  url: 'https://api.ipdata.co/',
  headers: {
    'Accept': 'application/json'
  }}, function (error, response, body) {
  console.log('Status:', response.statusCode);
  console.log('Headers:', JSON.stringify(response.headers));
  console.log('Response:', body);
});
                

var request = new XMLHttpRequest();

request.open('GET', 'https://api.ipdata.co/');

request.setRequestHeader('Accept', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
                

from urllib2 import Request, urlopen

headers = {
  'Accept': 'application/json'
}
request = Request('https://api.ipdata.co/', headers=headers)

response_body = urlopen(request).read()
print response_body
                

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.ipdata.co");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Accept: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
                

require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :accept => 'application/json'
}

response = RestClient.get 'https://api.ipdata.co/', headers
puts response
                

package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
)

func main() {
  client := &http.Client{}

  req, _ := http.NewRequest("GET", "https://api.ipdata.co", nil)

  req.Header.Add("Accept", "application/json")

  resp, err := client.Do(req)

  if err != nil {
    fmt.Println("Errored when sending request to the server")
    return
  }

  defer resp.Body.Close()
  resp_body, _ := ioutil.ReadAll(resp.Body)

  fmt.Println(resp.Status)
  fmt.Println(string(resp_body))
}
                

//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://api.ipdata.co");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json");
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
                
Examples for looking up a specific IP address. Replace 8.8.8.8 with any valid IPv4 or IPv6 address.
Pick a language
curl --header "Accept: application/json" https://api.ipdata.co/8.8.8.8

  // Maven : Add these dependecies to your pom.xml (java6+)
  // 
  //     org.glassfish.jersey.core
  //     jersey-client
  //     2.8
  // 
  // 
  //     org.glassfish.jersey.media
  //     jersey-media-json-jackson
  //     2.8
  // 
  
  import javax.ws.rs.client.Client;
  import javax.ws.rs.client.ClientBuilder;
  import javax.ws.rs.client.Entity;
  import javax.ws.rs.core.Response;
  import javax.ws.rs.core.MediaType;
  
  Client client = ClientBuilder.newClient();
  Response response = client.target("https://api.ipdata.co/8.8.8.8")
    .request(MediaType.TEXT_PLAIN_TYPE)
    .header("Accept", "application/json")
    .get();
  
  System.out.println("status: " + response.getStatus());
  System.out.println("headers: " + response.getHeaders());
  System.out.println("body:" + response.readEntity(String.class));
                  

  var request = require('request');
  
  request({
    method: 'GET',
    url: 'https://api.ipdata.co/8.8.8.8/',
    headers: {
      'Accept': 'application/json'
    }}, function (error, response, body) {
    console.log('Status:', response.statusCode);
    console.log('Headers:', JSON.stringify(response.headers));
    console.log('Response:', body);
  });
                  

  var request = new XMLHttpRequest();
  
  request.open('GET', 'https://api.ipdata.co/8.8.8.8/');
  
  request.setRequestHeader('Accept', 'application/json');
  
  request.onreadystatechange = function () {
    if (this.readyState === 4) {
      console.log('Status:', this.status);
      console.log('Headers:', this.getAllResponseHeaders());
      console.log('Body:', this.responseText);
    }
  };
  
  request.send();
                  

  from urllib2 import Request, urlopen
  
  headers = {
    'Accept': 'application/json'
  }
  request = Request('https://api.ipdata.co/8.8.8.8/', headers=headers)
  
  response_body = urlopen(request).read()
  print response_body
                  

  <?php
  $ch = curl_init();
  
  curl_setopt($ch, CURLOPT_URL, "https://api.ipdata.co/8.8.8.8");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
  
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Accept: application/json"
  ));
  
  $response = curl_exec($ch);
  curl_close($ch);
  
  var_dump($response);
                  

  require 'rubygems' if RUBY_VERSION < '1.9'
  require 'rest_client'
  
  headers = {
    :accept => 'application/json'
  }
  
  response = RestClient.get 'https://api.ipdata.co/8.8.8.8/', headers
  puts response
                  

  package main
  
  import (
    "fmt"
    "io/ioutil"
    "net/http"
  )
  
  func main() {
    client := &http.Client{}
  
    req, _ := http.NewRequest("GET", "https://api.ipdata.co/8.8.8.8", nil)
  
    req.Header.Add("Accept", "application/json")
  
    resp, err := client.Do(req)
  
    if err != nil {
      fmt.Println("Errored when sending request to the server")
      return
    }
  
    defer resp.Body.Close()
    resp_body, _ := ioutil.ReadAll(resp.Body)
  
    fmt.Println(resp.Status)
    fmt.Println(string(resp_body))
  }
                  

  //Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
  //System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
  
  //Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
  using System;
  using System.Net.Http;
  
  var baseAddress = new Uri("https://api.ipdata.co/8.8.8.8");
  
  using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
  {
  
    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json");
    
    using(var response = await httpClient.GetAsync("undefined"))
    {
   
          string responseData = await response.Content.ReadAsStringAsync();
    }
  }
                  

Threat Intelligence Data

Our threat data consists of a database of 600M malicious IP addresses from several authoritative and actively maintained lists.
We also track Tor nodes and aggregate data from several sources that track open proxies.

Description

  • is_tor: is True if the IP address is associated with a node on the Tor network
  • is_proxy: is True if the IP address is a known proxy, includes HTTP/HTTPS/SSL/SOCKS/CONNECT and transparent proxies
  • is_anonymous: is set to True if either one of is_tor or is_proxy is true
  • is_known_attacker: is True if an IP address is a known source of malicious activity, i.e. attacks, malware, botnet activity etc
  • is_known_abuser: is True if the IP address is a known source of abuse i.e. spam, harvesters, registration bots and other nuisance bots etc
  • is_threat: is True if either one of is_known_abuser or is_known_attacker is true

JSONP

This is as simple as passing the callback parameter with your request.


$.get("https://api.ipdata.co", function (response) {
$("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");

Bulk Lookups

It's just as easy to lookup multiple IP addresses.

Put all your ip addresses in a file eg. ips.txt


1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4
Then run

    cat ips.txt | xargs -I% curl https://api.ipdata.co/%
And that would give

{
  "ip": "1.1.1.1",
  "city": "Research",
  "region": "Victoria",
  "country_name": "Australia",
  "country_code": "AU",
  "continent_name": "Oceania",
  "continent_code": "OC",
  "latitude": -37.7,
  "longitude": 145.1833,
  "asn": "",
  "organisation": "",
  "postal": "3095",
  "currency": "AUD",
  "currency_symbol": "$",
  "calling_code": "61",
  "flag": "https://ipdata.co/flags/au.png",
  "time_zone": "Australia/Melbourne"
}{
  "ip": "2.2.2.2",
  "city": "",
  "region": "",
  "country_name": "France",
  "country_code": "FR",
  "continent_name": "Europe",
  "continent_code": "EU",
  "latitude": 48.8582,
  "longitude": 2.3387000000000002,
  "asn": "AS3215",
  "organisation": "Orange",
  "postal": "",
  "currency": "EUR",
  "currency_symbol": "\u20ac",
  "calling_code": "33",
  "flag": "https://ipdata.co/flags/fr.png",
  "time_zone": "Europe/Paris"
}{
  "ip": "3.3.3.3",
  "city": "Fairfield",
  "region": "Connecticut",
  "country_name": "United States",
  "country_code": "US",
  "continent_name": "North America",
  "continent_code": "NA",
  "latitude": 41.1412,
  "longitude": -73.2637,
  "asn": "",
  "organisation": "",
  "postal": "06828",
  "currency": "USD",
  "currency_symbol": "$",
  "calling_code": "1",
  "flag": "https://ipdata.co/flags/us.png",
  "time_zone": "America/New_York"
}{
  "ip": "4.4.4.4",
  "city": "",
  "region": "",
  "country_name": "United States",
  "country_code": "US",
  "continent_name": "North America",
  "continent_code": "NA",
  "latitude": 37.751,
  "longitude": -97.822,
  "asn": "AS3356",
  "organisation": "Level 3 Communications, Inc.",
  "postal": "",
  "currency": "USD",
  "currency_symbol": "$",
  "calling_code": "1",
  "flag": "https://ipdata.co/flags/us.png",
  "time_zone": ""
}

Libraries

Let us know if you develop a language specific library and would like it listed here. Currently only the Python, Node and Golang libraries are officially supported.

Python SDK

By Jonathan Kosgei

Installation


pip install ipdata
Using the library

from ipdata import ipdata
ip = ipdata.ipdata()
data = ip.lookup('1.1.1.1')
if data['status']==200:
    for key in data['response']:
        print('#', key, ':', data['response'][key])
else:
    print(data['response'])
# ip : 1.1.1.1
# city : Research
# region : Victoria
# country_name : Australia
# country_code : AU
# continent_name : Oceania
# continent_code : OC
# latitude : -37.7
# longitude : 145.1833
# asn : 
# organisation : 
# postal : 3095
# currency : AUD
# currency_symbol : $
# calling_code : 61
# flag : https://ipdata.co/flags/au.png
# time_zone : Australia/Melbourne

country = ip.lookup('1.1.1.1')['response']['country_name']
# 'Australia'
Using an API key

from ipdata import ipdata

apikey = 'myapikey'
ip = ipdata.ipdata(apikey=apikey)
data = ip.lookup('1.1.1.1')

if data['status']==200:
    for key in data['response']:
        print('#', key, ':', data['response'][key])
else:
    print(data['response'])
        
        

Javascript SDK

This is a user contributed library. Special thanks to @thomasconner for creating this! Test this in your browser.

Installation


npm install ipdata

Importing

Import the library under a namespace.


  import * as ipdata from 'ipdata';
  // ipdata.lookup()

Import just the lookup function.


  import { lookup } from 'ipdata';
  // lookup()

Require the library.


  var ipdata = require('ipdata');
  // ipdata.lookup()

Usage

Looking up the calling IP


lookup()
.then(function(info) {
  // info.ip === 'hostcomputerip'
  // ...
})

Looking up any IP address


  lookup('8.8.8.8')
  .then(function(info) {
    // info.ip === 8.8.8.8
    // ...
  })

Using an API key


lookup('8.8.8.8', 'apiKey')
.then(function(info) {
  // info.ip === 8.8.8.8
  // ...
})

Go SDK

This is a user contributed library. Special thanks to @theckman for creating this!

Usage


import "github.com/theckman/go-ipdata"

ipd := ipdata.NewClient("")

data, err := ipd.Lookup("8.8.8.8")
if err != nil {
  // handle error
}

fmt.Printf("%s (%s)\n", data.IP, data.ASN)

Error handling


import "github.com/pkg/errors"

data, err := ipd.Lookup("8.8.8.8")
if err != nil {
  // do a type assertion on the error
  rerr, ok := errors.Cause(err).(interface{
      RateLimited() bool
    })

    if !ok {
      // this wasn't a failure from rate limiting
    }

    if rerr.RateLimited() {
      // we were rate limited
    }
}

Status Codes

The following are a list of status codes and their meanings as returned by the API.

Status Code Meaning
200 (OK) Your request was valid and a response was successfully returned.
400 (Bad Request) In the case of a private IP address the error will be accompanied by the message 203.0.113.0 is a private IP address. In the case of input that is not a valid IPv4 or IPv6 address you will get the message bleh does not appear to be an IPv4 or IPv6 address
429 (Too Many Reqests) This status code will be returned if you have made more than the 1500 requests on the free plan or exceeded your daily plan quota. It is accompanied by the message You have exceeded your free tier limit of 1500 requests. Register for a paid plan at https://ipdata.co to make more requests.