diff --git a/lib/geocoder/esri_token.rb b/lib/geocoder/esri_token.rb
index eecb3f915db9892fc9d38ec24b245361c4df7529..a68f01555e5c62199e92f64d642b09709bff2b9b 100644
--- a/lib/geocoder/esri_token.rb
+++ b/lib/geocoder/esri_token.rb
@@ -11,8 +11,28 @@ module Geocoder
         @value
     end
 
-    def valid?
+    def active?
       @expires_at > Time.now
     end
+
+    def self.generate_token(client_id, client_secret, expires=1440)
+      # creates a new token that will expire in 1 day by default
+      getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
+        f: 'json',
+        client_id: client_id,
+        client_secret: client_secret,
+        grant_type: 'client_credentials',
+        expiration: expires # (minutes) max: 20160, default: 1 day
+
+      response = JSON.parse(getToken.body)
+
+      if response['error']
+        Geocoder.log(:warn, response['error'])
+      else
+        token_value = response['access_token']
+        expires_at = Time.now + expires.minutes
+        new(token_value, expires_at)
+      end
+    end
   end
 end
diff --git a/lib/geocoder/lookups/esri.rb b/lib/geocoder/lookups/esri.rb
index a7f3f2cee83a1fa29046066358186de0ef95d938..364283b72aa73d7f9a68def17c21db9cdd121cbf 100644
--- a/lib/geocoder/lookups/esri.rb
+++ b/lib/geocoder/lookups/esri.rb
@@ -16,24 +16,6 @@ module Geocoder::Lookup
         url_query_string(query)
     end
 
-    def generate_token(expires=1440)
-      # creates a new token that will expire in 1 day by default
-      getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
-        f: 'json',
-        client_id: configuration.api_key[0],
-        client_secret: configuration.api_key[1],
-        grant_type: 'client_credentials',
-        expiration: expires # (minutes) max: 20160, default: 1 day
-
-      if JSON.parse(getToken.body)['error']
-        raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Couldn't generate ESRI token: invalid API key.")
-      else
-        token_value = JSON.parse(getToken.body)['access_token']
-        expires_at = Time.now + expires.minutes
-        Geocoder::EsriToken.new(token_value, expires_at)
-      end
-    end
-
     private # ---------------------------------------------------------------
 
     def results(query)
@@ -66,10 +48,10 @@ module Geocoder::Lookup
     end
 
     def token
-      if configuration.token && configuration.token.valid? # if we have a token, use it
+      if configuration.token && configuration.token.active? # if we have a token, use it
         configuration.token.to_s
       elsif configuration.api_key # generate a new token if we have credentials
-        token_instance = generate_token
+        token_instance = EsriToken.generate_token(*configuration.api_key)
         Geocoder.configure(:esri => {:token => token_instance})
         token_instance.to_s
       end
diff --git a/test/unit/lookups/esri_test.rb b/test/unit/lookups/esri_test.rb
index 6d946c9a1d7db5a026e26f53748f5d668b16895b..ff76f32c9213b5fcdb4c502e9354fd69716a7460 100644
--- a/test/unit/lookups/esri_test.rb
+++ b/test/unit/lookups/esri_test.rb
@@ -15,6 +15,16 @@ class EsriTest < GeocoderTestCase
       res
   end
 
+  def test_query_for_geocode_with_token_for_storage
+    token = 'xxxxx'
+    Geocoder.configure(token: token, for_storage: true)
+    query = Geocoder::Query.new("Bluffton, SC")
+    lookup = Geocoder::Lookup.get(:esri)
+    res = lookup.query_url(query)
+    assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?f=pjson&outFields=%2A&text=Bluffton%2C+SC&forStorage=true&token=xxxxx",
+      res
+  end
+
   def test_query_for_reverse_geocode
     query = Geocoder::Query.new([45.423733, -75.676333])
     lookup = Geocoder::Lookup.get(:esri)