diff --git a/README_API_GUIDE.md b/README_API_GUIDE.md
index cf1a5ebc5..01547a688 100644
--- a/README_API_GUIDE.md
+++ b/README_API_GUIDE.md
@@ -474,6 +474,37 @@ IP Address Lookups
 * **Terms of Service**: https://www.ip2location.com/web-service
 * **Notes**: With the non-free version, specify your desired package: `Geocoder.configure(ip2location: {package: "WSX"})` (see API documentation for package details).
 
+### IPInfoDB (`:ipinfodb`)
+
+* **API key**: required
+* **Quota**: 2 queries per second
+* **Region**: world
+* **SSL support**: yes
+* **Languages**: English
+* **Documentation**: https://www.ipinfodb.com/api
+* **Terms of Service**: https://www.ipinfodb.com/api
+
+### Ipregistry (`:ipregistry`)
+
+* **API key**: required (see https://ipregistry.co)
+* **Quota**: first 100,000 requests are free, then you pay per request (see https://ipregistry.co/pricing)
+* **Region**: world
+* **SSL support**: yes
+* **Languages**: English
+* **Documentation**: https://ipregistry.co/docs
+* **Terms of Service**: https://ipregistry.co/terms
+
+### Ipgeolocation (`:ipgeolocation`)
+
+* **API key**: required (see https://ipgeolocation.io/pricing)
+* **Quota**: 1500/day (with free API Key)
+* **Region**: world
+* **SSL support**: yes
+* **Languages**: English, German, Russian, Japanese, French, Chinese, Spanish, Czech, Italian
+* **Documentation**: https://ipgeolocation.io/documentation
+* **Terms of Service**: https://ipgeolocation/tos
+* **Notes**: To use Ipgeolocation set `Geocoder.configure(ip_lookup: :ipgeolocation, api_key: "your_ipgeolocation_api_key", use_https:true)`. Supports the optional params:  { excludes: "continent_code"}, {fields: "geo"}, {lang: "ru"}, {output: "xml"}, {include: "hostname"}, {ip: "174.7.116.0"}) (see API documentation for details).
+
 
 Local IP Address Lookups
 ------------------------
diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index 5ccae1022..70a87e788 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -73,7 +73,9 @@ def ip_services
         :ipdata_co,
         :db_ip_com,
         :ipstack,
-        :ip2location
+        :ip2location,
+        :ipinfodb,
+        :ipgeolocation
       ]
     end
 
diff --git a/lib/geocoder/lookups/ipinfodb.rb b/lib/geocoder/lookups/ipinfodb.rb
new file mode 100644
index 000000000..4fc9be9fb
--- /dev/null
+++ b/lib/geocoder/lookups/ipinfodb.rb
@@ -0,0 +1,46 @@
+require 'geocoder/lookups/base'
+require 'geocoder/results/ipinfodb'
+
+module Geocoder::Lookup
+  class Ipinfodb < Base
+
+    def name
+      "IPInfoDBApi"
+    end
+
+    def query_url(query)
+      url = "#{protocol}://api.ipinfodb.com/v3/ip-city/?key=#{configuration.api_key}&ip=#{query.sanitized_text}&format=json"
+    end
+
+    def supported_protocols
+      [:http, :https]
+    end
+
+    private # ----------------------------------------------------------------
+
+    def results(query)
+      return [reserved_result(query.text)] if query.loopback_ip_address?
+      return [] unless doc = fetch_data(query)
+      if doc["statusMessage"] == "Invalid API key."
+        raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
+        return []
+      else
+        return [doc]
+      end
+    end
+
+    def reserved_result(query)
+      {
+        "countryCode"         => "-",
+        "countryName"         => "-",
+        "regionName"          => "-",
+        "cityName"            => "-",
+        "zipCode"             => "-",
+        "latitude"            => "0",
+        "longitude"           => "0",
+        "timeZone"            => "-"
+      }
+    end
+
+  end
+end
diff --git a/lib/geocoder/results/ipinfodb.rb b/lib/geocoder/results/ipinfodb.rb
new file mode 100644
index 000000000..209082635
--- /dev/null
+++ b/lib/geocoder/results/ipinfodb.rb
@@ -0,0 +1,20 @@
+require 'geocoder/results/base'
+
+module Geocoder::Result
+  class Ipinfodb < Base
+
+    def address(format = :full)
+      "#{cityName} #{zipCode}, #{countryName}".sub(/^[ ,]*/, '')
+    end
+
+    def self.response_attributes
+      %w[countryCode countryName regionName cityName zipCode latitude longitude timeZone]
+    end
+
+    response_attributes.each do |attr|
+      define_method attr do
+        @data[attr] || ""
+      end
+    end
+  end
+end
diff --git a/test/fixtures/ipinfodb_8_8_8_8 b/test/fixtures/ipinfodb_8_8_8_8
new file mode 100644
index 000000000..515a56086
--- /dev/null
+++ b/test/fixtures/ipinfodb_8_8_8_8
@@ -0,0 +1,13 @@
+{
+  "statusCode" : "OK",
+  "statusMessage" : "",
+  "ipAddress" : "8.8.8.8",
+  "countryCode" : "US",
+  "countryName" : "United States",
+  "regionName" : "California",
+  "cityName" : "Mountain View",
+  "zipCode" : "94043",
+  "latitude" : "37.406",
+  "longitude" : "-122.079",
+  "timeZone" : "-07:00"
+}
\ No newline at end of file
diff --git a/test/fixtures/ipinfodb_invalid_api_key b/test/fixtures/ipinfodb_invalid_api_key
new file mode 100644
index 000000000..a686ce1cb
--- /dev/null
+++ b/test/fixtures/ipinfodb_invalid_api_key
@@ -0,0 +1,13 @@
+{
+  "statusCode" : "ERROR",
+  "statusMessage" : "Invalid API key.",
+  "ipAddress" : "",
+  "countryCode" : "",
+  "countryName" : "",
+  "regionName" : "",
+  "cityName" : "",
+  "zipCode" : "",
+  "latitude" : "0",
+  "longitude" : "0",
+  "timeZone" : ""
+}
\ No newline at end of file
diff --git a/test/fixtures/ipinfodb_no_results b/test/fixtures/ipinfodb_no_results
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/test_helper.rb b/test/test_helper.rb
index d6243a919..815755ccd 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -225,6 +225,22 @@ def default_fixture_filename
       end
     end
 
+    require 'geocoder/lookups/ipinfodb'
+    class Ipinfodb
+      private
+      def default_fixture_filename
+        "ipinfodb_8_8_8_8"
+      end
+    end
+
+    require 'geocoder/lookups/ipgeolocation'
+    class Ipgeolocation
+      private
+      def default_fixture_filename
+        "ipgeolocation_103_217_177_217"
+      end
+    end
+
     require 'geocoder/lookups/ipstack'
     class Ipstack
       private
diff --git a/test/unit/lookups/ipinfodb_test.rb b/test/unit/lookups/ipinfodb_test.rb
new file mode 100644
index 000000000..7397dab68
--- /dev/null
+++ b/test/unit/lookups/ipinfodb_test.rb
@@ -0,0 +1,22 @@
+# encoding: utf-8
+require 'test_helper'
+
+class IpinfodbTest < GeocoderTestCase
+
+  def setup
+    Geocoder.configure(:ip_lookup => :ipinfodb, :api_key => 'IPINFODB_API_KEY')
+  end
+
+  def test_ipinfodb_lookup_address
+    result = Geocoder.search("8.8.8.8").first
+    assert_equal "US", result.countryCode
+    assert_equal "United States", result.countryName
+    assert_equal "California", result.regionName
+    assert_equal "Mountain View", result.cityName
+  end
+
+  def test_ipinfodb_lookup_loopback_address
+    result = Geocoder.search("127.0.0.1").first
+    assert_equal "-", result.countryCode
+  end
+end
diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb
index eeb579ee8..06b3be0cf 100644
--- a/test/unit/result_test.rb
+++ b/test/unit/result_test.rb
@@ -6,6 +6,7 @@ class ResultTest < GeocoderTestCase
   def test_forward_geocoding_result_has_required_attributes
     Geocoder::Lookup.all_services_except_test.each do |l|
       next if l == :ip2location # has pay-per-attribute pricing model
+      next if l == :ipinfodb
       Geocoder.configure(:lookup => l)
       set_api_key!(l)
       result = Geocoder.search("Madison Square Garden").first
@@ -16,6 +17,8 @@ def test_forward_geocoding_result_has_required_attributes
   def test_reverse_geocoding_result_has_required_attributes
     Geocoder::Lookup.all_services_except_test.each do |l|
       next if l == :ip2location # has pay-per-attribute pricing model
+      next if l == :ipinfodb
+      next if l == :nationaal_georegister_nl # no reverse geocoding
       Geocoder.configure(:lookup => l)
       set_api_key!(l)
       result = Geocoder.search([45.423733, -75.676333]).first