diff --git a/beeline/__init__.py b/beeline/__init__.py
index e6dce92..ed238fc 100644
--- a/beeline/__init__.py
+++ b/beeline/__init__.py
@@ -9,7 +9,7 @@ from libhoney import Client
 from beeline.trace import SynchronousTracer
 from beeline.version import VERSION
 from beeline import internal
-import beeline.propagation.honeycomb
+import beeline.propagation.default
 import sys
 # pyflakes
 assert internal
@@ -59,8 +59,8 @@ class Beeline(object):
                  max_concurrent_batches=10, max_batch_size=100, send_frequency=0.25,
                  block_on_send=False, block_on_response=False,
                  transmission_impl=None, sampler_hook=None, presend_hook=None,
-                 http_trace_parser_hook=beeline.propagation.honeycomb.http_trace_parser_hook,
-                 http_trace_propagation_hook=beeline.propagation.honeycomb.http_trace_propagation_hook,
+                 http_trace_parser_hook=beeline.propagation.default.http_trace_parser_hook,
+                 http_trace_propagation_hook=beeline.propagation.default.http_trace_propagation_hook,
                  debug=False):
 
         self.client = None
diff --git a/beeline/propagation/default.py b/beeline/propagation/default.py
new file mode 100644
index 0000000..633eecc
--- /dev/null
+++ b/beeline/propagation/default.py
@@ -0,0 +1,21 @@
+from beeline.propagation import honeycomb, w3c
+
+
+def http_trace_parser_hook(request):
+    """
+    Retrieves the propagation context out of the request. Uses the honeycomb header, with W3C header as fallback.
+    """
+    honeycomb_header_value = honeycomb.http_trace_parser_hook(request)
+    w3c_header_value = w3c.http_trace_parser_hook(request)
+    if honeycomb_header_value:
+        return honeycomb_header_value
+    else:
+        return w3c_header_value
+
+
+def http_trace_propagation_hook(propagation_context):
+    """
+    Given a propagation context, returns a dictionary of key value pairs that should be
+    added to outbound requests (usually HTTP headers). Uses the honeycomb format.
+    """
+    return honeycomb.http_trace_propagation_hook(propagation_context)
diff --git a/beeline/trace.py b/beeline/trace.py
index 7f5561e..06a5bd5 100644
--- a/beeline/trace.py
+++ b/beeline/trace.py
@@ -18,6 +18,7 @@ from contextlib import contextmanager
 from beeline.internal import log, stringify_exception
 
 import beeline.propagation
+import beeline.propagation.default
 import beeline.propagation.honeycomb
 
 MAX_INT32 = math.pow(2, 32) - 1
@@ -49,8 +50,8 @@ class Tracer(object):
 
         self.presend_hook = None
         self.sampler_hook = None
-        self.http_trace_parser_hook = beeline.propagation.honeycomb.http_trace_parser_hook
-        self.http_trace_propagation_hook = beeline.propagation.honeycomb.http_trace_propagation_hook
+        self.http_trace_parser_hook = beeline.propagation.default.http_trace_parser_hook
+        self.http_trace_propagation_hook = beeline.propagation.default.http_trace_propagation_hook
 
     @contextmanager
     def __call__(self, name, trace_id=None, parent_id=None):

diff --git a/beeline/test_trace.py b/beeline/test_trace.py
index 43beece..5033618 100644
--- a/beeline/test_trace.py
+++ b/beeline/test_trace.py
@@ -623,7 +623,7 @@ class TestSpan(unittest.TestCase):
 
 
 class TestPropagationHooks(unittest.TestCase):
-    def test_propagate_and_start_trace(self):
+    def test_propagate_and_start_trace_uses_honeycomb_header(self):
         # FIXME: Test basics, including error handling and custom hooks
 
         # implicitly tests finish_span
@@ -653,6 +653,61 @@ class TestPropagationHooks(unittest.TestCase):
         # ensure that there is no current trace
         self.assertIsNone(tracer._trace)
 
