diff --git a/datadog-tracing.cabal b/datadog-tracing.cabal
--- a/datadog-tracing.cabal
+++ b/datadog-tracing.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                datadog-tracing
-version:             1.0.1
+version:             1.1.0
 synopsis:            Datadog tracing client and mock agent.
 license:             BSD-3-Clause
 license-file:        LICENSE
diff --git a/library/Datadog/Agent.hs b/library/Datadog/Agent.hs
--- a/library/Datadog/Agent.hs
+++ b/library/Datadog/Agent.hs
@@ -108,8 +108,17 @@
          <*> v .:? "metrics" .!= Nothing
          <*> v .:? "type" .!= Nothing
 
--- The meaning of this is ambiguous: https://github.com/DataDog/datadog-agent/issues/3031
--- The Double is always in the range [0.0, 1.0]
+-- "rate" is a number between `[0.0, 1.0]` indicating the desired percentage of
+-- traces that the agent wishes to downsample for a given service (`0.0` meaning
+-- dropping everything, `1.0` meaning keeping everything).
+--
+-- Clients should act upon `rate` by setting a `_sampling_priority_v1` field in
+-- `metrics` of the root span, which is an enum `[-1, 0, 1, 2]` indicating:
+--
+--    -1) the agent should drop the trace
+--     0) the agent may drop the trace
+--     1) the agent should try to keep the trace
+--     2) the agent must keep the trace (subject to account limits).
 data TraceResponse = TraceResponse
   { trRateByService :: Map Text Double
   }
diff --git a/library/Datadog/Client.hs b/library/Datadog/Client.hs
--- a/library/Datadog/Client.hs
+++ b/library/Datadog/Client.hs
@@ -12,7 +12,7 @@
 module Datadog.Client where
 
 import           Control.Monad             (unless, void)
-import           Data.Char                 (isAlpha, isAlphaNum)
+import           Data.Char                 (isAlpha, isAsciiLower, isDigit)
 import           Data.Int                  (Int64)
 import qualified Data.List.NonEmpty        as NEL
 import           Data.Map.Strict           (Map)
@@ -34,7 +34,7 @@
 
 newtype SpanId = SpanId (Refined NonZero Word64)
 newtype TraceId = TraceId (Refined NonZero Word64)
-newtype ServiceName = ServiceName (Refined (DDText && AlphaNum) Text)
+newtype ServiceName = ServiceName (Refined (DDText && Tag) Text)
 
 data Trace = Trace
   { tService :: ServiceName
@@ -43,7 +43,7 @@
   }
 
 newtype SpanName = SpanName (Refined (DDText && HasAlpha) Text)
-newtype MetaKey = MetaKey (Refined (DDText && AlphaNum) Text)
+newtype MetaKey = MetaKey (Refined (DDText && Tag) Text) deriving (Eq, Ord)
 newtype MetaValue = MetaValue (Refined DDText Text)
 
 data Span = Span
@@ -97,9 +97,17 @@
       let (nanos, _) = properFraction (1000000000 * time)
       in  nanos
 
-data AlphaNum
-instance Predicate AlphaNum Text where
-   validate p txt = validate' p (T.all isAlphaNum) txt
+data Tag
+instance Predicate Tag Text where
+   validate p txt = validate' p (T.all isValidChar) txt
+                    where
+                      -- dumbed down `normalizeTag`
+                      isValidChar c = case c of
+                        ':' -> True
+                        '.' -> True
+                        '/' -> True
+                        '-' -> True
+                        c'  -> isAsciiLower c' || isDigit c'
 
 data HasAlpha
 instance Predicate HasAlpha Text where
