diff --git a/mapbox/errors.py b/mapbox/errors.py
index 005796a..95d982f 100644
--- a/mapbox/errors.py
+++ b/mapbox/errors.py
@@ -46,14 +46,22 @@ class InvalidParameterError(ValidationError):
 class InvalidFileError(ValidationError):
     pass
 
+
 class InvalidResourceTypeError(ValidationError):
     pass
-        
+
+
 class InvalidPeriodError(ValidationError):
     pass
 
+
 class InvalidUsernameError(ValidationError):
     pass
 
+
 class InvalidId(ValidationError):
     pass
+
+
+class MapboxDeprecationWarning(UserWarning):
+    pass
diff --git a/mapbox/services/static.py b/mapbox/services/static.py
index fe5a9fb..235a238 100644
--- a/mapbox/services/static.py
+++ b/mapbox/services/static.py
@@ -40,7 +40,8 @@ class Static(Service):
         return val
 
     def image(self, mapid, lon=None, lat=None, z=None, features=None,
-              width=600, height=600, image_format='png256', sort_keys=False):
+              width=600, height=600, image_format='png256', sort_keys=False,
+              retina=False):
 
         if lon is not None and lat is not None and z is not None:
             auto = False
@@ -58,8 +59,7 @@ class Static(Service):
             lat=str(lat),
             z=str(z),
             width=str(width),
-            height=str(height),
-            fmt=image_format)
+            height=str(height))
 
         if features:
             collection = normalize_geojson_featurecollection(features)
@@ -69,19 +69,25 @@ class Static(Service):
             self._validate_overlay(values['overlay'])
 
             if auto:
-                pth = '/{mapid}/geojson({overlay})/auto/{width}x{height}.{fmt}'
+                pth = '/{mapid}/geojson({overlay})/auto/{width}x{height}'
             else:
                 pth = ('/{mapid}/geojson({overlay})/{lon},{lat},{z}'
-                       '/{width}x{height}.{fmt}')
+                       '/{width}x{height}')
         else:
             if auto:
                 raise errors.InvalidCoordError(
                     "Must provide features if lat, lon, z are None")
 
             # No overlay
-            pth = '/{mapid}/{lon},{lat},{z}/{width}x{height}.{fmt}'
+            pth = '/{mapid}/{lon},{lat},{z}/{width}x{height}'
 
         uri = URITemplate(self.baseuri + pth).expand(**values)
+
+        # @2x.format handled separately to avoid HTML escaping the ampersand
+        twox = '@2x' if retina else ''
+        full_fmt = '{0}.{1}'.format(twox, image_format)
+        uri += full_fmt
+
         res = self.session.get(uri)
         self.handle_http_error(res)
         return res
diff --git a/mapbox/services/static_style.py b/mapbox/services/static_style.py
index 50eb0b5..b0cef3a 100644
--- a/mapbox/services/static_style.py
+++ b/mapbox/services/static_style.py
@@ -1,4 +1,5 @@
 import json
+import warnings
 
 from uritemplate import URITemplate
 
@@ -61,13 +62,13 @@ class StaticStyle(Service):
             raise errors.ImageSizeError('tile_size must be 256 or 512 pixels')
 
         pth = '/{username}/{style_id}/tiles/{tile_size}/{z}/{x}/{y}'
-        if retina:
-            pth += '@2x'
 
         values = dict(username=username, style_id=style_id,
                       tile_size=tile_size, z=z, x=x, y=y)
 
         uri = URITemplate(self.baseuri + pth).expand(**values)
+        if retina:
+            uri += '@2x'
         res = self.session.get(uri)
         self.handle_http_error(res)
         return res
@@ -80,8 +81,8 @@ class StaticStyle(Service):
         return res
 
     def image(self, username, style_id, lon=None, lat=None, zoom=None, features=None,
-              pitch=0, bearing=0, width=600, height=600, twox=False, sort_keys=False,
-              attribution=None, logo=None, before_layer=None):
+              pitch=0, bearing=0, width=600, height=600, retina=None, sort_keys=False,
+              attribution=None, logo=None, before_layer=None, twox=None):
 
         params = {}
         if attribution is not None:
@@ -91,6 +92,16 @@ class StaticStyle(Service):
         if before_layer is not None:
             params['before_layer'] = before_layer
 
+        # twox as a deprecated alias for retina
+        if retina is None:
+            if twox is not None:
+                warnings.warn('twox is a deprecated alias for retina',
+                              errors.MapboxDeprecationWarning)
+                retina = twox
+        else:
+            if twox is not None:
+                raise errors.ValidationError('Conflicting args; Remove twox and use retina')
+
         if lon is not None and lat is not None and zoom is not None:
             auto = False
             lat = validate_lat(lat)