+    def test_propagate_and_start_trace_uses_w3c_header_as_fallback(self):
+        # implicitly tests finish_span
+        m_client = Mock()
+        # these values are used before sending
+        m_client.new_event.return_value.start_time = datetime.datetime.now()
+        m_client.new_event.return_value.sample_rate = 1
+        tracer = SynchronousTracer(m_client)
+
+        header_value = '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00'
+        req = DictRequest({
+            'traceparent': header_value,
+        })
+
+        span = tracer.propagate_and_start_trace(
+            context={'big': 'important_stuff'}, request=req)
+        self.assertEqual(tracer._trace.stack[0], span)
+        self.assertEqual(span.trace_id, "0af7651916cd43dd8448eb211c80319c")
+        self.assertEqual(span.parent_id, "b7ad6b7169203331")
+
+        tracer.finish_trace(span)
+
+        # ensure the event is sent
+        span.event.send_presampled.assert_called_once_with()
+        # ensure that there is no current trace
+        self.assertIsNone(tracer._trace)
+
+    def test_propagate_and_start_trace_uses_honeycomb_header_when_w3c_also_present(self):
+        # implicitly tests finish_span
+        m_client = Mock()
+        # these values are used before sending
+        m_client.new_event.return_value.start_time = datetime.datetime.now()
+        m_client.new_event.return_value.sample_rate = 1
+        tracer = SynchronousTracer(m_client)
+
+        w3c_value = '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00'
+        honeycomb_value = '1;dataset=flibble,trace_id=bloop,parent_id=scoop,context=e30K'
+        req = DictRequest({
+            'traceparent': w3c_value,
+            'x-honeycomb-trace': honeycomb_value
+        })
+
+        span = tracer.propagate_and_start_trace(
+            context={'big': 'important_stuff'}, request=req)
+        self.assertEqual(tracer._trace.stack[0], span)
+        self.assertEqual(span.trace_id, "bloop")
+        self.assertEqual(span.parent_id, "scoop")
+
+        tracer.finish_trace(span)
+        self.assertEqual(span.event.dataset, 'flibble')
+
+        # ensure the event is sent
+        span.event.send_presampled.assert_called_once_with()
+        # ensure that there is no current trace
+        self.assertIsNone(tracer._trace)
+
     def test_error_handling(self):
         class TestException(Exception):
             pass

Enable Beeline to simultaneously accept w3c and honeycomb propagation headers
<!---
Thank you for contributing an idea to this project!

Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
--->

**Is your feature request related to a problem? Please describe.**

Currently, it's not possible to incrementally move a microservices architecture from the honeycomb propagation headers format to the w3c propagation headers format. This makes it difficult if not impossible for beeline customers with a large enough deployment to move towards interoperating with OpenTelemetry.

**Describe the solution you'd like**

Allow the beeline to simultaneously accept both w3c and honeycomb propagation headers, whichever is found on the incoming request. The outgoing propagation header format can still be static and set by configuration.

**Describe alternatives you've considered**


**Additional context**

beeline/test_trace.py::TestPropagationHooks::test_propagate_and_start_trace_uses_w3c_header_as_fallback
beeline/test_trace.py::TestTraceContext::test_marshal_trace_context_empty_context beeline/test_trace.py::TestTraceContext::test_marshal_trace_context beeline/test_trace.py::TestTraceContext::test_marshal_trace_context_dataset_included beeline/test_trace.py::TestSynchronousTracer::test_custom_dataset_propagates_to_event beeline/test_trace.py::TestSynchronousTracer::test_run_hooks_and_send_adds_trace_fields beeline/test_trace.py::TestSynchronousTracer::test_start_span_returns_none_if_no_trace beeline/test_trace.py::TestSynchronousTracer::test_trace_context_manager_starts_trace_if_trace_id_supplied beeline/test_trace.py::TestSynchronousTracer::test_start_trace beeline/test_trace.py::TestSynchronousTracer::test_finish_trace beeline/test_trace.py::TestSynchronousTracer::test_add_rollup_field_propagates beeline/test_trace.py::TestSynchronousTracer::test_start_trace_with_trace_id_set beeline/test_trace.py::TestSynchronousTracer::test_trace_context_manager_exception beeline/test_trace.py::TestSynchronousTracer::test_get_active_span beeline/test_trace.py::TestSynchronousTracer::test_add_trace_field_propagates beeline/test_trace.py::TestSynchronousTracer::test_trace_context_manager_does_not_crash_if_span_is_none beeline/test_trace.py::TestSynchronousTracer::test_run_hooks_and_send_sampler beeline/test_trace.py::TestSynchronousTracer::test_run_hooks_and_send_no_hooks beeline/test_trace.py::TestSynchronousTracer::test_trace_context_manager_starts_span_if_trace_active beeline/test_trace.py::TestSynchronousTracer::test_start_span beeline/test_trace.py::TestSynchronousTracer::test_run_hooks_and_send_presend_hook beeline/test_trace.py::TestSynchronousTracer::test_trace_context_manager_passes_parent_id_if_supplied beeline/test_trace.py::TestSynchronousTracer::test_trace_with_custom_dataset beeline/test_trace.py::TestTraceSampling::test_deterministic beeline/test_trace.py::TestTraceSampling::test_probability beeline/test_trace.py::TestTraceSampling::test_deterministic_interop beeline/test_trace.py::TestSpan::test_span_context beeline/test_trace.py::TestPropagationHooks::test_propagate_and_start_trace_uses_honeycomb_header beeline/test_trace.py::TestPropagationHooks::test_error_handling beeline/test_trace.py::TestPropagationHooks::test_propagate_and_start_trace_uses_honeycomb_header_when_w3c_also_present beeline/test_trace.py::TestIDGeneration::test_span_id beeline/test_trace.py::TestIDGeneration::test_trace_id