diff --git a/src/core/ext/census/gen/trace_context.pb.c b/src/core/ext/census/gen/trace_context.pb.c
index c8aea324cee638598ea86380dbcce2d94dd37832..f4126d4d807e5e4f879163fdbe5db50b1ce9e7fb 100644
--- a/src/core/ext/census/gen/trace_context.pb.c
+++ b/src/core/ext/census/gen/trace_context.pb.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,51 +31,24 @@
  *
  */
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.3.5-dev */
+/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
 
 #include "src/core/ext/census/gen/trace_context.pb.h"
 
+/* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #endif
 
 
 
-const pb_field_t google_trace_TraceId_fields[3] = {
-    PB_FIELD(  1, FIXED64 , OPTIONAL, STATIC  , FIRST, google_trace_TraceId, hi, hi, 0),
-    PB_FIELD(  2, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceId, lo, hi, 0),
+const pb_field_t google_trace_TraceContext_fields[5] = {
+    PB_FIELD(  1, FIXED64 , OPTIONAL, STATIC  , FIRST, google_trace_TraceContext, trace_id_hi, trace_id_hi, 0),
+    PB_FIELD(  2, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, trace_id_lo, trace_id_hi, 0),
+    PB_FIELD(  3, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, span_id, trace_id_lo, 0),
+    PB_FIELD(  4, FIXED32 , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, span_options, span_id, 0),
     PB_LAST_FIELD
 };
 
-const pb_field_t google_trace_TraceContext_fields[4] = {
-    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, google_trace_TraceContext, trace_id, trace_id, &google_trace_TraceId_fields),
-    PB_FIELD(  2, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, span_id, trace_id, 0),
-    PB_FIELD(  3, BOOL    , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, is_sampled, span_id, 0),
-    PB_LAST_FIELD
-};
-
-
-/* Check that field information fits in pb_field_t */
-#if !defined(PB_FIELD_32BIT)
-/* If you get an error here, it means that you need to define PB_FIELD_32BIT
- * compile-time option. You can do that in pb.h or on compiler command line.
- * 
- * The reason you need to do this is that some of your messages contain tag
- * numbers or field sizes that are larger than what can fit in 8 or 16 bit
- * field descriptors.
- */
-PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
-#endif
-
-#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
-/* If you get an error here, it means that you need to define PB_FIELD_16BIT
- * compile-time option. You can do that in pb.h or on compiler command line.
- * 
- * The reason you need to do this is that some of your messages contain tag
- * numbers or field sizes that are larger than what can fit in the default
- * 8 bit descriptors.
- */
-PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
-#endif
-
 
+/* @@protoc_insertion_point(eof) */
diff --git a/src/core/ext/census/gen/trace_context.pb.h b/src/core/ext/census/gen/trace_context.pb.h
index cfb2f04ccd231056d6558f5d8717cadb6a91aba9..ea127bf70a79ae21ab46cd4c7937f9de5c5dca9f 100644
--- a/src/core/ext/census/gen/trace_context.pb.h
+++ b/src/core/ext/census/gen/trace_context.pb.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,13 @@
  *
  */
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.5-dev */
+/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
 
 #ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
 #define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
 #include "third_party/nanopb/pb.h"
+
+/* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #endif
@@ -45,44 +47,35 @@ extern "C" {
 #endif
 
 /* Struct definitions */
-typedef struct _google_trace_TraceId {
-    bool has_hi;
-    uint64_t hi;
-    bool has_lo;
-    uint64_t lo;
-} google_trace_TraceId;
-
 typedef struct _google_trace_TraceContext {
-    bool has_trace_id;
-    google_trace_TraceId trace_id;
+    bool has_trace_id_hi;
+    uint64_t trace_id_hi;
+    bool has_trace_id_lo;
+    uint64_t trace_id_lo;
     bool has_span_id;
     uint64_t span_id;
-    bool has_is_sampled;
-    bool is_sampled;
+    bool has_span_options;
+    uint32_t span_options;
+/* @@protoc_insertion_point(struct:google_trace_TraceContext) */
 } google_trace_TraceContext;
 
 /* Default values for struct fields */
 
 /* Initializer values for message structs */