@@ -112,7 +123,6 @@ class StaticStyle(Service):
             lat=str(lat),
             zoom=str(zoom),
             auto=auto,
-            twox='@2x' if twox else '',
             width=str(width),
             height=str(height))
 
@@ -126,9 +136,9 @@ class StaticStyle(Service):
             pth = '/{username}/{style_id}/static/geojson({overlay})/'
             if auto:
                 # TODO what about {bearing} and {pitch}
-                pth += 'auto/{width}x{height}{twox}'
+                pth += 'auto/{width}x{height}'
             else:
-                pth += '{lon},{lat},{zoom},{bearing},{pitch}/{width}x{height}{twox}'
+                pth += '{lon},{lat},{zoom},{bearing},{pitch}/{width}x{height}'
         else:
             if auto:
                 raise errors.InvalidCoordError(
@@ -136,9 +146,14 @@ class StaticStyle(Service):
 
             # No overlay
             pth = ('/{username}/{style_id}/static/'
-                   '{lon},{lat},{zoom},{bearing},{pitch}/{width}x{height}{twox}')
+                   '{lon},{lat},{zoom},{bearing},{pitch}/{width}x{height}')
 
         uri = URITemplate(self.baseuri + pth).expand(**values)
+
+        # @2x handled separately to avoid HTML escaping the ampersand
+        if retina:
+            uri += '@2x'
+
         res = self.session.get(uri, params=params)
         self.handle_http_error(res)
         return res

Retina with Static Api? 
Hello, it seems I can't choose the retina format for my static generated maps.

If I look in the code:

` if auto:
pth = '/{mapid}/geojson({overlay})/auto/{width}x{height}.{fmt}'`

But if I look at the global documentation, the url scheme is `{width}x{height}@2x.{fmt}`

So the is not the possibility to add retina images here?
diff --git a/tests/test_staticmaps.py b/tests/test_staticmaps.py
index 4e582d4..cb325bf 100644
--- a/tests/test_staticmaps.py
+++ b/tests/test_staticmaps.py
@@ -104,6 +104,7 @@ def test_staticmap_featurestoolarge(points):
     with pytest.raises(mapbox.errors.ValidationError):
         service._validate_overlay(json.dumps(points * 100))
 
+
 def test_staticmap_imagesize():
     service = mapbox.Static(access_token='pk.test')
     with pytest.raises(mapbox.errors.ValidationError):
@@ -111,14 +112,32 @@ def test_staticmap_imagesize():
     with pytest.raises(mapbox.errors.ValidationError):
         service._validate_image_size(2000)
 
+
 def test_latlon():
     service = mapbox.Static(access_token='pk.test')
     assert -179.0 == service._validate_lon(-179.0)
     assert -85.0 == service._validate_lat(-85.0)
 
+
 def test_lon_invalid():
     service = mapbox.Static(access_token='pk.test')
     with pytest.raises(mapbox.errors.ValidationError):
         service._validate_lat(-86.0)
     with pytest.raises(mapbox.errors.ValidationError):
         service._validate_lon(-181.0)
+
+
+@responses.activate
+def test_staticmap_retina():
+
+    responses.add(
+        responses.GET,
+        'https://api.mapbox.com/v4/mapbox.satellite/-61.7,12.1,12/600x600@2x.png256?access_token=pk.test',
+        match_querystring=True,
+        body='png123',
+        status=200,
+        content_type='image/png')
+
+    res = mapbox.Static(access_token='pk.test').image(
+        'mapbox.satellite', -61.7, 12.1, 12, retina=True)
+    assert res.status_code == 200
diff --git a/tests/test_staticstyle.py b/tests/test_staticstyle.py
index 1d89344..6cf9941 100644
--- a/tests/test_staticstyle.py
+++ b/tests/test_staticstyle.py
@@ -184,7 +184,7 @@ def test_bad_tilesize():
 
 
 @responses.activate
