diff --git a/lib/geocoder/lookups/ipapi_com.rb b/lib/geocoder/lookups/ipapi_com.rb
index df6f098b4182da3b7b7ac5b5235ba9fe19781b74..f38a58370e027b87677183a4e5cc3be95fc5c593 100644
--- a/lib/geocoder/lookups/ipapi_com.rb
+++ b/lib/geocoder/lookups/ipapi_com.rb
@@ -9,7 +9,8 @@ module Geocoder::Lookup
     end
 
     def query_url(query)
-      url_ = "#{protocol}://ip-api.com/json/#{query.sanitized_text}"
+      domain = configuration.api_key ? "pro.ip-api.com" : "ip-api.com"
+      url_ = "#{protocol}://#{domain}/json/#{query.sanitized_text}"
 
       if (params = url_query_string(query)) && !params.empty?
         url_ + "?" + params
@@ -29,17 +30,32 @@ module Geocoder::Lookup
 
     private
 
+    def parse_raw_data(raw_data)
+      if raw_data == "invalid key\n" || raw_data == "invalid key"
+        invalid_key_result
+      else
+        super(raw_data)
+      end
+    end
+
     def results(query)
       return [reserved_result(query.text)] if query.loopback_ip_address?
 
-      (doc = fetch_data(query)) ? [doc] : []
+      return [] unless doc = fetch_data(query)
+
+      if doc["message"] == "invalid key"
+        raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
+        return []
+      else
+        return [doc]
+      end
     end
 
     def reserved_result(query)
       {
         "message"      => "reserved range",
         "query"        => query,
-        "status"       => fail,
+        "status"       => "fail",
         "ip"           => query,
         "city"         => "",
         "region_code"  => "",
@@ -53,6 +69,12 @@ module Geocoder::Lookup
       }
     end
 
+    def invalid_key_result
+      {
+        "message"      => "invalid key"
+      }
+    end
+
     def query_url_params(query)
       params = {}
       params.merge!(fields: configuration[:fields]) if configuration.has_key?(:fields)
diff --git a/test/fixtures/ipapi_com_74_200_247_60 b/test/fixtures/ipapi_com_74_200_247_60
new file mode 100644
index 0000000000000000000000000000000000000000..b22bbe1c93e095b3333f229f14a158648e82f77e
--- /dev/null
+++ b/test/fixtures/ipapi_com_74_200_247_60
@@ -0,0 +1 @@
+invalid key
diff --git a/test/unit/lookups/ipapi_com_test.rb b/test/unit/lookups/ipapi_com_test.rb
index 6cb07cb9545cd98ff4433872837030351ac9a311..ce2fe3bb1c8d09080af846d513defde2d09a1e6f 100644
--- a/test/unit/lookups/ipapi_com_test.rb
+++ b/test/unit/lookups/ipapi_com_test.rb
@@ -41,6 +41,16 @@ class IpapiComTest < GeocoderTestCase
     assert_equal nil, result.message
   end
 
+  def test_localhost
+    result = Geocoder.search("::1").first
+    assert_equal nil, result.lat
+    assert_equal nil, result.lon
+    assert_equal [nil, nil], result.coordinates
+    assert_equal nil, result.reverse
+    assert_equal "::1", result.query
+    assert_equal "fail", result.status
+  end
+
   def test_api_key
     Geocoder.configure(:api_key => "MY_KEY")
     g = Geocoder::Lookup::IpapiCom.new
@@ -50,7 +60,7 @@ class IpapiComTest < GeocoderTestCase
   def test_url_with_api_key_and_fields
     Geocoder.configure(:api_key => "MY_KEY", :ipapi_com => {:fields => "lat,lon,xyz"})
     g = Geocoder::Lookup::IpapiCom.new
-    assert_equal "http://ip-api.com/json/74.200.247.59?fields=lat%2Clon%2Cxyz&key=MY_KEY", g.query_url(Geocoder::Query.new("74.200.247.59"))
+    assert_equal "http://pro.ip-api.com/json/74.200.247.59?fields=lat%2Clon%2Cxyz&key=MY_KEY", g.query_url(Geocoder::Query.new("74.200.247.59"))
   end
 
   def test_url_with_fields
@@ -70,4 +80,16 @@ class IpapiComTest < GeocoderTestCase
     assert_equal "http://ip-api.com/json/74.200.247.59?fields=lat%2Czip", g.query_url(q)
   end
 
+  def test_use_https_with_api_key
+    Geocoder.configure(:api_key => "MY_KEY", :use_https => true)
+    g = Geocoder::Lookup::IpapiCom.new
+    assert_equal "https://pro.ip-api.com/json/74.200.247.59?key=MY_KEY", g.query_url(Geocoder::Query.new("74.200.247.59"))
+  end
+
+  def test_invalid_api_key
+    Geocoder.configure(:api_key => "MY_KEY")
+    result = Geocoder.search("74.200.247.60").first
+    assert_equal nil, result
+  end
+
 end