diff --git a/RELEASE.CHANGELOG.md b/RELEASE.CHANGELOG.md
index 5638b74..fc45791 100644
--- a/RELEASE.CHANGELOG.md
+++ b/RELEASE.CHANGELOG.md
@@ -1,3 +1,19 @@
+### May 26, 2025
+`3.1.1`
+- Move unhandled exception warning message to init errors. ([#189](https://github.com/aws/aws-lambda-python-runtime-interface-client/pull/189))
+
+### May 21, 2025
+`3.1.0`
+- Add support for multi tenancy ([#187](https://github.com/aws/aws-lambda-python-runtime-interface-client/pull/187))
+
+### February 27, 2024
+`3.0.2`
+- Update `simplejson` to `3.20.1`([#184](https://github.com/aws/aws-lambda-python-runtime-interface-client/pull/184))
+
+### January 27, 2024
+`3.0.1`
+- Don't enforce text format on uncaught exception warning message ([#182](https://github.com/aws/aws-lambda-python-runtime-interface-client/pull/182))
+
 ### November 19, 2024
 `3.0.0`
 - Drop support for deprecated python versions ([#179](https://github.com/aws/aws-lambda-python-runtime-interface-client/pull/179))
diff --git a/awslambdaric/__init__.py b/awslambdaric/__init__.py
index bc306b2..5605903 100644
--- a/awslambdaric/__init__.py
+++ b/awslambdaric/__init__.py
@@ -2,4 +2,4 @@
 Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 """
 
-__version__ = "3.0.0"
+__version__ = "3.1.1"
diff --git a/awslambdaric/bootstrap.py b/awslambdaric/bootstrap.py
index f10c7bf..cb8d5c3 100644
--- a/awslambdaric/bootstrap.py
+++ b/awslambdaric/bootstrap.py
@@ -102,7 +102,6 @@ def replace_line_indentation(line, indent_char, new_indent_char):
 
 if _AWS_LAMBDA_LOG_FORMAT == LogFormat.JSON:
     _ERROR_FRAME_TYPE = _JSON_FRAME_TYPES[logging.ERROR]
-    _WARNING_FRAME_TYPE = _JSON_FRAME_TYPES[logging.WARNING]
 
     def log_error(error_result, log_sink):
         error_result = {
@@ -118,7 +117,6 @@ def log_error(error_result, log_sink):
 
 else:
     _ERROR_FRAME_TYPE = _TEXT_FRAME_TYPES[logging.ERROR]
-    _WARNING_FRAME_TYPE = _TEXT_FRAME_TYPES[logging.WARNING]
 
     def log_error(error_result, log_sink):
         error_description = "[ERROR]"
@@ -160,6 +158,7 @@ def handle_event_request(
     cognito_identity_json,
     invoked_function_arn,
     epoch_deadline_time_in_ms,
+    tenant_id,
     log_sink,
 ):
     error_result = None
@@ -170,6 +169,7 @@ def handle_event_request(
             epoch_deadline_time_in_ms,
             invoke_id,
             invoked_function_arn,
+            tenant_id,
         )
         event = lambda_runtime_client.marshaller.unmarshal_request(
             event_body, content_type
@@ -201,9 +201,7 @@ def handle_event_request(
         )
 
     if error_result is not None:
-        from .lambda_literals import lambda_unhandled_exception_warning_message
 
-        log_sink.log(lambda_unhandled_exception_warning_message, _WARNING_FRAME_TYPE)
         log_error(error_result, log_sink)
         lambda_runtime_client.post_invocation_error(
             invoke_id, to_json(error_result), to_json(xray_fault)
@@ -231,6 +229,7 @@ def create_lambda_context(
     epoch_deadline_time_in_ms,
     invoke_id,
     invoked_function_arn,
+    tenant_id,
 ):
     client_context = None
     if client_context_json:
@@ -245,6 +244,7 @@ def create_lambda_context(
         cognito_identity,
         epoch_deadline_time_in_ms,
         invoked_function_arn,
+        tenant_id,
     )
 
 
@@ -339,6 +339,7 @@ def emit(self, record):
 class LambdaLoggerFilter(logging.Filter):
     def filter(self, record):
         record.aws_request_id = _GLOBAL_AWS_REQUEST_ID or ""
+        record.tenant_id = _GLOBAL_TENANT_ID
         return True
 
 
@@ -447,6 +448,7 @@ def create_log_sink():
 
 
 _GLOBAL_AWS_REQUEST_ID = None
+_GLOBAL_TENANT_ID = None
 
 
 def _setup_logging(log_format, log_level, log_sink):
@@ -492,7 +494,7 @@ def run(app_root, handler, lambda_runtime_api_addr):
 
         try:
             _setup_logging(_AWS_LAMBDA_LOG_FORMAT, _AWS_LAMBDA_LOG_LEVEL, log_sink)
-            global _GLOBAL_AWS_REQUEST_ID
+            global _GLOBAL_AWS_REQUEST_ID, _GLOBAL_TENANT_ID
 
             request_handler = _get_handler(handler)
         except FaultException as e:
@@ -505,6 +507,9 @@ def run(app_root, handler, lambda_runtime_api_addr):
             error_result = build_fault_result(sys.exc_info(), None)
 
         if error_result is not None:
+            from .lambda_literals import lambda_unhandled_exception_warning_message
+
+            logging.warning(lambda_unhandled_exception_warning_message)
             log_error(error_result, log_sink)
             lambda_runtime_client.post_init_error(error_result)
 
@@ -517,6 +522,7 @@ def run(app_root, handler, lambda_runtime_api_addr):
             event_request = lambda_runtime_client.wait_next_invocation()
 
             _GLOBAL_AWS_REQUEST_ID = event_request.invoke_id
+            _GLOBAL_TENANT_ID = event_request.tenant_id
 
             update_xray_env_variable(event_request.x_amzn_trace_id)
 
@@ -530,5 +536,6 @@ def run(app_root, handler, lambda_runtime_api_addr):
                 event_request.cognito_identity,
                 event_request.invoked_function_arn,
                 event_request.deadline_time_in_ms,
+                event_request.tenant_id,
                 log_sink,
             )
diff --git a/awslambdaric/lambda_context.py b/awslambdaric/lambda_context.py
index 1465827..e0a3363 100644
--- a/awslambdaric/lambda_context.py
+++ b/awslambdaric/lambda_context.py
@@ -16,6 +16,7 @@ def __init__(
         cognito_identity,
         epoch_deadline_time_in_ms,
         invoked_function_arn=None,
+        tenant_id=None,
     ):
         self.aws_request_id = invoke_id
         self.log_group_name = os.environ.get("AWS_LAMBDA_LOG_GROUP_NAME")
@@ -24,6 +25,7 @@ def __init__(
         self.memory_limit_in_mb = os.environ.get("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")
         self.function_version = os.environ.get("AWS_LAMBDA_FUNCTION_VERSION")
         self.invoked_function_arn = invoked_function_arn
+        self.tenant_id = tenant_id
 
         self.client_context = make_obj_from_dict(ClientContext, client_context)
         if self.client_context is not None:
@@ -65,7 +67,8 @@ def __repr__(self):
             f"function_version={self.function_version},"
             f"invoked_function_arn={self.invoked_function_arn},"
             f"client_context={self.client_context},"
-            f"identity={self.identity}"
+            f"identity={self.identity},"
+            f"tenant_id={self.tenant_id}"
             "])"
         )
 
diff --git a/awslambdaric/lambda_runtime_client.py b/awslambdaric/lambda_runtime_client.py
index cc87262..ba4ad92 100644
--- a/awslambdaric/lambda_runtime_client.py
+++ b/awslambdaric/lambda_runtime_client.py
@@ -137,6 +137,7 @@ def wait_next_invocation(self):
             deadline_time_in_ms=headers.get("Lambda-Runtime-Deadline-Ms"),
             client_context=headers.get("Lambda-Runtime-Client-Context"),
             cognito_identity=headers.get("Lambda-Runtime-Cognito-Identity"),
+            tenant_id=headers.get("Lambda-Runtime-Aws-Tenant-Id"),
             content_type=headers.get("Content-Type"),
             event_body=response_body,
         )
diff --git a/awslambdaric/lambda_runtime_log_utils.py b/awslambdaric/lambda_runtime_log_utils.py
index 7ed9940..9ddbcfb 100644
--- a/awslambdaric/lambda_runtime_log_utils.py
+++ b/awslambdaric/lambda_runtime_log_utils.py
@@ -30,6 +30,7 @@
     "processName",
     "process",
     "aws_request_id",
+    "tenant_id",
     "_frame_type",
 }
 
@@ -124,6 +125,9 @@ def format(self, record: logging.LogRecord) -> str:
             "requestId": getattr(record, "aws_request_id", None),
             "location": self.__format_location(record),
         }
+        if hasattr(record, "tenant_id") and record.tenant_id is not None:
+            result["tenantId"] = record.tenant_id
+
         result.update(
             (key, value)
             for key, value in record.__dict__.items()
diff --git a/awslambdaric/runtime_client.cpp b/awslambdaric/runtime_client.cpp
index 66252bf..7fb2e95 100644
--- a/awslambdaric/runtime_client.cpp
+++ b/awslambdaric/runtime_client.cpp
@@ -52,9 +52,10 @@ static PyObject *method_next(PyObject *self) {
     auto client_context = response.client_context.c_str();
     auto content_type = response.content_type.c_str();
     auto cognito_id = response.cognito_identity.c_str();
+    auto tenant_id = response.tenant_id.c_str();
 
     PyObject *payload_bytes = PyBytes_FromStringAndSize(payload.c_str(), payload.length());
-    PyObject *result = Py_BuildValue("(O,{s:s,s:s,s:s,s:l,s:s,s:s,s:s})",
+    PyObject *result = Py_BuildValue("(O,{s:s,s:s,s:s,s:l,s:s,s:s,s:s,s:s})",
                          payload_bytes,  //Py_BuildValue() increments reference counter
                          "Lambda-Runtime-Aws-Request-Id", request_id,
                          "Lambda-Runtime-Trace-Id", NULL_IF_EMPTY(trace_id),
@@ -62,7 +63,8 @@ static PyObject *method_next(PyObject *self) {
                          "Lambda-Runtime-Deadline-Ms", deadline,
                          "Lambda-Runtime-Client-Context", NULL_IF_EMPTY(client_context),
                          "Content-Type", NULL_IF_EMPTY(content_type),
-                         "Lambda-Runtime-Cognito-Identity", NULL_IF_EMPTY(cognito_id)
+                         "Lambda-Runtime-Cognito-Identity", NULL_IF_EMPTY(cognito_id),
+                         "Lambda-Runtime-Aws-Tenant-Id", NULL_IF_EMPTY(tenant_id)
     );
 
     Py_XDECREF(payload_bytes);
diff --git a/deps/aws-lambda-cpp-0.2.6.tar.gz b/deps/aws-lambda-cpp-0.2.6.tar.gz
index 26fa498..51d7f51 100644
Binary files a/deps/aws-lambda-cpp-0.2.6.tar.gz and b/deps/aws-lambda-cpp-0.2.6.tar.gz differ
diff --git a/deps/patches/aws-lambda-cpp-add-tenant-id.patch b/deps/patches/aws-lambda-cpp-add-tenant-id.patch
new file mode 100644
index 0000000..a7b7172
--- /dev/null
+++ b/deps/patches/aws-lambda-cpp-add-tenant-id.patch
@@ -0,0 +1,39 @@
+diff --git a/include/aws/lambda-runtime/runtime.h b/include/aws/lambda-runtime/runtime.h
+index 7812ff6..96be869 100644
+--- a/include/aws/lambda-runtime/runtime.h
++++ b/include/aws/lambda-runtime/runtime.h
+@@ -61,6 +61,11 @@ struct invocation_request {
+      */
+     std::string content_type;
+ 
++    /**
++     * The Tenant ID of the current invocation.
++     */
++    std::string tenant_id;
++
+     /**
+      * Function execution deadline counted in milliseconds since the Unix epoch.
+      */
+diff --git a/src/runtime.cpp b/src/runtime.cpp
+index e53b2b8..9763282 100644
+--- a/src/runtime.cpp
++++ b/src/runtime.cpp
+@@ -40,6 +40,7 @@ static constexpr auto CLIENT_CONTEXT_HEADER = "lambda-runtime-client-context";
+ static constexpr auto COGNITO_IDENTITY_HEADER = "lambda-runtime-cognito-identity";
+ static constexpr auto DEADLINE_MS_HEADER = "lambda-runtime-deadline-ms";
+ static constexpr auto FUNCTION_ARN_HEADER = "lambda-runtime-invoked-function-arn";
++static constexpr auto TENANT_ID_HEADER = "lambda-runtime-aws-tenant-id";
+ 
+ enum Endpoints {
+     INIT,
+@@ -289,6 +290,10 @@ runtime::next_outcome runtime::get_next()
+         req.function_arn = resp.get_header(FUNCTION_ARN_HEADER);
+     }
+ 
++    if (resp.has_header(TENANT_ID_HEADER)) {
++        req.tenant_id = resp.get_header(TENANT_ID_HEADER);
++    }
++
+     if (resp.has_header(DEADLINE_MS_HEADER)) {
+         auto const& deadline_string = resp.get_header(DEADLINE_MS_HEADER);
+         constexpr int base = 10;
diff --git a/requirements/base.txt b/requirements/base.txt
index afdff74..4bb251e 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,2 +1,2 @@
-simplejson>=3.18.4
+simplejson>=3.20.1
 snapshot-restore-py>=1.0.0
diff --git a/scripts/update_deps.sh b/scripts/update_deps.sh
index 0baa3f9..4799a6f 100755
--- a/scripts/update_deps.sh
+++ b/scripts/update_deps.sh
@@ -30,7 +30,8 @@ wget -c https://github.com/awslabs/aws-lambda-cpp/archive/v$AWS_LAMBDA_CPP_RELEA
     patch -p1 < ../patches/aws-lambda-cpp-posting-init-errors.patch && \
     patch -p1 < ../patches/aws-lambda-cpp-make-the-runtime-client-user-agent-overrideable.patch && \
     patch -p1 < ../patches/aws-lambda-cpp-make-lto-optional.patch && \
-    patch -p1 < ../patches/aws-lambda-cpp-add-content-type.patch
+    patch -p1 < ../patches/aws-lambda-cpp-add-content-type.patch && \
+    patch -p1 < ../patches/aws-lambda-cpp-add-tenant-id.patch
 )
 
 ## Pack again and remove the folder
diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py
index 79dcae6..33afb1c 100644
--- a/tests/test_bootstrap.py
+++ b/tests/test_bootstrap.py
@@ -18,7 +18,11 @@
 
 import awslambdaric.bootstrap as bootstrap
 from awslambdaric.lambda_runtime_exception import FaultException
-from awslambdaric.lambda_runtime_log_utils import LogFormat, _get_log_level_from_env_var
+from awslambdaric.lambda_runtime_log_utils import (
+    LogFormat,
+    _get_log_level_from_env_var,
+    JsonFormatter,
+)
 from awslambdaric.lambda_runtime_marshaller import LambdaMarshaller
 from awslambdaric.lambda_literals import (
     lambda_unhandled_exception_warning_message,
@@ -61,6 +65,14 @@ def setUp(self):
         self.event_body = '"event_body"'
         self.working_directory = os.getcwd()
 
+        logging.getLogger().handlers.clear()
+
+    def tearDown(self) -> None:
+        logging.getLogger().handlers.clear()
+        logging.getLogger().level = logging.NOTSET
+
+        return super().tearDown()
+
     @staticmethod
     def dummy_handler(json_input, lambda_context):
         return {"input": json_input, "aws_request_id": lambda_context.aws_request_id}
@@ -76,6 +88,7 @@ def test_handle_event_request_happy_case(self):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         self.lambda_runtime.post_invocation_result.assert_called_once_with(
@@ -99,6 +112,7 @@ def test_handle_event_request_invalid_client_context(self):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -140,6 +154,7 @@ def test_handle_event_request_invalid_cognito_idenity(self):
             "invalid_cognito_identity",
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -182,6 +197,7 @@ def test_handle_event_request_invalid_event_body(self):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -226,6 +242,7 @@ def invalid_json_response(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -271,6 +288,7 @@ def __init__(self, message):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -323,6 +341,7 @@ def __init__(self, message):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -374,6 +393,7 @@ def unable_to_import_module(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -413,6 +433,7 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
         args, _ = self.lambda_runtime.post_invocation_error.call_args
@@ -451,6 +472,8 @@ def raise_exception_handler(json_input, lambda_context):
                     ),
                 )
 
+        logging.getLogger().addHandler(logging.StreamHandler(mock_stdout))
+
         bootstrap.handle_event_request(
             self.lambda_runtime,
             raise_exception_handler,
@@ -461,14 +484,12 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
 
         # NOTE: Indentation characters are NO-BREAK SPACE (U+00A0) not SPACE (U+0020)
-        error_logs = (
-            lambda_unhandled_exception_warning_message
-            + "[ERROR] FaultExceptionType: Fault exception msg\r"
-        )
+        error_logs = "[ERROR] FaultExceptionType: Fault exception msg\r"
         error_logs += "Traceback (most recent call last):\r"
         error_logs += '  File "spam.py", line 3, in <module>\r'
         error_logs += "    spam.eggs()\r"
@@ -487,6 +508,8 @@ def raise_exception_handler(json_input, lambda_context):
                     "FaultExceptionType", "Fault exception msg", None
                 )
 
+        logging.getLogger().addHandler(logging.StreamHandler(mock_stdout))
+
         bootstrap.handle_event_request(
             self.lambda_runtime,
             raise_exception_handler,
@@ -497,12 +520,10 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
-        error_logs = (
-            lambda_unhandled_exception_warning_message
-            + "[ERROR] FaultExceptionType: Fault exception msg\rTraceback (most recent call last):\n"
-        )
+        error_logs = "[ERROR] FaultExceptionType: Fault exception msg\rTraceback (most recent call last):\n"
 
         self.assertEqual(mock_stdout.getvalue(), error_logs)
 
@@ -516,6 +537,8 @@ def raise_exception_handler(json_input, lambda_context):
             except ImportError:
                 raise bootstrap.FaultException("FaultExceptionType", None, None)
 
+        logging.getLogger().addHandler(logging.StreamHandler(mock_stdout))
+
         bootstrap.handle_event_request(
             self.lambda_runtime,
             raise_exception_handler,
@@ -526,12 +549,10 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
-        error_logs = (
-            lambda_unhandled_exception_warning_message
-            + "[ERROR] FaultExceptionType\rTraceback (most recent call last):\n"
-        )
+        error_logs = "[ERROR] FaultExceptionType\rTraceback (most recent call last):\n"
 
         self.assertEqual(mock_stdout.getvalue(), error_logs)
 
@@ -545,6 +566,8 @@ def raise_exception_handler(json_input, lambda_context):
             except ImportError:
                 raise bootstrap.FaultException(None, "Fault exception msg", None)
 
+        logging.getLogger().addHandler(logging.StreamHandler(mock_stdout))
+
         bootstrap.handle_event_request(
             self.lambda_runtime,
             raise_exception_handler,
@@ -555,12 +578,10 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
-        error_logs = (
-            lambda_unhandled_exception_warning_message
-            + "[ERROR] Fault exception msg\rTraceback (most recent call last):\n"
-        )
+        error_logs = "[ERROR] Fault exception msg\rTraceback (most recent call last):\n"
 
         self.assertEqual(mock_stdout.getvalue(), error_logs)
 
@@ -583,6 +604,8 @@ def raise_exception_handler(json_input, lambda_context):
                     ),
                 )
 
+        logging.getLogger().addHandler(logging.StreamHandler(mock_stdout))
+
         bootstrap.handle_event_request(
             self.lambda_runtime,
             raise_exception_handler,
@@ -593,9 +616,10 @@ def raise_exception_handler(json_input, lambda_context):
             {},
             "invoked_function_arn",
             0,
+            "tenant_id",
             bootstrap.StandardLogSink(),
         )
-        error_logs = lambda_unhandled_exception_warning_message + "[ERROR]\r"
+        error_logs = "[ERROR]\r"
         error_logs += "Traceback (most recent call last):\r"
         error_logs += '  File "spam.py", line 3, in <module>\r'
         error_logs += "    spam.eggs()\r"
@@ -604,6 +628,39 @@ def raise_exception_handler(json_input, lambda_context):
 
         self.assertEqual(mock_stdout.getvalue(), error_logs)
 
+    @patch("sys.stdout", new_callable=StringIO)
+    def test_handle_event_request_fault_exception_logging_in_json(self, mock_stdout):
+        def raise_exception_handler(json_input, lambda_context):
+            try:
+                import invalid_module  # noqa: F401
+            except ImportError:
+                raise bootstrap.FaultException("FaultExceptionType", None, None)
+
+        logging_handler = logging.StreamHandler(mock_stdout)
+        logging_handler.setFormatter(JsonFormatter())
+        logging.getLogger().addHandler(logging_handler)
+
+        bootstrap.handle_event_request(
+            self.lambda_runtime,
+            raise_exception_handler,
+            "invoke_id",
+            self.event_body,
+            "application/json",
+            {},
+            {},
+            "invoked_function_arn",
+            0,
+            "tenant_id",
+            bootstrap.StandardLogSink(),
+        )
+
+        stdout_value = mock_stdout.getvalue()
+
+        # this line is not in json because of the way the test runtime is bootstrapped
+        error_logs = "[ERROR] FaultExceptionType\rTraceback (most recent call last):\n"
+
+        self.assertEqual(stdout_value, error_logs)
+
 
 class TestXrayFault(unittest.TestCase):
     def test_make_xray(self):
@@ -800,6 +857,7 @@ def test_application_json(self):
             cognito_identity_json=None,
             invoked_function_arn="invocation-arn",
             epoch_deadline_time_in_ms=1415836801003,
+            tenant_id=None,
             log_sink=bootstrap.StandardLogSink(),
         )
 
@@ -819,6 +877,7 @@ def test_binary_request_binary_response(self):
             cognito_identity_json=None,
             invoked_function_arn="invocation-arn",
             epoch_deadline_time_in_ms=1415836801003,
+            tenant_id=None,
             log_sink=bootstrap.StandardLogSink(),
         )
 
@@ -838,6 +897,7 @@ def test_json_request_binary_response(self):
             cognito_identity_json=None,
             invoked_function_arn="invocation-arn",
             epoch_deadline_time_in_ms=1415836801003,
+            tenant_id=None,
             log_sink=bootstrap.StandardLogSink(),
         )
 
@@ -856,6 +916,7 @@ def test_binary_with_application_json(self):
             cognito_identity_json=None,
             invoked_function_arn="invocation-arn",
             epoch_deadline_time_in_ms=1415836801003,
+            tenant_id=None,
             log_sink=bootstrap.StandardLogSink(),
         )
 
@@ -1289,6 +1350,31 @@ def test_json_formatter(self, mock_stderr):
                     )
         self.assertEqual(mock_stderr.getvalue(), "")
 
+    @patch("awslambdaric.bootstrap._GLOBAL_TENANT_ID", "test-tenant-id")
+    @patch("sys.stderr", new_callable=StringIO)
+    def test_json_formatter_with_tenant_id(self, mock_stderr):
+        logger = logging.getLogger("a.b")
+        level = logging.INFO
+        message = "Test json formatting with tenant id"
+        expected = {
+            "level": "INFO",
+            "logger": "a.b",
+            "message": message,
+            "requestId": "",
+            "tenantId": "test-tenant-id",
+        }
+
+        with patch("sys.stdout", new_callable=StringIO) as mock_stdout:
+            logger.log(level, message)
+
+            data = json.loads(mock_stdout.getvalue())
+            data.pop("timestamp")
+            self.assertEqual(
+                data,
+                expected,
+            )
+        self.assertEqual(mock_stderr.getvalue(), "")
+
     @patch("sys.stdout", new_callable=StringIO)
     @patch("sys.stderr", new_callable=StringIO)
     def test_exception(self, mock_stderr, mock_stdout):
diff --git a/tests/test_lambda_context.py b/tests/test_lambda_context.py
index 34d59da..f7959ab 100644
--- a/tests/test_lambda_context.py
+++ b/tests/test_lambda_context.py
@@ -37,6 +37,7 @@ def test_init(self):
         self.assertEqual(context.memory_limit_in_mb, "1234")
         self.assertEqual(context.function_version, "version1")
         self.assertEqual(context.invoked_function_arn, "arn:test1")
+        self.assertEqual(context.tenant_id, None)
         self.assertEqual(context.identity.cognito_identity_id, None)
         self.assertEqual(context.identity.cognito_identity_pool_id, None)
         self.assertEqual(context.client_context.client.installation_id, None)
@@ -74,6 +75,21 @@ def test_init_cognito(self):
         self.assertEqual(context.identity.cognito_identity_id, "id1")
         self.assertEqual(context.identity.cognito_identity_pool_id, "poolid1")
 
+    def test_init_tenant_id(self):
+        client_context = {}
+        cognito_identity = {}
+        tenant_id = "blue"
+
+        context = LambdaContext(
+            "invoke-id1",
+            client_context,
+            cognito_identity,
+            1415836801000,
+            "arn:test",
+            tenant_id,
+        )
+        self.assertEqual(context.tenant_id, "blue")
+
     def test_init_client_context(self):
         client_context = {
             "client": {
diff --git a/tests/test_lambda_runtime_client.py b/tests/test_lambda_runtime_client.py
index b13aa83..fc4af65 100644
--- a/tests/test_lambda_runtime_client.py
+++ b/tests/test_lambda_runtime_client.py
@@ -26,6 +26,7 @@ def test_constructor(self):
             deadline_time_in_ms="Lambda-Runtime-Deadline-Ms",
             client_context="Lambda-Runtime-Client-Context",
             cognito_identity="Lambda-Runtime-Cognito-Identity",
+            tenant_id="Lambda-Runtime-Aws-Tenant-Id",
             content_type="Content-Type",
             event_body="response_body",
         )
@@ -37,6 +38,7 @@ def test_constructor(self):
             deadline_time_in_ms="Lambda-Runtime-Deadline-Ms",
             client_context="Lambda-Runtime-Client-Context",
             cognito_identity="Lambda-Runtime-Cognito-Identity",
+            tenant_id="Lambda-Runtime-Aws-Tenant-Id",
             content_type="Content-Type",
             event_body="response_body",
         )
@@ -48,6 +50,7 @@ def test_constructor(self):
             deadline_time_in_ms="Lambda-Runtime-Deadline-Ms",
             client_context="Lambda-Runtime-Client-Context",
             cognito_identity="Lambda-Runtime-Cognito-Identity",
+            tenant_id="Lambda-Runtime-Aws-Tenant-Id",
             content_type="Content-Type",
             event_body="another_response_body",
         )
@@ -68,6 +71,7 @@ def test_wait_next_invocation(self, mock_runtime_client):
             "Lambda-Runtime-Deadline-Ms": 12,
             "Lambda-Runtime-Client-Context": "client_context",
             "Lambda-Runtime-Cognito-Identity": "cognito_identity",
+            "Lambda-Runtime-Aws-Tenant-Id": "tenant_id",
             "Content-Type": "application/json",
         }
         mock_runtime_client.next.return_value = response_body, headears
@@ -82,6 +86,7 @@ def test_wait_next_invocation(self, mock_runtime_client):
         self.assertEqual(event_request.deadline_time_in_ms, 12)
         self.assertEqual(event_request.client_context, "client_context")
         self.assertEqual(event_request.cognito_identity, "cognito_identity")
+        self.assertEqual(event_request.tenant_id, "tenant_id")
         self.assertEqual(event_request.content_type, "application/json")
         self.assertEqual(event_request.event_body, response_body)
 
@@ -97,9 +102,77 @@ def test_wait_next_invocation(self, mock_runtime_client):
         self.assertEqual(event_request.deadline_time_in_ms, 12)
         self.assertEqual(event_request.client_context, "client_context")
         self.assertEqual(event_request.cognito_identity, "cognito_identity")
+        self.assertEqual(event_request.tenant_id, "tenant_id")
         self.assertEqual(event_request.content_type, "application/json")
         self.assertEqual(event_request.event_body, response_body)
 
+    @patch("awslambdaric.lambda_runtime_client.runtime_client")
+    def test_wait_next_invocation_without_tenant_id_header(self, mock_runtime_client):
+        response_body = b"{}"
+        headers = {
+            "Lambda-Runtime-Aws-Request-Id": "RID1234",
+            "Lambda-Runtime-Trace-Id": "TID1234",
+            "Lambda-Runtime-Invoked-Function-Arn": "FARN1234",
+            "Lambda-Runtime-Deadline-Ms": 12,
+            "Lambda-Runtime-Client-Context": "client_context",
+            "Lambda-Runtime-Cognito-Identity": "cognito_identity",
+            "Content-Type": "application/json",
+        }
+        mock_runtime_client.next.return_value = response_body, headers
+        runtime_client = LambdaRuntimeClient("localhost:1234")
+
+        event_request = runtime_client.wait_next_invocation()
+
+        self.assertIsNotNone(event_request)
+        self.assertIsNone(event_request.tenant_id)
+        self.assertEqual(event_request.event_body, response_body)
+
+    @patch("awslambdaric.lambda_runtime_client.runtime_client")
+    def test_wait_next_invocation_with_null_tenant_id_header(self, mock_runtime_client):
+        response_body = b"{}"
+        headers = {
+            "Lambda-Runtime-Aws-Request-Id": "RID1234",
+            "Lambda-Runtime-Trace-Id": "TID1234",
+            "Lambda-Runtime-Invoked-Function-Arn": "FARN1234",
+            "Lambda-Runtime-Deadline-Ms": 12,
+            "Lambda-Runtime-Client-Context": "client_context",
+            "Lambda-Runtime-Cognito-Identity": "cognito_identity",
+            "Lambda-Runtime-Aws-Tenant-Id": None,
+            "Content-Type": "application/json",
+        }
+        mock_runtime_client.next.return_value = response_body, headers
+        runtime_client = LambdaRuntimeClient("localhost:1234")
+
+        event_request = runtime_client.wait_next_invocation()
+
+        self.assertIsNotNone(event_request)
+        self.assertIsNone(event_request.tenant_id)
+        self.assertEqual(event_request.event_body, response_body)
+
+    @patch("awslambdaric.lambda_runtime_client.runtime_client")
+    def test_wait_next_invocation_with_empty_tenant_id_header(
+        self, mock_runtime_client
+    ):
+        response_body = b"{}"
+        headers = {
+            "Lambda-Runtime-Aws-Request-Id": "RID1234",
+            "Lambda-Runtime-Trace-Id": "TID1234",
+            "Lambda-Runtime-Invoked-Function-Arn": "FARN1234",
+            "Lambda-Runtime-Deadline-Ms": 12,
+            "Lambda-Runtime-Client-Context": "client_context",
+            "Lambda-Runtime-Cognito-Identity": "cognito_identity",
+            "Lambda-Runtime-Aws-Tenant-Id": "",
+            "Content-Type": "application/json",
+        }
+        mock_runtime_client.next.return_value = response_body, headers
+        runtime_client = LambdaRuntimeClient("localhost:1234")
+
+        event_request = runtime_client.wait_next_invocation()
+
+        self.assertIsNotNone(event_request)
+        self.assertEqual(event_request.tenant_id, "")
+        self.assertEqual(event_request.event_body, response_body)
+
     error_result = {
         "errorMessage": "Dummy message",
         "errorType": "Runtime.DummyError",