-#define google_trace_TraceId_init_default        {false, 0, false, 0}
-#define google_trace_TraceContext_init_default   {false, google_trace_TraceId_init_default, false, 0, false, 0}
-#define google_trace_TraceId_init_zero           {false, 0, false, 0}
-#define google_trace_TraceContext_init_zero      {false, google_trace_TraceId_init_zero, false, 0, false, 0}
+#define google_trace_TraceContext_init_default   {false, 0, false, 0, false, 0, false, 0}
+#define google_trace_TraceContext_init_zero      {false, 0, false, 0, false, 0, false, 0}
 
 /* Field tags (for use in manual encoding/decoding) */
-#define google_trace_TraceId_hi_tag              1
-#define google_trace_TraceId_lo_tag              2
-#define google_trace_TraceContext_trace_id_tag   1
-#define google_trace_TraceContext_span_id_tag    2
-#define google_trace_TraceContext_is_sampled_tag 3
+#define google_trace_TraceContext_trace_id_hi_tag 1
+#define google_trace_TraceContext_trace_id_lo_tag 2
+#define google_trace_TraceContext_span_id_tag    3
+#define google_trace_TraceContext_span_options_tag 4
 
 /* Struct field encoding specification for nanopb */
-extern const pb_field_t google_trace_TraceId_fields[3];
-extern const pb_field_t google_trace_TraceContext_fields[4];
+extern const pb_field_t google_trace_TraceContext_fields[5];
 
 /* Maximum encoded size of messages (where known) */
-#define google_trace_TraceId_size                18
-#define google_trace_TraceContext_size           31
+#define google_trace_TraceContext_size           32
 
 /* Message IDs (where set with "msgid" option) */
 #ifdef PB_MSGID
@@ -95,5 +88,6 @@ extern const pb_field_t google_trace_TraceContext_fields[4];
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
+/* @@protoc_insertion_point(eof) */
 
-#endif /* GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H */
+#endif
diff --git a/src/core/ext/census/trace_context.c b/src/core/ext/census/trace_context.c
index fbb20d3448f781cfe502268814ccb27e74f698ba..47d0de19daca4a87fb85a92583859efe409a8ff3 100644
--- a/src/core/ext/census/trace_context.c
+++ b/src/core/ext/census/trace_context.c
@@ -73,7 +73,7 @@ bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
   }
 
   // check fields
