diff --git a/geomet/wkb.py b/geomet/wkb.py
index a132adf..0552303 100644
--- a/geomet/wkb.py
+++ b/geomet/wkb.py
@@ -27,6 +27,9 @@
 #: '\x01': The first byte of any WKB string. Indicates little endian byte
 #: ordering for the data.
 LITTLE_ENDIAN = b'\x01'
+#: High byte in a 4-byte geometry type field to indicate that a 4-byte SRID
+#: field follows.
+SRID_FLAG = b'\x20'
 
 #: Mapping of GeoJSON geometry types to the "2D" 4-byte binary string
 #: representation for WKB. "2D" indicates that the geometry is 2-dimensional,
@@ -104,6 +107,46 @@
 _INT_TO_DIM_LABEL = {2: '2D', 3: 'Z', 4: 'ZM'}
 
 
+def _get_geom_type(type_bytes):
+    """Get the GeoJSON geometry type label from a WKB type byte string.
+
+    :param type_bytes:
+        4 byte string in big endian byte order containing a WKB type number.
+        It may also contain a "has SRID" flag in the high byte (the first type,
+        since this is big endian byte order), indicated as 0x20. If the SRID
+        flag is not set, the high byte will always be null (0x00).
+    :returns:
+        3-tuple ofGeoJSON geometry type label, the bytes resprenting the
+        geometry type, and a separate "has SRID" flag. If the input
+        `type_bytes` contains an SRID flag, it will be removed.
+
+        >>> # Z Point, with SRID flag
+        >>> _get_geom_type(b'\\x20\\x00\\x03\\xe9') == (
+        ... 'Point', b'\\x00\\x00\\x03\\xe9', True)
+        True
+
+        >>> # 2D MultiLineString, without SRID flag
+        >>> _get_geom_type(b'\\x00\\x00\\x00\\x05') == (
+        ... 'MultiLineString', b'\\x00\\x00\\x00\\x05', False)
+        True
+
+    """
+    # slice off the high byte, which may contain the SRID flag
+    high_byte = type_bytes[0]
+    if six.PY3:
+        high_byte = bytes([high_byte])
+    has_srid = high_byte == b'\x20'
+    if has_srid:
+        # replace the high byte with a null byte
+        type_bytes = as_bin_str(b'\x00' + type_bytes[1:])
+    else:
+        type_bytes = as_bin_str(type_bytes)
+
+    # look up the geometry type
+    geom_type = _BINARY_TO_GEOM_TYPE.get(type_bytes)
+    return geom_type, type_bytes, has_srid
+
+
 def dump(obj, dest_file):
     """
     Dump GeoJSON-like `dict` to WKB and write it to the `dest_file`.
@@ -169,6 +212,9 @@ def dumps(obj, big_endian=True):
     :param bool big_endian:
         Defaults to `True`. If `True`, data values in the generated WKB will
         be represented using big endian byte order. Else, little endian.
+
+    TODO: remove this
+
     :param str dims:
         Indicates to WKB representation desired from converting the given
         GeoJSON `dict` ``obj``. The accepted values are:
@@ -182,6 +228,7 @@ def dumps(obj, big_endian=True):
         A WKB binary string representing of the ``obj``.
     """
     geom_type = obj['type']
+    meta = obj.get('meta', {})
 
     exporter = _dumps_registry.get(geom_type)
     if exporter is None:
@@ -196,7 +243,7 @@ def dumps(obj, big_endian=True):
             'dimensionality of the WKB would be ambiguous.'
         )
 
-    return exporter(obj, big_endian)
+    return exporter(obj, big_endian, meta)
 
 
 def loads(string):
@@ -214,13 +261,19 @@ def loads(string):
         raise ValueError("Invalid endian byte: '0x%s'. Expected 0x00 or 0x01"
                          % binascii.hexlify(endianness.encode()).decode())
 
+    endian_token = '>' if big_endian else '<'
     # type_bytes = string[1:5]
     type_bytes = as_bin_str(take(4, string))
     if not big_endian:
         # To identify the type, order the type bytes in big endian:
         type_bytes = type_bytes[::-1]
 
-    geom_type = _BINARY_TO_GEOM_TYPE.get(type_bytes)
+    geom_type, type_bytes, has_srid = _get_geom_type(type_bytes)
+    srid = None
+    if has_srid:
+        srid_field = as_bin_str(take(4, string))
+        [srid] = struct.unpack('%si' % endian_token, srid_field)
+
     # data_bytes = string[5:]  # FIXME: This won't work for GeometryCollections
     data_bytes = string
 
