update validation of Lambda AWS Proxy format
diff --git a/localstack/services/apigateway/integration.py b/localstack/services/apigateway/integration.py
index 6291170ef6ccd..30c5025af8275 100644
--- a/localstack/services/apigateway/integration.py
+++ b/localstack/services/apigateway/integration.py
@@ -216,8 +216,13 @@ def lambda_result_to_response(cls, result) -> LambdaResponse:
         parsed_result = common.json_safe(parsed_result)
         parsed_result = {} if parsed_result is None else parsed_result
 
-        keys = parsed_result.keys()
-        if "statusCode" not in keys or "body" not in keys:
+        if set(parsed_result) - {
+            "body",
+            "statusCode",
+            "headers",
+            "isBase64Encoded",
+            "multiValueHeaders",
+        }:
             LOG.warning(
                 'Lambda output should follow the next JSON format: { "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... },"body": "..."}\n Lambda output: %s',
                 parsed_result,
@@ -366,9 +371,13 @@ def invoke(self, invocation_context: ApiInvocationContext):
         parsed_result = common.json_safe(parsed_result)
         parsed_result = {} if parsed_result is None else parsed_result
 
-        keys = parsed_result.keys()
-
-        if not ("statusCode" in keys and "body" in keys):
+        if set(parsed_result) - {
+            "body",
+            "statusCode",
+            "headers",
+            "isBase64Encoded",
+            "multiValueHeaders",
+        }:
             LOG.warning(
                 'Lambda output should follow the next JSON format: { "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... },"body": "..."}\n Lambda output: %s',
                 parsed_result,
diff --git a/tests/aws/services/apigateway/test_apigateway_lambda.py b/tests/aws/services/apigateway/test_apigateway_lambda.py
index 846e728635778..9ff789cd670f2 100644
--- a/tests/aws/services/apigateway/test_apigateway_lambda.py
+++ b/tests/aws/services/apigateway/test_apigateway_lambda.py
@@ -15,6 +15,7 @@
 from tests.aws.services.apigateway.conftest import APIGATEWAY_ASSUME_ROLE_POLICY
 from tests.aws.services.lambda_.test_lambda import (
     TEST_LAMBDA_AWS_PROXY,
+    TEST_LAMBDA_AWS_PROXY_FORMAT,
     TEST_LAMBDA_MAPPING_RESPONSES,
     TEST_LAMBDA_PYTHON_ECHO,
     TEST_LAMBDA_PYTHON_SELECT_PATTERN,
@@ -666,3 +667,94 @@ def invoke_api(status_code):
     for status_code in status_codes:
         response = retry(invoke_api, sleep=2, retries=10, status_code=status_code)
         snapshot.match(f"lambda-selection-pattern-{status_code}", response.json())
+
+
+@markers.aws.validated
+def test_lambda_aws_proxy_response_format(
+    create_rest_apigw, create_lambda_function, create_role_with_policy, aws_client
+):
+    stage_name = "test"
+    _, role_arn = create_role_with_policy(
+        "Allow", "lambda:InvokeFunction", json.dumps(APIGATEWAY_ASSUME_ROLE_POLICY), "*"
+    )
+
+    # create 2 lambdas
+    function_name = f"test-function-{short_uid()}"
+    create_function_response = create_lambda_function(
+        func_name=function_name,
+        handler_file=TEST_LAMBDA_AWS_PROXY_FORMAT,
+        handler="lambda_aws_proxy_format.handler",
+        runtime=Runtime.python3_9,
+    )
+    # create invocation role
+    lambda_arn = create_function_response["CreateFunctionResponse"]["FunctionArn"]
+
+    # create rest api
+    api_id, _, root = create_rest_apigw(
+        name=f"test-api-{short_uid()}",
+        description="Integration test API",
+    )
+
+    resource_id = aws_client.apigateway.create_resource(
+        restApiId=api_id, parentId=root, pathPart="{proxy+}"
+    )["id"]
+
+    aws_client.apigateway.put_method(
+        restApiId=api_id,
+        resourceId=resource_id,
+        httpMethod="ANY",
+        authorizationType="NONE",
+    )
+
+    # Lambda AWS_PROXY integration
+    aws_client.apigateway.put_integration(
+        restApiId=api_id,
+        resourceId=resource_id,
+        httpMethod="ANY",
+        type="AWS_PROXY",
+        integrationHttpMethod="POST",
+        uri=f"arn:aws:apigateway:{aws_client.apigateway.meta.region_name}:lambda:path/2015-03-31/functions/{lambda_arn}/invocations",
+        credentials=role_arn,
+    )
+
+    aws_client.apigateway.create_deployment(restApiId=api_id, stageName=stage_name)
+
+    format_types = [
+        "no-body",
+        "only-headers",
+        "wrong-format",
+        "empty-response",
+    ]
+
+    for lambda_format_type in format_types:
+        # invoke rest api
+        invocation_url = api_invoke_url(
+            api_id=api_id,
+            stage=stage_name,
+            path=f"/{lambda_format_type}",
+        )
+
+        def invoke_api(url):
+            # use test header with different casing to check if it is preserved in the proxy payload
+            response = requests.get(
+                url,
+                headers={"User-Agent": "python-requests/testing"},
+                verify=False,
+            )
+            if lambda_format_type == "wrong-format":
+                assert response.status_code == 502
+            else:
+                assert response.status_code == 200
+            return response
+
+        # retry is necessary against AWS, probably IAM permission delay
+        response = retry(invoke_api, sleep=2, retries=10, url=invocation_url)
+
+        if lambda_format_type in ("no-body", "only-headers", "empty-response"):
+            assert response.content == b""
+            if lambda_format_type == "only-headers":
+                assert response.headers["test-header"] == "value"
+
+        elif lambda_format_type == "wrong-format":
+            assert response.status_code == 502
+            assert response.json() == {"message": "Internal server error"}
diff --git a/tests/aws/services/apigateway/test_apigateway_lambda.validation.json b/tests/aws/services/apigateway/test_apigateway_lambda.validation.json
index a6c2ed459bec3..048c33d769676 100644
--- a/tests/aws/services/apigateway/test_apigateway_lambda.validation.json
+++ b/tests/aws/services/apigateway/test_apigateway_lambda.validation.json
@@ -11,6 +11,9 @@
   "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_integration": {
     "last_validated_date": "2023-04-26T18:03:23+00:00"
   },
+  "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_aws_proxy_response_format": {
+    "last_validated_date": "2024-02-23T18:39:48+00:00"
+  },
   "tests/aws/services/apigateway/test_apigateway_lambda.py::test_lambda_selection_patterns": {
     "last_validated_date": "2023-09-05T19:54:21+00:00"
   }
diff --git a/tests/aws/services/lambda_/functions/lambda_aws_proxy_format.py b/tests/aws/services/lambda_/functions/lambda_aws_proxy_format.py
new file mode 100644
index 0000000000000..877059e1ca210
--- /dev/null
+++ b/tests/aws/services/lambda_/functions/lambda_aws_proxy_format.py
@@ -0,0 +1,22 @@
+import json
+
+
+def handler(event, context):
+    # Just print the event that was passed to the Lambda
+    print(json.dumps(event))
+    if event["path"] == "/no-body":
+        return {"statusCode": 200}
+    elif event["path"] == "/only-headers":
+        return {"statusCode": 200, "headers": {"test-header": "value"}}
+    elif event["path"] == "/wrong-format":
+        return {"statusCode": 200, "wrongValue": "value"}
+
+    elif event["path"] == "/empty-response":
+        return {}
+
+    else:
+        return {
+            "statusCode": 200,
+            "body": json.dumps(event),
+            "isBase64Encoded": False,
+        }
diff --git a/tests/aws/services/lambda_/test_lambda.py b/tests/aws/services/lambda_/test_lambda.py
index 9c1034a2ea855..ef3ae5defe805 100644
--- a/tests/aws/services/lambda_/test_lambda.py
+++ b/tests/aws/services/lambda_/test_lambda.py
@@ -68,6 +68,7 @@
 TEST_LAMBDA_PYTHON_HANDLER_ERROR = os.path.join(THIS_FOLDER, "functions/lambda_handler_error.py")
 TEST_LAMBDA_PYTHON_HANDLER_EXIT = os.path.join(THIS_FOLDER, "functions/lambda_handler_exit.py")
 TEST_LAMBDA_AWS_PROXY = os.path.join(THIS_FOLDER, "functions/lambda_aws_proxy.py")
+TEST_LAMBDA_AWS_PROXY_FORMAT = os.path.join(THIS_FOLDER, "functions/lambda_aws_proxy_format.py")
 TEST_LAMBDA_PYTHON_S3_INTEGRATION = os.path.join(THIS_FOLDER, "functions/lambda_s3_integration.py")
 TEST_LAMBDA_INTEGRATION_NODEJS = os.path.join(THIS_FOLDER, "functions/lambda_integration.js")
 TEST_LAMBDA_NODEJS = os.path.join(THIS_FOLDER, "functions/lambda_handler.js")

<!-- Please refer to the contribution guidelines before raising a PR: https://github.com/localstack/localstack/blob/master/CONTRIBUTING.md -->

<!-- Why am I raising this PR? Add context such as related issues, PRs, or documentation. -->
## Motivation
As reported in #10310, it seems we were overzealous over the validation of the output of the AWS Proxy lambda integration. 
We need to validate that no wrong fields are returned, but no field is mandatory. 

The documentation was not clear on that:
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

<!-- What notable changes does this PR make? -->
## Changes
- added a test to validate different formats of return of the lambda function
- updated the logic, not sure why it's duplicated in 2 spots but made it in both for now to be sure. We can refactor this in the future

<!-- The following sections are optional, but can be useful! 

## Testing

Description of how to test the changes

## TODO

What's left to do:

- [ ] ...
- [ ] ...

-->