-  if (!ctxt->has_trace_id) {
+  if (!ctxt->has_trace_id_hi || !ctxt->has_trace_id_lo) {
     gpr_log(GPR_DEBUG, "Invalid TraceContext: missing trace_id");
     return false;
   }
diff --git a/src/core/ext/census/trace_context.h b/src/core/ext/census/trace_context.h
index 1cb5e26ea7a980e23530fa3a8dd62c099e506a52..f391a1b7c1c45adbacab0a0f62a30ce235fe7ae6 100644
--- a/src/core/ext/census/trace_context.h
+++ b/src/core/ext/census/trace_context.h
@@ -38,6 +38,9 @@
 
 #include "src/core/ext/census/gen/trace_context.pb.h"
 
+/* Span option flags. */
+#define SPAN_OPTIONS_IS_SAMPLED 0x01
+
 /* Maximum number of bytes required to encode a TraceContext (31)
 1 byte for trace_id field
 1 byte for trace_id length
diff --git a/src/proto/census/trace_context.proto b/src/proto/census/trace_context.proto
index a5d5a9595db621effdb399c6912fc1e15009c4bb..fc0a54d2ce614069251428b676c32b4a076327e2 100644
--- a/src/proto/census/trace_context.proto
+++ b/src/proto/census/trace_context.proto
@@ -31,18 +31,14 @@ syntax = "proto3";
 
 package google.trace;
 
-// A TraceId uniquely represents a single Trace. It is a 128-bit nonce.
-message TraceId {
-  fixed64 hi = 1;
-  fixed64 lo = 2;
-}
-
 // Tracing information that is propagated with RPC's.
 message TraceContext {
-  // Trace identifer. Must be present.
-  TraceId trace_id = 1;
-  // ID of parent (client) span. Must be present.
-  fixed64 span_id = 2;
-  // true if this trace is sampled.
-  bool is_sampled = 3;
+  // A TraceId uniquely represents a single Trace. It is a 128-bit nonce.
+  // The 128-bit ID is split into 2 64-bit chunks. (REQUIRED)
+  fixed64 trace_id_hi = 1;
+  fixed64 trace_id_lo = 2;
+  // ID of parent (client) span. (REQUIRED)
+  fixed64 span_id = 3;
+  // Span option flags. First bit is true if this trace is sampled. (OPTIONAL)
+  fixed32 span_options = 4;
 }
diff --git a/test/core/census/data/context_full.pb b/test/core/census/data/context_full.pb
index 80ebcf280bc5a358d595eb88ff84420bcfe9d11e..7b5895cbf163f53e8ade57ebb4a4b55b6a8f88d8 100644
Binary files a/test/core/census/data/context_full.pb and b/test/core/census/data/context_full.pb differ
diff --git a/test/core/census/data/context_full.txt b/test/core/census/data/context_full.txt
index 7901a10c33652293054c507dca9719bc0a537230..7d8df37ea1de6f25958e85390bd9e53c51d616ca 100644
--- a/test/core/census/data/context_full.txt
+++ b/test/core/census/data/context_full.txt
@@ -1,3 +1,4 @@
-trace_id { hi : 5; lo : 1 }
+trace_id_hi : 5
+trace_id_lo : 1
 span_id : 7
-is_sampled : true
+span_options : 1
diff --git a/test/core/census/data/context_no_sample.pb b/test/core/census/data/context_no_sample.pb
deleted file mode 100644
index ab7ad7d1091955636cfaa7e342d94497b717e55b..0000000000000000000000000000000000000000
Binary files a/test/core/census/data/context_no_sample.pb and /dev/null differ
diff --git a/test/core/census/data/context_no_sample.txt b/test/core/census/data/context_no_sample.txt
deleted file mode 100644
index 150298002fc2d0bbb4feaffde67606c2a865bbde..0000000000000000000000000000000000000000
--- a/test/core/census/data/context_no_sample.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-trace_id { hi : 5; lo : 1 }
-span_id : 7
diff --git a/test/core/census/data/context_no_span_options.pb b/test/core/census/data/context_no_span_options.pb
new file mode 100644
index 0000000000000000000000000000000000000000..4b3425ac01783b7cd278411a8dee20ffafe2d8e1
Binary files /dev/null and b/test/core/census/data/context_no_span_options.pb differ
diff --git a/test/core/census/data/context_no_span_options.txt b/test/core/census/data/context_no_span_options.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4c8398ffd030ec83f2a4d92dbfe71317de521b00
--- /dev/null
+++ b/test/core/census/data/context_no_span_options.txt
@@ -0,0 +1,3 @@
+trace_id_hi : 5
+trace_id_lo : 1
+span_id : 7
diff --git a/test/core/census/data/context_span_only.pb b/test/core/census/data/context_span_only.pb
index 2a9527a75a6ddb2ea7a17d096ad5c70615512819..a9315be91a2611c6869fff527b2646942ab31f19 100644
Binary files a/test/core/census/data/context_span_only.pb and b/test/core/census/data/context_span_only.pb differ
diff --git a/test/core/census/data/context_span_only.txt b/test/core/census/data/context_span_only.txt
index d90de2e614b406844e15c0bc045e1b4e03ee7fde..4e473fce53e35ec5013134861cae2db44536be10 100644
--- a/test/core/census/data/context_span_only.txt
+++ b/test/core/census/data/context_span_only.txt
@@ -1,2 +1,2 @@
 span_id : 7
-is_sampled : true
+span_options : 1
diff --git a/test/core/census/data/context_trace_only.pb b/test/core/census/data/context_trace_only.pb
index 7fdf6f61a3f2e4b72edc05f23a0632043d4f6bcc..aabb325f92489c4efac64ddd5461fd67540ea2d0 100644
Binary files a/test/core/census/data/context_trace_only.pb and b/test/core/census/data/context_trace_only.pb differ
diff --git a/test/core/census/data/context_trace_only.txt b/test/core/census/data/context_trace_only.txt
index 9b68a6aa9285a2072bbbc3326656fbb9ae93a9a6..e48a6d745744b8c240931764964d8e3c95d6c38f 100644
--- a/test/core/census/data/context_trace_only.txt
+++ b/test/core/census/data/context_trace_only.txt
@@ -1,2 +1,3 @@
-trace_id { hi : 5; lo : 1 }
-is_sampled : true
+trace_id_hi : 5
+trace_id_lo : 1
+span_options : 1
diff --git a/test/core/census/trace_context_test.c b/test/core/census/trace_context_test.c
index ee409e8d1a5a72ef8fb80765727835c2cd444aca..5963b1a2469025f48526585c9ce05485a9a924c2 100644
--- a/test/core/census/trace_context_test.c
+++ b/test/core/census/trace_context_test.c
@@ -59,7 +59,6 @@ bool validate_encode_decode_context(google_trace_TraceContext *ctxt1,
                                     uint8_t *buffer, size_t buf_size) {
   google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero;
   size_t msg_length;
-  GPR_ASSERT(ctxt1->has_trace_id && ctxt1->has_span_id);
 
   msg_length = encode_trace_context(ctxt1, buffer, buf_size);
   if (msg_length == 0) {
@@ -70,16 +69,17 @@ bool validate_encode_decode_context(google_trace_TraceContext *ctxt1,
     return false;
   }
 
-  if (!ctxt2.has_trace_id || !ctxt2.has_span_id) {
+  if (!ctxt2.has_trace_id_hi || !ctxt2.has_trace_id_lo || !ctxt2.has_span_id) {
     return false;
   }
 
-  GPR_ASSERT(
-      ctxt1->trace_id.hi == ctxt2.trace_id.hi &&
-      ctxt1->trace_id.lo == ctxt2.trace_id.lo &&
-      ctxt1->span_id == ctxt2.span_id &&
-      ctxt1->has_is_sampled == ctxt2.has_is_sampled &&
-      (ctxt1->has_is_sampled ? ctxt1->is_sampled == ctxt2.is_sampled : true));
+  GPR_ASSERT(ctxt1->trace_id_hi == ctxt2.trace_id_hi &&
+             ctxt1->trace_id_lo == ctxt2.trace_id_lo &&
+             ctxt1->span_id == ctxt2.span_id &&
+             ctxt1->has_span_options == ctxt2.has_span_options &&
+             (ctxt1->has_span_options
+                  ? ctxt1->span_options == ctxt2.span_options
+                  : true));
 
   return true;
 }
@@ -94,7 +94,7 @@ bool validate_decode_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
     return false;
   }
 
-  if (!ctxt->has_trace_id || !ctxt->has_span_id) {
+  if (!ctxt->has_trace_id_hi || !ctxt->has_trace_id_lo || !ctxt->has_span_id) {
     return false;
   }
 
@@ -144,49 +144,48 @@ static void test_span_only() {
       &ctxt, "test/core/census/data/context_span_only.pb", false);
 }
 
-// Test proto-buffer without is_sampled value.
-static void test_no_sample() {
+// Test proto-buffer without span_options value.
+static void test_no_span_options() {
   google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
   read_and_validate_context_from_file(
-      &ctxt, "test/core/census/data/context_no_sample.pb", true);
-  GPR_ASSERT(ctxt.has_is_sampled == false && ctxt.is_sampled == false);
+      &ctxt, "test/core/census/data/context_no_span_options.pb", true);
+  GPR_ASSERT(ctxt.has_span_options == false && ctxt.span_options == 0);
 }
 
 static void test_encode_decode() {
   uint8_t buffer[BUF_SIZE] = {0};
 
   google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
-  ctxt1.has_trace_id = true;
-  ctxt1.trace_id.has_hi = true;
-  ctxt1.trace_id.has_lo = true;
-  ctxt1.trace_id.lo = 1;
-  ctxt1.trace_id.hi = 2;
+  ctxt1.has_trace_id_hi = true;
+  ctxt1.has_trace_id_lo = true;
+  ctxt1.trace_id_lo = 1;
+  ctxt1.trace_id_hi = 2;
   ctxt1.has_span_id = true;
   ctxt1.span_id = 3;
   validate_encode_decode_context(&ctxt1, buffer, sizeof(buffer));
 
+  // Missing trace_id. This should fail.
   google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero;
-  ctxt2.has_trace_id = true;
-  ctxt2.trace_id.has_hi = false;
-  ctxt2.trace_id.has_lo = false;
+  ctxt2.has_trace_id_hi = false;
+  ctxt2.has_trace_id_lo = false;
   ctxt2.has_span_id = true;
   validate_encode_decode_context(&ctxt2, buffer, sizeof(buffer));
 }
 
-// Test a corrupted proto-buffer.
+// Test a corrupted proto-buffer. This should fail.
 static void test_corrupt() {
   uint8_t buffer[BUF_SIZE] = {0};
   google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
   size_t msg_length;
 
-  ctxt1.has_trace_id = true;
-  ctxt1.trace_id.has_hi = true;
-  ctxt1.trace_id.has_lo = true;
-  ctxt1.trace_id.lo = 1;
-  ctxt1.trace_id.hi = 2;
+  ctxt1.has_trace_id_hi = true;
+  ctxt1.has_trace_id_lo = true;
+  ctxt1.trace_id_lo = 1;
+  ctxt1.trace_id_hi = 2;
   ctxt1.has_span_id = true;
   ctxt1.span_id = 3;
-  ctxt1.is_sampled = true;
+  ctxt1.has_span_options = true;
+  ctxt1.span_options = SPAN_OPTIONS_IS_SAMPLED;
   msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer));
 
   /* Corrupt some bytes.  255 (0xFF) should be illegal for the first byte of the
@@ -198,19 +197,19 @@ static void test_corrupt() {
 }
 
 static void test_buffer_size() {
-  // This buffer is too small, so the encode should fail.
+  // This buffer is too small. This should fail.
   uint8_t buffer[16] = {0};
   google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
   size_t msg_length;
 
-  ctxt1.has_trace_id = true;
-  ctxt1.trace_id.has_hi = true;
-  ctxt1.trace_id.has_lo = true;
-  ctxt1.trace_id.lo = 1;
-  ctxt1.trace_id.hi = 2;
+  ctxt1.has_trace_id_hi = true;
+  ctxt1.has_trace_id_lo = true;
+  ctxt1.trace_id_lo = 1;
+  ctxt1.trace_id_hi = 2;
   ctxt1.has_span_id = true;
   ctxt1.span_id = 3;
-  ctxt1.is_sampled = true;
+  ctxt1.has_span_options = true;
+  ctxt1.span_options = SPAN_OPTIONS_IS_SAMPLED;
   msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer));
 
   GPR_ASSERT(msg_length == 0);
@@ -224,7 +223,7 @@ int main(int argc, char **argv) {
   test_span_only();
   test_encode_decode();
   test_corrupt();
-  test_no_sample();
+  test_no_span_options();
   test_buffer_size();
 
   return 0;