diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+* 0.12.1 [2018-01-31]
+
+Add new functions for constructing a query URI where not all parts are escaped.
+
 * 0.12 [2018-01-28]
 
 URI encoding is now back to upper-case hexadecimal, as that is the preferred canonicalization, and the previous change caused issues with URI
diff --git a/Network/HTTP/Types.hs b/Network/HTTP/Types.hs
--- a/Network/HTTP/Types.hs
+++ b/Network/HTTP/Types.hs
@@ -170,6 +170,12 @@
 , renderSimpleQuery
 , parseQuery
 , parseSimpleQuery
+  -- **Escape only parts
+, renderQueryPartialEscape
+, renderQueryBuilderPartialEscape
+, EscapeItem(..)
+, PartialEscapeQueryItem
+, PartialEscapeQuery
   -- *** Text query string (UTF8 encoded)
 , QueryText
 , queryTextToQuery
diff --git a/Network/HTTP/Types/URI.hs b/Network/HTTP/Types/URI.hs
--- a/Network/HTTP/Types/URI.hs
+++ b/Network/HTTP/Types/URI.hs
@@ -12,6 +12,12 @@
 , renderSimpleQuery
 , parseQuery
 , parseSimpleQuery
+  -- **Escape only parts
+, renderQueryPartialEscape
+, renderQueryBuilderPartialEscape
+, EscapeItem(..)
+, PartialEscapeQueryItem
+, PartialEscapeQuery
   -- ** Text query string (UTF8 encoded)
 , QueryText
 , queryTextToQuery
@@ -323,3 +329,51 @@
 decodePath b =
     let (x, y) = B.break (== 63) b -- question mark
     in (decodePathSegments x, parseQuery y)
+
+-----------------------------------------------------------------------------------------
+
+-- | For some URIs characters must not be URI encoded,
+-- eg '+' or ':' in q=a+language:haskell+created:2009-01-01..2009-02-01&sort=stars
+-- The character list unreservedPI instead of unreservedQS would solve this.
+-- But we explicitly decide what part to encode.
+-- This is mandatory when searching for '+': q=%2B+language:haskell.
+data EscapeItem = QE B.ByteString -- will be URL encoded
+                | QN B.ByteString -- will not be url encoded, eg '+' or ':'
+    deriving (Show, Eq, Ord)
+
+-- | Query item
+type PartialEscapeQueryItem = (B.ByteString, [EscapeItem])
+
+-- | Query with some chars that should not be escaped.
+-- 
+-- General form: a=b&c=d:e+f&g=h
+type PartialEscapeQuery = [PartialEscapeQueryItem]
+
+-- | Convert 'PartialEscapeQuery' to 'ByteString'.
+renderQueryPartialEscape :: Bool -- ^ prepend question mark?
+            -> PartialEscapeQuery -> B.ByteString
+renderQueryPartialEscape qm = BL.toStrict . B.toLazyByteString . renderQueryBuilderPartialEscape qm
+
+-- | Convert 'PartialEscapeQuery' to a 'Builder'.
+renderQueryBuilderPartialEscape :: Bool -- ^ prepend a question mark?
+                   -> PartialEscapeQuery
+                   -> B.Builder
+renderQueryBuilderPartialEscape _ [] = mempty
+-- FIXME replace mconcat + map with foldr
+renderQueryBuilderPartialEscape qmark' (p:ps) = mconcat
+    $ go (if qmark' then qmark else mempty) p
+    : map (go amp) ps
+  where
+    qmark = B.byteString "?"
+    amp = B.byteString "&"
+    equal = B.byteString "="
+    go sep (k, mv) = mconcat [
+                      sep
+                     , urlEncodeBuilder True k
+                     , case mv of
+                         [] -> mempty
+                         vs -> equal `mappend` (mconcat (map encode vs))
+                     ]
+    encode (QE v) = urlEncodeBuilder True v
+    encode (QN v) = B.byteString v
+
diff --git a/http-types.cabal b/http-types.cabal
--- a/http-types.cabal
+++ b/http-types.cabal
@@ -1,5 +1,5 @@
 Name:                http-types
-Version:             0.12
+Version:             0.12.1
 Synopsis:            Generic HTTP types for Haskell (for both client and server code).
 Description:         Generic HTTP types for Haskell (for both client and server code).
 Homepage:            https://github.com/aristidb/http-types
@@ -16,7 +16,7 @@
 Source-repository this
   type: git
   location: https://github.com/aristidb/http-types.git
-  tag: 0.12
+  tag: 0.12.1
 
 Source-repository head
   type: git
