diff --git a/README.md b/README.md
index 92cfbc28b94fc9699424ab8deafb6248edad3dc5..bf14c8f521627d9140dc4483f89016bcb5708a29 100644
--- a/README.md
+++ b/README.md
@@ -578,6 +578,31 @@ The [Google Places Details API](https://developers.google.com/places/documentati
 * **Limitations**: ?
 * **Notes**: You can specify which projection you want to use by setting, for example: `Geocoder.configure(:esri => {:outSR => 102100})`.
 
+#### Mapzen (`:mapzen`)
+
+* **About**: Mapzen is the primary author of pelias and offers Pelias-as-a-service in free and paid versions https://mapzen.com/pelias.
+* **API key**: required
+* **Quota**: 6/sec, up to 30k per day, paid plan info at https://mapzen.com/documentation/search/api-keys-rate-limits/#rate-limits
+* **Region**: World
+* **SSL support**: yes
+* **Languages**: en
+* **Documentation**: https://mapzen.com/documentation/search/search/
+* **Terms of Service**: http://mapzen.com/terms
+* **Limitations**: See terms
+
+#### Pelias (`:pelias`)
+
+* **About**: Pelias is a modular open-source geocoder using ElasticSearch for fast geocoding https://github.com/pelias/pelias.
+* **API key**: required
+* **Quota**: None, self-hosted service.
+* **Region**: World
+* **SSL support**: yes
+* **Languages**: en
+* **Documentation**: https://mapzen.com/documentation/search/search/
+* **Terms of Service**: http://mapzen.com/terms
+* **Limitations**: See terms
+* **Notes**: Configure your self-hosted pelias with the `endpoint` option: `Geocoder.configure(:lookup => :pelias, :api_key => 'your_api_key', :pelias => {:endpoint => 'self.hosted/pelias'})`.  Defaults to `localhost`.
+
 #### Data Science Toolkit (`:dstk`)
 
 Data Science Toolkit provides an API whose reponse format is like Google's but which can be set up as a privately hosted service.
diff --git a/Rakefile b/Rakefile
index 4651cf1a5715f6d3bd3ade845dd54f94cf78500f..c7d1063269103798fe90403ad75bf51af73d6a06 100644
--- a/Rakefile
+++ b/Rakefile
@@ -60,13 +60,11 @@ Rake::TestTask.new(:test) do |test|
   Rake::Task['db:reset'].invoke if ACCEPTED_DB_VALUES.include? ENV['DB']
   test.libs << 'lib' << 'test'
   test.pattern = 'test/unit/**/*_test.rb'
-  test.verbose = true
 end
 
 Rake::TestTask.new(:integration) do |test|
   test.libs << 'lib' << 'test'
   test.pattern = 'test/integration/*_test.rb'
-  test.verbose = true
 end
 
 task :default => [:test]
diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index 962f5a79c74bfe6f05db49aeeb9207ad9168109f..35ebc15e36ee31d969f6dba4106997656c9f740a 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -36,8 +36,10 @@ module Geocoder
         :nominatim,
         :mapbox,
         :mapquest,
+        :mapzen,
         :opencagedata,
         :ovi,
+        :pelias,
         :here,
         :baidu,
         :geocodio,
diff --git a/lib/geocoder/lookups/mapzen.rb b/lib/geocoder/lookups/mapzen.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0bb70d3095cb4429ca0c3b46bf4737eaf9adcee6
--- /dev/null
+++ b/lib/geocoder/lookups/mapzen.rb
@@ -0,0 +1,15 @@
+require 'geocoder/lookups/pelias'
+require 'geocoder/results/mapzen'
+
+# https://mapzen.com/documentation/search/search/ for more information
+module Geocoder::Lookup
+  class Mapzen < Pelias
+    def name
+      'Mapzen'
+    end
+
+    def endpoint
+      configuration[:endpoint] || 'search.mapzen.com'
+    end
+  end
+end
diff --git a/lib/geocoder/lookups/pelias.rb b/lib/geocoder/lookups/pelias.rb
new file mode 100644
index 0000000000000000000000000000000000000000..31c89696881a85a679e5f96b2a41b8221a1affa6
--- /dev/null
+++ b/lib/geocoder/lookups/pelias.rb
@@ -0,0 +1,56 @@
+require 'geocoder/lookups/base'
+require 'geocoder/results/pelias'
+
+module Geocoder::Lookup
+  class Pelias < Base
+    def name
+      'Pelias'
+    end
+
+    def endpoint
+      configuration[:endpoint] || 'localhost'
+    end
+
+    def query_url(query)
+      query_type = query.reverse_geocode? ? 'reverse' : 'search'
+      "#{protocol}://#{endpoint}/v1/#{query_type}?" + url_query_string(query)
+    end
+
+    def required_api_key_parts
+      ['search-XXXX']
+    end
+
+    private
+
+    def query_url_params(query)
+      {
+        api_key: configuration.api_key,
+        text: query.text,
+        size: 1
+      }.merge(super(query))
+    end
+
+    def results(query)
+      return [] unless doc = fetch_data(query)
+
+      # not all responses include a meta
+      if doc['meta']
+        error = doc.fetch('results', {}).fetch('error', {})
+        message = error.fetch('type', 'Unknown Error') + ': ' + error.fetch('message', 'No message')
+        log_message = 'Pelias Geocoding API error - ' + message
+        case doc['meta']['status_code']
+          when '200'
+            # nothing to see here
+          when '403'
+            raise_error(Geocoder::RequestDenied, message) || Geocoder.log(:warn, log_message)
+          when '429'
+            raise_error(Geocoder::OverQueryLimitError, message) || Geocoder.log(:warn, log_message)
+          else
+            raise_error(Geocoder::Error, message) || Geocoder.log(:warn, log_message)
+        end
+      end
+
+      doc['features'] || []
+    end
+  end
+end
diff --git a/lib/geocoder/results/mapzen.rb b/lib/geocoder/results/mapzen.rb
new file mode 100644
index 0000000000000000000000000000000000000000..125f4da860a2e4b8ec05a8773f6508b50e1fa3f8
--- /dev/null
+++ b/lib/geocoder/results/mapzen.rb
@@ -0,0 +1,5 @@
+require 'geocoder/results/pelias'
+
+module Geocoder::Result
+  class Mapzen < Pelias; end
+end
diff --git a/lib/geocoder/results/pelias.rb b/lib/geocoder/results/pelias.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f5311b046010af81be4b55539a76a4d9ff7993e4
--- /dev/null
+++ b/lib/geocoder/results/pelias.rb
@@ -0,0 +1,58 @@
+require 'geocoder/results/base'
+
+module Geocoder::Result
+  class Pelias < Base
+    def address(format = :full)
+      properties['label']
+    end
+
+    def city
+      locality
+    end
+
+    def coordinates
+      geometry['coordinates'].reverse
+    end
+
+    def country_code
+      properties['country_a']
+    end
+
+    def postal_code
+      properties['postalcode'].to_s
+    end
+
+    def province
+      state
+    end
+
+    def state
+      properties['region']
+    end
+
+    def state_code
+      properties['region_a']
+    end
+
+    def self.response_attributes
+      %w[county confidence country gid id layer localadmin locality neighborhood]
+    end
+
+    response_attributes.each do |a|
+      define_method a do
+        properties[a]
+      end
+    end
+
+    private
+
+    def geometry
+      @data.fetch('geometry', {})
+    end
+
+    def properties
+      @data.fetch('properties', {})
+    end
+  end
+end
+
diff --git a/test/fixtures/pelias_madison_square_garden b/test/fixtures/pelias_madison_square_garden
new file mode 100644
index 0000000000000000000000000000000000000000..261d0fb2037af0073d5e82a8a28fed7013d4dd08
--- /dev/null
+++ b/test/fixtures/pelias_madison_square_garden
@@ -0,0 +1,326 @@
+{
+  "bbox": [
+    -85.693709,
+    39.942189,
+    -73.9897,
+    40.75066
+  ],
+  "features": [
+    {
+      "geometry": {
+        "coordinates": [
+          -73.99347,
+          40.75066
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "Madison Square Garden Center, Manhattan, NY",
+        "confidence": 0.896,
+        "neighbourhood": "Garment District",
+        "locality": "New York",
+        "localadmin": "Manhattan",
+        "county": "New York County",
+        "region_a": "NY",
+        "region": "New York",
+        "country": "United States",
+        "country_a": "USA",
+        "name": "Madison Square Garden Center",
+        "source": "gn",
+        "layer": "venue",
+        "gid": "gn:venue:5125640",
+        "id": "5125640"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -73.993392,
+          40.750497
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "Madison Square Garden, Manhattan, NY",
+        "confidence": 0.896,
+        "neighbourhood": "Garment District",
+        "locality": "New York",
+        "localadmin": "Manhattan",
+        "county": "New York County",
+        "region_a": "NY",
+        "region": "New York",
+        "country": "United States",
+        "country_a": "USA",
+        "street": "Pennsylvania Plaza",
+        "housenumber": "46",
+        "name": "Madison Square Garden",
+        "source": "osm",
+        "layer": "venue",
+        "gid": "osm:venue:138141251",
+        "id": "138141251"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -73.9897,
+          40.7478
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "Hampton Inn Madison Square Garden, Manhattan, NY",
+        "confidence": 0.885,
+        "neighbourhood": "Koreatown",
+        "locality": "New York",
+        "localadmin": "Manhattan",
+        "county": "New York County",
+        "region_a": "NY",
+        "region": "New York",
+        "country": "United States",
+        "country_a": "USA",
+        "name": "Hampton Inn Madison Square Garden",
+        "source": "gn",
+        "layer": "venue",
+        "gid": "gn:venue:6466291",
+        "id": "6466291"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -73.99541,
+          40.74882
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "Holiday Inn Express NYC Madison Square Garden, Manhattan, NY",
+        "confidence": 0.673,
+        "neighbourhood": "Garment District",
+        "locality": "New York",
+        "localadmin": "Manhattan",
+        "county": "New York County",
+        "region_a": "NY",
+        "region": "New York",
+        "country": "United States",
+        "country_a": "USA",
+        "name": "Holiday Inn Express NYC Madison Square Garden",
+        "source": "gn",
+        "layer": "venue",
+        "gid": "gn:venue:7645793",
+        "id": "7645793"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -73.99,
+          40.748
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "Hampton Inn Madison Square Garden Area Hotel, Manhattan, NY",
+        "confidence": 0.673,
+        "neighbourhood": "Garment District",
+        "locality": "New York",
+        "localadmin": "Manhattan",
+        "county": "New York County",
+        "region_a": "NY",
+        "region": "New York",
+        "country": "United States",
+        "country_a": "USA",
+        "name": "Hampton Inn Madison Square Garden Area Hotel",
+        "source": "gn",
+        "layer": "venue",
+        "gid": "gn:venue:6499758",
+        "id": "6499758"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -75.181686,
+          39.942425
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "2315 Madison Square, Philadelphia, PA",
+        "confidence": 0.5,
+        "neighbourhood": "Schuylkill",
+        "locality": "Philadelphia",
+        "localadmin": "Philadelphia",
+        "county": "Philadelphia County",
+        "region_a": "PA",
+        "region": "Pennsylvania",
+        "country": "United States",
+        "country_a": "USA",
+        "postalcode": "19146",
+        "street": "Madison Square",
+        "housenumber": "2315",
+        "name": "2315 Madison Square",
+        "source": "oa",
+        "layer": "address",
+        "gid": "oa:address:0eef7b448f064f90869b1b4610fb2ccd",
+        "id": "0eef7b448f064f90869b1b4610fb2ccd"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -75.183109,
+          39.942643
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "2419 Madison Square, Philadelphia, PA",
+        "confidence": 0.5,
+        "neighbourhood": "Devil's Pocket",
+        "locality": "Philadelphia",
+        "localadmin": "Philadelphia",
+        "county": "Philadelphia County",
+        "region_a": "PA",
+        "region": "Pennsylvania",
+        "country": "United States",
+        "country_a": "USA",
+        "postalcode": "19146",
+        "street": "Madison Square",
+        "housenumber": "2419",
+        "name": "2419 Madison Square",
+        "source": "oa",
+        "layer": "address",
+        "gid": "oa:address:e7c287fb14f0459f8a1b4d938f57feb9",
+        "id": "e7c287fb14f0459f8a1b4d938f57feb9"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -75.181266,
+          39.942212
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "2304 Madison Square, Philadelphia, PA",
+        "confidence": 0.5,
+        "neighbourhood": "Schuylkill",
+        "locality": "Philadelphia",
+        "localadmin": "Philadelphia",
+        "county": "Philadelphia County",
+        "region_a": "PA",
+        "region": "Pennsylvania",
+        "country": "United States",
+        "country_a": "USA",
+        "postalcode": "19146",
+        "street": "Madison Square",
+        "housenumber": "2304",
+        "name": "2304 Madison Square",
+        "source": "oa",
+        "layer": "address",
+        "gid": "oa:address:fd605b0d1b3a422f9a9b8df9f136a80b",
+        "id": "fd605b0d1b3a422f9a9b8df9f136a80b"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -85.693709,
+          40.131756
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "2200 Madison Square, Anderson, IN",
+        "confidence": 0.5,
+        "neighbourhood": "North Anderson",
+        "locality": "Anderson",
+        "localadmin": "Anderson",
+        "county": "Madison County",
+        "region_a": "IN",
+        "region": "Indiana",
+        "country": "United States",
+        "country_a": "USA",
+        "postalcode": "46011",
+        "street": "Madison Square",
+        "housenumber": "2200",
+        "name": "2200 Madison Square",
+        "source": "oa",
+        "layer": "address",
+        "gid": "oa:address:acd7f29cc4bc44f69c719cf5cdad39e8",
+        "id": "acd7f29cc4bc44f69c719cf5cdad39e8"
+      },
+      "type": "Feature"
+    },
+    {
+      "geometry": {
+        "coordinates": [
+          -75.181085,
+          39.942189
+        ],
+        "type": "Point"
+      },
+      "properties": {
+        "label": "2300 Madison Square, Philadelphia, PA",
+        "confidence": 0.5,
+        "neighbourhood": "Schuylkill",
+        "locality": "Philadelphia",
+        "localadmin": "Philadelphia",
+        "county": "Philadelphia County",
+        "region_a": "PA",
+        "region": "Pennsylvania",
+        "country": "United States",
+        "country_a": "USA",
+        "postalcode": "19146",
+        "street": "Madison Square",
+        "housenumber": "2300",
+        "name": "2300 Madison Square",
+        "source": "oa",
+        "layer": "address",
+        "gid": "oa:address:c1d20ac81ac54f35af822359dc70171e",
+        "id": "c1d20ac81ac54f35af822359dc70171e"
+      },
+      "type": "Feature"
+    }
+  ],
+  "type": "FeatureCollection",
+  "geocoding": {
+    "timestamp": 1457996697682,
+    "engine": {
+      "version": "1.0",
+      "author": "Mapzen",
+      "name": "Pelias"
+    },
+    "query": {
+      "querySize": 20,
+      "private": false,
+      "size": 10,
+      "parsed_text": {
+        "admin_parts": "New York, NY 10001, United States\"",
+        "regions": [
+          "Garden",
+          "New York",
+          "10001",
+          "United States\""
+        ],
+        "state": "NY",
+        "street": "\"Madison Square",
+        "name": "\"Madison Square Garden"
+      },
+      "text": "\"Madison Square Garden, New York, NY 10001, United States\""
+    },
+    "attribution": "https:\/\/search.mapzen.com\/v1\/attribution",
+    "version": "0.1"
+  }
+}
diff --git a/test/fixtures/pelias_no_results b/test/fixtures/pelias_no_results
new file mode 100644
index 0000000000000000000000000000000000000000..7d3c12e72c0c0fed7b811739c436b79064b132fc
--- /dev/null
+++ b/test/fixtures/pelias_no_results
@@ -0,0 +1,38 @@
+{
+  "bbox": [
+    -85.693709,
+    39.942189,
+    -73.9897,
+    40.75066
+  ],
+  "features": [],
+  "type": "FeatureCollection",
+  "geocoding": {
+    "timestamp": 1457996697682,
+    "engine": {
+      "version": "1.0",
+      "author": "Mapzen",
+      "name": "Pelias"
+    },
+    "query": {
+      "querySize": 20,
+      "private": false,
+      "size": 0,
+      "parsed_text": {
+        "admin_parts": "New York, NY 10001, United States\"",
+        "regions": [
+          "Garden",
+          "New York",
+          "10001",
+          "United States\""
+        ],
+        "state": "NY",
+        "street": "\"Madison Square",
+        "name": "\"Madison Square Garden"
+      },
+      "text": "\"Madison Square Garden, New York, NY 10001, United States\""
+    },
+    "attribution": "https:\/\/search.mapzen.com\/v1\/attribution",
+    "version": "0.1"
+  }
+}
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 73c9cac423684bfd364eb4633d6d31920d27e295..4a9c4d62c1fe549b51ef1865312d46cd02ffe939 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -321,6 +321,13 @@ module Geocoder
       end
     end
 
+    require 'geocoder/lookups/mapzen'
+    class Mapzen
+      def fixture_prefix
+        'pelias'
+      end
+    end
+
     require 'geocoder/lookups/ipinfo_io'
     class IpinfoIo
       private
diff --git a/test/unit/lookups/geoportail_lu_test.rb b/test/unit/lookups/geoportail_lu_test.rb
index 303e664a12705c37ba0d9a5afe82535baa6a3b00..d81949b65b1a2568e848f75b3484f7d9b8f35a8e 100644
--- a/test/unit/lookups/geoportail_lu_test.rb
+++ b/test/unit/lookups/geoportail_lu_test.rb
@@ -52,7 +52,7 @@ class GeoportailLuTest < GeocoderTestCase
   end
 
   def test_no_results
-    results = Geocoder.search('no results')
+    results = Geocoder.search('')
     assert_equal 0, results.length
   end
 
diff --git a/test/unit/lookups/mapzen_test.rb b/test/unit/lookups/mapzen_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..83ad909d1266b614af6d761a710995e680dd7b83
--- /dev/null
+++ b/test/unit/lookups/mapzen_test.rb
@@ -0,0 +1,17 @@
+# encoding: utf-8
+require 'test_helper'
+
+class MapzenTest < GeocoderTestCase
+  def setup
+    Geocoder.configure(lookup: :mapzen, api_key: 'abc123')
+  end
+
+  def test_configure_default_endpoint
+    query = Geocoder::Query.new('Madison Square Garden, New York, NY')
+    assert_true query.url.start_with?('http://search.mapzen.com/v1/search'), query.url
+  end
+
+  def test_inherits_from_pelias
+    assert_true Geocoder::Lookup::Mapzen.new.is_a?(Geocoder::Lookup::Pelias)
+  end
+end
diff --git a/test/unit/lookups/pelias_test.rb b/test/unit/lookups/pelias_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ba209d6e1d379946b9bafde5ac281fcd96007687
--- /dev/null
+++ b/test/unit/lookups/pelias_test.rb
@@ -0,0 +1,24 @@
+# encoding: utf-8
+require 'test_helper'
+
+class PeliasTest < GeocoderTestCase
+  def setup
+    Geocoder.configure(lookup: :pelias, api_key: 'abc123', pelias: {}) # Empty pelias hash only for test (pollution control)
+  end
+
+  def test_configure_default_endpoint
+    query = Geocoder::Query.new('Madison Square Garden, New York, NY')
+    assert_true query.url.start_with?('http://localhost/v1/search'), query.url
+  end
+
+  def test_configure_custom_endpoint
+    Geocoder.configure(lookup: :pelias, api_key: 'abc123', pelias: {endpoint: 'self.hosted.pelias/proxy'})
+    query = Geocoder::Query.new('Madison Square Garden, New York, NY')
+    assert_true query.url.start_with?('http://self.hosted.pelias/proxy/v1/search'), query.url
+  end
+
+  def test_query_url_defaults_to_one
+    query = Geocoder::Query.new('Madison Square Garden, New York, NY')
+    assert_match 'size=1', query.url
+  end
+end