@@ -230,14 +283,18 @@ def loads(string):
         _unsupported_geom_type(geom_type)
 
     data_bytes = iter(data_bytes)
-    return importer(big_endian, type_bytes, data_bytes)
+    result = importer(big_endian, type_bytes, data_bytes)
+    if has_srid:
+        result['meta'] = {'srid': str(srid)}
+    return result
 
 
 def _unsupported_geom_type(geom_type):
     raise ValueError("Unsupported geometry type '%s'" % geom_type)
 
 
-def _header_bytefmt_byteorder(geom_type, num_dims, big_endian):
+# TODO: dont default meta to none
+def _header_bytefmt_byteorder(geom_type, num_dims, big_endian, meta=None):
     """
     Utility function to get the WKB header (endian byte + type header), byte
     format string, and byte order string.
@@ -247,6 +304,10 @@ def _header_bytefmt_byteorder(geom_type, num_dims, big_endian):
         pass  # TODO: raise
 
     type_byte_str = _WKB[dim][geom_type]
+    srid = meta.get('srid')
+    if srid is not None:
+        # Add the srid flag
+        type_byte_str = SRID_FLAG + type_byte_str[1:]
 
     if big_endian:
         header = BIG_ENDIAN
@@ -260,12 +321,20 @@ def _header_bytefmt_byteorder(geom_type, num_dims, big_endian):
         type_byte_str = type_byte_str[::-1]
 
     header += type_byte_str
+    if srid is not None:
+        srid = int(srid)
+
+        if big_endian:
+            srid_header = struct.pack('>i', srid)
+        else:
+            srid_header = struct.pack('<i', srid)
+        header += srid_header
     byte_fmt += b'd' * num_dims
 
     return header, byte_fmt, byte_order
 
 
-def _dump_point(obj, big_endian):
+def _dump_point(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a point WKB string.
 
@@ -274,6 +343,17 @@ def _dump_point(obj, big_endian):
     :param bool big_endian:
         If `True`, data values in the generated WKB will be represented using
         big endian byte order. Else, little endian.
+    :param dict meta:
+        Metadata associated with the GeoJSON object. Currently supported
+        metadata:
+
+        - srid: Used to support EWKT/EWKB. For example, ``meta`` equal to
+          ``{'srid': '4326'}`` indicates that the geometry is defined using
+          Extended WKT/WKB and that it bears a Spatial Reference System
+          Identifier of 4326. This ID will be encoded into the resulting
+          binary.
+
+        Any other meta data objects will simply be ignored by this function.
 
     :returns:
         A WKB binary string representing of the Point ``obj``.
@@ -282,14 +362,14 @@ def _dump_point(obj, big_endian):
     num_dims = len(coords)
 
     wkb_string, byte_fmt, _ = _header_bytefmt_byteorder(
-        'Point', num_dims, big_endian
+        'Point', num_dims, big_endian, meta
     )
 
     wkb_string += struct.pack(byte_fmt, *coords)
     return wkb_string
 
 
-def _dump_linestring(obj, big_endian):
+def _dump_linestring(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a linestring WKB string.
 
@@ -301,7 +381,7 @@ def _dump_linestring(obj, big_endian):
     num_dims = len(vertex)
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'LineString', num_dims, big_endian
+        'LineString', num_dims, big_endian, meta
     )
     # append number of vertices in linestring
     wkb_string += struct.pack('%sl' % byte_order, len(coords))
@@ -312,7 +392,7 @@ def _dump_linestring(obj, big_endian):
     return wkb_string
 
 
-def _dump_polygon(obj, big_endian):
+def _dump_polygon(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a polygon WKB string.
 
@@ -324,7 +404,7 @@ def _dump_polygon(obj, big_endian):
     num_dims = len(vertex)
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'Polygon', num_dims, big_endian
+        'Polygon', num_dims, big_endian, meta
     )
 
     # number of rings:
@@ -338,7 +418,7 @@ def _dump_polygon(obj, big_endian):
     return wkb_string
 
 
-def _dump_multipoint(obj, big_endian):
+def _dump_multipoint(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a multipoint WKB string.
 
@@ -349,7 +429,7 @@ def _dump_multipoint(obj, big_endian):
     num_dims = len(vertex)
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'MultiPoint', num_dims, big_endian
+        'MultiPoint', num_dims, big_endian, meta
     )
 
     point_type = _WKB[_INT_TO_DIM_LABEL.get(num_dims)]['Point']
@@ -367,7 +447,7 @@ def _dump_multipoint(obj, big_endian):
     return wkb_string
 
 
-def _dump_multilinestring(obj, big_endian):
+def _dump_multilinestring(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a multilinestring WKB string.
 
@@ -378,7 +458,7 @@ def _dump_multilinestring(obj, big_endian):
     num_dims = len(vertex)
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'MultiLineString', num_dims, big_endian
+        'MultiLineString', num_dims, big_endian, meta
     )
 
     ls_type = _WKB[_INT_TO_DIM_LABEL.get(num_dims)]['LineString']
@@ -400,7 +480,7 @@ def _dump_multilinestring(obj, big_endian):
     return wkb_string
 
 
-def _dump_multipolygon(obj, big_endian):
+def _dump_multipolygon(obj, big_endian, meta):
     """
     Dump a GeoJSON-like `dict` to a multipolygon WKB string.
 
