diff --git a/README.md b/README.md
index 213c23dcc298d4a4aa2da0322a9c051ea8b27bf4..5c63e2411b37ed2506151643214a49af812579bb 100644
--- a/README.md
+++ b/README.md
@@ -500,6 +500,18 @@ The [Google Places Details API](https://developers.google.com/places/documentati
 * **Terms of Service**: http://geocoder.us/terms.shtml
 * **Limitations**: ?
 
+#### Mapbox (`:mapbox`)
+
+* **API key**: required
+* **Key signup**: https://www.mapbox.com/pricing/
+* **Quota**: 1 Geocode per request
+* **Region**: US, Canada, and Europe are stable, rest of the world is closes
+* **SSL support**: no
+* **Languages**: English
+* **Documentation**: https://www.mapbox.com/developers/api/geocoding/
+* **Terms of Service**: https://www.mapbox.com/tos/
+* **Limitations**: ?  Must be displayed on a Mapbox map. Cache results for up to 30 days.
+
 #### Mapquest (`:mapquest`)
 
 * **API key**: required
diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index a704e570602172f1bf24b7b532ba7ac46875216e..f80d55284fdc18746a4f045f18de34b8b7eefc16 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -32,6 +32,7 @@ module Geocoder
         :geocoder_us,
         :yandex,
         :nominatim,
+        :mapbox,
         :mapquest,
         :opencagedata,
         :ovi,
diff --git a/lib/geocoder/lookups/mapbox.rb b/lib/geocoder/lookups/mapbox.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8fa84884561b9a3a6251298bb876f3756859a251
--- /dev/null
+++ b/lib/geocoder/lookups/mapbox.rb
@@ -0,0 +1,47 @@
+require 'geocoder/lookups/base'
+require "geocoder/results/mapbox"
+
+module Geocoder::Lookup
+  class Mapbox < Base
+
+    def name
+      "Mapbox"
+    end
+
+    def query_url(query)
+      "#{protocol}://api.mapbox.com/geocoding/v5/#{dataset}/#{url_query_string(query)}.json?access_token=#{configuration.api_key}"
+    end
+
+    private # ---------------------------------------------------------------
+
+    def results(query)
+      return [] unless data = fetch_data(query)
+      if data['features']
+        sort_relevant_feature(data['features'])
+      elsif data['message'] =~ /Invalid\sToken/
+        raise_error(Geocoder::InvalidApiKey, data['message'])
+      else
+        []
+      end
+    end
+
+    def url_query_string(query)
+      require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
+      CGI.escape query.text.to_s
+    end
+
+    def dataset
+      "mapbox.places"
+    end
+
+    def supported_protocols
+      [:https]
+    end
+
+    def sort_relevant_feature(features)
+      features.sort_by do |feature|
+        feature["relevance"]
+      end.reverse
+    end
+  end
+end
diff --git a/lib/geocoder/results/mapbox.rb b/lib/geocoder/results/mapbox.rb
new file mode 100644
index 0000000000000000000000000000000000000000..695bbfaacc18f96fabd5824cb720423058638725
--- /dev/null
+++ b/lib/geocoder/results/mapbox.rb
@@ -0,0 +1,53 @@
+require 'geocoder/results/base'
+
+module Geocoder::Result
+  class Mapbox < Base
+
+    def latitude
+      @latitude ||= @data["geometry"]["coordinates"].first.to_f
+    end
+
+    def longitude
+      @longitude ||= @data["geometry"]["coordinates"].last.to_f
+    end
+
+    def coordinates
+      [latitude, longitude]
+    end
+
+    def city
+      @data['context'].map {|c| c['text'] if c['id'] =~ /place/ }.compact.first || ''
+    end
+
+    def street
+      @data['properties']['address'] || ''
+    end
+
+    def state
+      @data['context'].map {|c| c['text'] if c['id'] =~ /region/ }.compact.first || ''
+    end
+
+    alias_method :state_code, :state
+
+    def postal_code
+      @data['context'].map {|c| c['text'] if c['id'] =~ /postcode/ }.compact.first  || ''
+    end
+
+    def country
+      @data['context'].map {|c| c['text'] if c['id'] =~ /country/ }.compact.first || ''
+    end
+
+    def country_code
+      country
+    end
+
+    def place_name
+      @data['text'] || ''
+    end
+
+    def address
+      [place_name, street, city, state, postal_code, country].reject{|s| s.length == 0 }.join(", ")
+    end
+  end
+end
+
diff --git a/test/fixtures/mapbox_invalid_api_key b/test/fixtures/mapbox_invalid_api_key
new file mode 100644
index 0000000000000000000000000000000000000000..41a8d6f4325761870ccf87ba03242ae80f1a4419
--- /dev/null
+++ b/test/fixtures/mapbox_invalid_api_key
@@ -0,0 +1,3 @@
+{
+    "message": "Not Authorized - Invalid Token"
+}
diff --git a/test/fixtures/mapbox_madison_square_garden b/test/fixtures/mapbox_madison_square_garden
new file mode 100644
index 0000000000000000000000000000000000000000..643ccb78d510c2ad162339eb0bc3c80ebb61b198
--- /dev/null
+++ b/test/fixtures/mapbox_madison_square_garden
@@ -0,0 +1,237 @@
+{
+    "attribution": "NOTICE: \u00a9 2015 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained.",
+    "features": [
+        {
+            "center": [
+                -73.991566,
+                40.749688
+            ],
+            "context": [
+                {
+                    "id": "neighborhood.12643",
+                    "text": "Garment District"
+                },
+                {
+                    "id": "place.37501",
+                    "text": "New York"
+                },
+                {
+                    "id": "postcode.573304472",
+                    "text": "10001"
+                },
+                {
+                    "id": "region.628083222",
+                    "text": "New York"
+                },
+                {
+                    "id": "country.4150104525",
+                    "text": "United States"
+                }
+            ],
+            "geometry": {
+                "coordinates": [
+                    -73.991566,
+                    40.749688
+                ],
+                "type": "Point"
+            },
+            "id": "poi.3734776765",
+            "place_name": "Madison Square Garden, 4 Penn Plz, New York, New York 10001, United States",
+            "properties": {
+                "address": "4 Penn Plz",
+                "category": "stadium, arena",
+                "maki": "baseball"
+            },
+            "relevance": 0.998,
+            "text": "Madison Square Garden",
+            "type": "Feature"
+        },
+        {
+            "center": [
+                -73.778678,
+                41.036928
+            ],
+            "context": [
+                {
+                    "id": "neighborhood.21227",
+                    "text": "Ferris Avenue"
+                },
+                {
+                    "id": "place.59673",
+                    "text": "White Plains"
+                },
+                {
+                    "id": "postcode.546749122",
+                    "text": "10607"
+                },
+                {
+                    "id": "region.628083222",
+                    "text": "New York"
+                },
+                {
+                    "id": "country.4150104525",
+                    "text": "United States"
+                }
+            ],
+            "geometry": {
+                "coordinates": [
+                    -73.778678,
+                    41.036928
+                ],
+                "type": "Point"
+            },
+            "id": "poi.4036603621",
+            "place_name": "Madison Square Garden, 198 Central Ave, White Plains, New York 10607, United States",
+            "properties": {
+                "address": "198 Central Ave",
+                "category": null,
+                "maki": null
+            },
+            "relevance": 0.996,
+            "text": "Madison Square Garden",
+            "type": "Feature"
+        },
+        {
+            "center": [
+                -73.983913,
+                40.739413
+            ],
+            "context": [
+                {
+                    "id": "neighborhood.21161",
+                    "text": "Gramercy-Flatiron"
+                },
+                {
+                    "id": "place.37501",
+                    "text": "New York"
+                },
+                {
+                    "id": "postcode.34207172",
+                    "text": "10010"
+                },
+                {
+                    "id": "region.628083222",
+                    "text": "New York"
+                },
+                {
+                    "id": "country.4150104525",
+                    "text": "United States"
+                }
+            ],
+            "geometry": {
+                "coordinates": [
+                    -73.983913,
+                    40.739413
+                ],
+                "type": "Point"
+            },
+            "id": "poi.3013644540",
+            "place_name": "United States Government Postal Service, 149 E 23rd St, New York, New York 10010, United States",
+            "properties": {
+                "address": "149 E 23rd St",
+                "category": "government agency,",
+                "maki": "town-hall"
+            },
+            "relevance": 0.748,
+            "text": "United States Government Postal Service",
+            "type": "Feature"
+        },
+        {
+            "center": [
+                -78.854005,
+                38.426163
+            ],
+            "context": [
+                {
+                    "id": "neighborhood.13118",
+                    "text": "Preston Heights"
+                },
+                {
+                    "id": "place.22836",
+                    "text": "Harrisonburg"
+                },
+                {
+                    "id": "postcode.912852583",
+                    "text": "22801"
+                },
+                {
+                    "id": "region.1248462799",
+                    "text": "Virginia"
+                },
+                {
+                    "id": "country.4150104525",
+                    "text": "United States"
+                }
+            ],
+            "geometry": {
+                "coordinates": [
+                    -78.854005,
+                    38.426163
+                ],
+                "type": "Point"
+            },
+            "id": "poi.2867869361",
+            "place_name": "Madison Square Garden, 420 Neff Ave, Harrisonburg, Virginia 22801, United States",
+            "properties": {
+                "address": "420 Neff Ave",
+                "category": "insurance",
+                "maki": "commercial"
+            },
+            "relevance": 0.74,
+            "text": "Madison Square Garden",
+            "type": "Feature"
+        },
+        {
+            "center": [
+                -85.384994,
+                40.196998
+            ],
+            "context": [
+                {
+                    "id": "neighborhood.2355",
+                    "text": "Creston"
+                },
+                {
+                    "id": "place.36166",
+                    "text": "Muncie"
+                },
+                {
+                    "id": "postcode.4261634171",
+                    "text": "47305"
+                },
+                {
+                    "id": "region.3248846408",
+                    "text": "Indiana"
+                },
+                {
+                    "id": "country.4150104525",
+                    "text": "United States"
+                }
+            ],
+            "geometry": {
+                "coordinates": [
+                    -85.384994,
+                    40.196998
+                ],
+                "type": "Point"
+            },
+            "id": "poi.1361420161",
+            "place_name": "Madison Square Garden, 211 E Wysor St, Muncie, Indiana 47305, United States",
+            "properties": {
+                "address": "211 E Wysor St",
+                "category": "restaurant",
+                "maki": "restaurant"
+            },
+            "relevance": 0.74,
+            "text": "Madison Square Garden",
+            "type": "Feature"
+        }
+    ],
+    "query": [
+        "madison",
+        "square",
+        "garden",
+        "ny"
+    ],
+    "type": "FeatureCollection"
+}
diff --git a/test/fixtures/mapbox_no_results b/test/fixtures/mapbox_no_results
new file mode 100644
index 0000000000000000000000000000000000000000..ff814f902e90d3e596bac8d9ae7534ccfe7f9e09
--- /dev/null
+++ b/test/fixtures/mapbox_no_results
@@ -0,0 +1,8 @@
+{
+    "attribution": "NOTICE: \u00a9 2015 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained.",
+    "features": [],
+    "query": [
+        "No Results"
+    ],
+    "type": "FeatureCollection"
+}
diff --git a/test/unit/lookup_test.rb b/test/unit/lookup_test.rb
index 5b6b4605d7d5a1e85d9341c169d3518c9e8629fc..45279ddd383923cfe3e20cee0beb3bf336d0f44c 100644
--- a/test/unit/lookup_test.rb
+++ b/test/unit/lookup_test.rb
@@ -24,7 +24,7 @@ class LookupTest < GeocoderTestCase
 
   def test_query_url_contains_values_in_params_hash
     Geocoder::Lookup.all_services_except_test.each do |l|
-      next if [:freegeoip, :maxmind_local, :telize, :pointpin, :geoip2, :maxmind_geoip2].include? l # does not use query string
+      next if [:freegeoip, :maxmind_local, :telize, :pointpin, :geoip2, :maxmind_geoip2, :mapbox].include? l # does not use query string
       set_api_key!(l)
       url = Geocoder::Lookup.get(l).query_url(Geocoder::Query.new(
         "test", :params => {:one_in_the_hand => "two in the bush"}
diff --git a/test/unit/lookups/mapbox_test.rb b/test/unit/lookups/mapbox_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b5fb73f7f82ff8e5f3da8d62d01c7f0292e708e
--- /dev/null
+++ b/test/unit/lookups/mapbox_test.rb
@@ -0,0 +1,33 @@
+# encoding: utf-8
+require 'test_helper'
+
+class MapboxTest < GeocoderTestCase
+
+  def setup
+    Geocoder.configure(lookup: :mapbox)
+    set_api_key!(:mapbox)
+  end
+
+  def test_url_contains_api_key
+    Geocoder.configure(mapbox: {api_key: "abc123"})
+    query = Geocoder::Query.new("Leadville, CO")
+    assert_equal "https://api.mapbox.com/geocoding/v5/mapbox.places/Leadville%2C+CO.json?access_token=abc123", query.url
+  end
+
+  def test_result_components
+    result = Geocoder.search("Madison Square Garden, New York, NY").first
+    assert_equal "10001", result.postal_code
+    assert_equal "Madison Square Garden, 4 Penn Plz, New York, New York, 10001, United States", result.address
+  end
+
+  def test_no_results
+    assert_equal [], Geocoder.search("no results")
+  end
+
+  def test_raises_exception_with_invalid_api_key
+    Geocoder.configure(always_raise: [Geocoder::InvalidApiKey])
+    assert_raises Geocoder::InvalidApiKey do
+      Geocoder.search("invalid API key")
+    end
+  end
+end