-def test_staticmap_tile():
+def test_staticmap_tile_retina():
 
     responses.add(
         responses.GET,
@@ -212,3 +212,44 @@ def test_staticmap_wmts():
 
     res = mapbox.StaticStyle(access_token='pk.test').wmts('mapbox', 'streets-v9')
     assert res.status_code == 200
+
+
+@responses.activate
+def test_staticmap_retina():
+
+    responses.add(
+        responses.GET,
+        'https://api.mapbox.com/styles/v1/mapbox/streets-v9/static/-61.7,12.1,12.5,75,25/600x600@2x?access_token=pk.test',
+        match_querystring=True,
+        body='png123',
+        status=200,
+        content_type='image/png')
+
+    res = mapbox.StaticStyle(access_token='pk.test').image(
+        'mapbox', 'streets-v9', -61.7, 12.1, 12.5, pitch=25,
+        bearing=75, retina=True)
+    assert res.status_code == 200
+
+
+@responses.activate
+def test_staticmap_twox_deprecated():
+    responses.add(
+        responses.GET,
+        'https://api.mapbox.com/styles/v1/mapbox/streets-v9/static/-61.7,12.1,12.5,75,25/600x600@2x?access_token=pk.test',
+        match_querystring=True,
+        body='png123',
+        status=200,
+        content_type='image/png')
+
+    with pytest.warns(mapbox.errors.MapboxDeprecationWarning):
+        res = mapbox.StaticStyle(access_token='pk.test').image(
+            'mapbox', 'streets-v9', -61.7, 12.1, 12.5, pitch=25,
+            bearing=75, twox=True)
+    assert res.status_code == 200
+
+
+def test_staticmap_twox_deprecated_error():
+    with pytest.raises(mapbox.errors.ValidationError):
+        mapbox.StaticStyle(access_token='pk.test').image(
+            'mapbox', 'streets-v9', -61.7, 12.1, 12.5, pitch=25,
+            bearing=75, retina=True, twox=True)

pip install -e .[test]
parse_log_pytest
pytest
pytest pytest-cov responses tox
apt-get update apt-get install -y gcc
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
boto3==1.23.10
botocore==1.26.10
CacheControl==0.12.14
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
click-plugins==1.1.1
cligj==0.7.2
coverage==6.2
coveralls==3.3.1
distlib==0.3.9
docopt==0.6.2
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
iso3166==2.1.1
jmespath==0.10.0
-e git+https://github.com/mapbox/mapbox-sdk-py.git@ac54c0dd453c61020f1f42eafdc3af34a7664718#egg=mapbox
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
msgpack==1.0.5
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
platformdirs==2.4.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
polyline==1.4.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
requests==2.27.1
responses==0.17.0
s3transfer==0.5.2
six==1.17.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tomli==1.2.3
tox==3.28.0
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
uritemplate==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: mapbox-sdk-py
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - boto3==1.23.10
      - botocore==1.26.10
      - cachecontrol==0.12.14
      - charset-normalizer==2.0.12
      - click==8.0.4
      - click-plugins==1.1.1
      - cligj==0.7.2
      - coverage==6.2
      - coveralls==3.3.1
      - distlib==0.3.9
      - docopt==0.6.2
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iso3166==2.1.1
      - jmespath==0.10.0
      - msgpack==1.0.5
      - platformdirs==2.4.0
      - polyline==1.4.0
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - requests==2.27.1
      - responses==0.17.0
      - s3transfer==0.5.2
      - six==1.17.0
      - tomli==1.2.3
      - tox==3.28.0
      - uritemplate==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
prefix: /opt/conda/envs/mapbox-sdk-py

tests/test_staticmaps.py::test_staticmap_retina tests/test_staticstyle.py::test_staticmap_retina tests/test_staticstyle.py::test_staticmap_twox_deprecated tests/test_staticstyle.py::test_staticmap_twox_deprecated_error
tests/test_staticmaps.py::test_staticmap_lonlatz_only tests/test_staticmaps.py::test_staticmap_lonlatz_features tests/test_staticmaps.py::test_staticmap_auto_features tests/test_staticmaps.py::test_staticmap_auto_nofeatures tests/test_staticmaps.py::test_staticmap_featurestoolarge tests/test_staticmaps.py::test_staticmap_imagesize tests/test_staticmaps.py::test_latlon tests/test_staticmaps.py::test_lon_invalid tests/test_staticstyle.py::test_staticmap_lonlatzpitchbearing tests/test_staticstyle.py::test_staticmap_lonlatz_features tests/test_staticstyle.py::test_staticmap_auto_features tests/test_staticstyle.py::test_staticmap_auto_nofeatures tests/test_staticstyle.py::test_staticmap_featurestoolarge tests/test_staticstyle.py::test_staticmap_validate_bearing tests/test_staticstyle.py::test_staticmap_validate_pitch tests/test_staticstyle.py::test_staticmap_imagesize tests/test_staticstyle.py::test_latlon tests/test_staticstyle.py::test_lon_invalid tests/test_staticstyle.py::test_staticmap_options tests/test_staticstyle.py::test_staticmap_tile tests/test_staticstyle.py::test_bad_tilesize tests/test_staticstyle.py::test_staticmap_tile_retina tests/test_staticstyle.py::test_staticmap_wmts
mapbox/errors.py mapbox/services/static_style.py mapbox/services/static.py
mapbox/errors.py mapbox/services/static_style.py mapbox/services/static.py