@@ -411,7 +491,7 @@ def _dump_multipolygon(obj, big_endian):
     num_dims = len(vertex)
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'MultiPolygon', num_dims, big_endian
+        'MultiPolygon', num_dims, big_endian, meta
     )
 
     poly_type = _WKB[_INT_TO_DIM_LABEL.get(num_dims)]['Polygon']
@@ -437,7 +517,7 @@ def _dump_multipolygon(obj, big_endian):
     return wkb_string
 
 
-def _dump_geometrycollection(obj, big_endian):
+def _dump_geometrycollection(obj, big_endian, meta):
     # TODO: handle empty collections
     geoms = obj['geometries']
     # determine the dimensionality (2d, 3d, 4d) of the collection
@@ -458,7 +538,7 @@ def _dump_geometrycollection(obj, big_endian):
         num_dims = 4
 
     wkb_string, byte_fmt, byte_order = _header_bytefmt_byteorder(
-        'GeometryCollection', num_dims, big_endian
+        'GeometryCollection', num_dims, big_endian, meta
     )
     # append the number of geometries
     wkb_string += struct.pack('%sl' % byte_order, len(geoms))
diff --git a/geomet/wkt.py b/geomet/wkt.py
index 3120198..3f5576a 100644
--- a/geomet/wkt.py
+++ b/geomet/wkt.py
@@ -77,7 +77,20 @@ def dumps(obj, decimals=16):
         raise geomet.InvalidGeoJSONException('Invalid GeoJSON: %s' % obj)
 
     fmt = '%%.%df' % decimals
-    return exporter(obj, fmt)
+    result = exporter(obj, fmt)
+    srid = obj.get('meta', {}).get('srid')
+    if srid is not None:
+        # Prepend the SRID
+        result = 'SRID=%s;%s' % (srid, result)
+    return result
+
+
+def _assert_next_token(sequence, expected):
+    next_token = next(sequence)
+    if not next_token == expected:
+        raise ValueError(
+            'Expected "%s" but found "%s"' % (expected, next_token)
+        )
 
 
 def loads(string):
@@ -88,7 +101,23 @@ def loads(string):
     # NOTE: This is not the intended purpose of `tokenize`, but it works.
     tokens = (x[1] for x in tokenize.generate_tokens(sio.readline))
     tokens = _tokenize_wkt(tokens)
-    geom_type = next(tokens)
+    geom_type_or_srid = next(tokens)
+    srid = None
+    geom_type = geom_type_or_srid
+    if geom_type_or_srid == 'SRID':
+        # The geometry WKT contains an SRID header.
+        _assert_next_token(tokens, '=')
+        srid = next(tokens)
+        try:
+            # Make sure the SRID is an integer. If not, it's invalid.
+            int(srid)
+        except ValueError:
+            raise ValueError('SRID must be an integer. Got: "%s"' % srid)
+        _assert_next_token(tokens, ';')
+        # We expected the geometry type to be next:
+        geom_type = next(tokens)
+    else:
+        geom_type = geom_type_or_srid
 
     importer = _loads_registry.get(geom_type)
 
@@ -105,7 +134,10 @@ def loads(string):
 
     # Put the peeked element back on the head of the token generator
     tokens = itertools.chain([peek], tokens)
-    return importer(tokens, string)
+    result = importer(tokens, string)
+    if srid is not None:
+        result['meta'] = dict(srid=srid)
+    return result
 
 
 def _tokenize_wkt(tokens):
