diff --git a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py
index 10c70272c7d..e6f63c4792d 100644
--- a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py
+++ b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py
@@ -1,3 +1,4 @@
+from .apigw import ApiGatewayEnvelope
 from .base import BaseEnvelope
 from .cloudwatch import CloudWatchLogsEnvelope
 from .dynamodb import DynamoDBStreamEnvelope
@@ -7,6 +8,7 @@
 from .sqs import SqsEnvelope
 
 __all__ = [
+    "ApiGatewayEnvelope",
     "CloudWatchLogsEnvelope",
     "DynamoDBStreamEnvelope",
     "EventBridgeEnvelope",
diff --git a/aws_lambda_powertools/utilities/parser/envelopes/apigw.py b/aws_lambda_powertools/utilities/parser/envelopes/apigw.py
new file mode 100644
index 00000000000..6b74a3037e9
--- /dev/null
+++ b/aws_lambda_powertools/utilities/parser/envelopes/apigw.py
@@ -0,0 +1,32 @@
+import logging
+from typing import Any, Dict, Optional, Type, Union
+
+from ..models import APIGatewayProxyEventModel
+from ..types import Model
+from .base import BaseEnvelope
+
+logger = logging.getLogger(__name__)
+
+
+class ApiGatewayEnvelope(BaseEnvelope):
+    """API Gateway envelope to extract data within body key"""
+
+    def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Optional[Model]:
+        """Parses data found with model provided
+
+        Parameters
+        ----------
+        data : Dict
+            Lambda event to be parsed
+        model : Type[Model]
+            Data model provided to parse after extracting data using envelope
+
+        Returns
+        -------
+        Any
+            Parsed detail payload with model provided
+        """
+        logger.debug(f"Parsing incoming data with Api Gateway model {APIGatewayProxyEventModel}")
+        parsed_envelope = APIGatewayProxyEventModel.parse_obj(data)
+        logger.debug(f"Parsing event payload in `detail` with {model}")
+        return self._parse(data=parsed_envelope.body, model=model)
diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py
index 923d5d057c3..0e59b2197a8 100644
--- a/aws_lambda_powertools/utilities/parser/models/__init__.py
+++ b/aws_lambda_powertools/utilities/parser/models/__init__.py
@@ -1,4 +1,10 @@
 from .alb import AlbModel, AlbRequestContext, AlbRequestContextData
+from .apigw import (
+    APIGatewayEventAuthorizer,
+    APIGatewayEventIdentity,
+    APIGatewayEventRequestContext,
+    APIGatewayProxyEventModel,
+)
 from .cloudwatch import CloudWatchLogsData, CloudWatchLogsDecode, CloudWatchLogsLogEvent, CloudWatchLogsModel
 from .dynamodb import DynamoDBStreamChangedRecordModel, DynamoDBStreamModel, DynamoDBStreamRecordModel
 from .event_bridge import EventBridgeModel
@@ -70,4 +76,8 @@
     "SqsRecordModel",
     "SqsMsgAttributeModel",
     "SqsAttributesModel",
+    "APIGatewayProxyEventModel",
+    "APIGatewayEventRequestContext",
+    "APIGatewayEventAuthorizer",
+    "APIGatewayEventIdentity",
 ]
diff --git a/aws_lambda_powertools/utilities/parser/models/apigw.py b/aws_lambda_powertools/utilities/parser/models/apigw.py
new file mode 100644
index 00000000000..de968e20ecf
--- /dev/null
+++ b/aws_lambda_powertools/utilities/parser/models/apigw.py
@@ -0,0 +1,92 @@
+from datetime import datetime
+from typing import Any, Dict, List, Optional
+
+from pydantic import BaseModel, root_validator
+from pydantic.networks import IPvAnyNetwork
+
+from ..types import Literal
+
+
+class ApiGatewayUserCertValidity(BaseModel):
+    notBefore: str
+    notAfter: str
+
+
+class ApiGatewayUserCert(BaseModel):
+    clientCertPem: str
+    subjectDN: str
+    issuerDN: str
+    serialNumber: str
+    validity: ApiGatewayUserCertValidity
+
+
+class APIGatewayEventIdentity(BaseModel):
+    accessKey: Optional[str]
+    accountId: Optional[str]
+    apiKey: Optional[str]
+    apiKeyId: Optional[str]
+    caller: Optional[str]
+    cognitoAuthenticationProvider: Optional[str]
+    cognitoAuthenticationType: Optional[str]
+    cognitoIdentityId: Optional[str]
+    cognitoIdentityPoolId: Optional[str]
+    principalOrgId: Optional[str]
+    sourceIp: IPvAnyNetwork
+    user: Optional[str]
+    userAgent: Optional[str]
+    userArn: Optional[str]
+    clientCert: Optional[ApiGatewayUserCert]
+
+
+class APIGatewayEventAuthorizer(BaseModel):
+    claims: Optional[Dict[str, Any]]
+    scopes: Optional[List[str]]
+
+
+class APIGatewayEventRequestContext(BaseModel):
+    accountId: str
+    apiId: str
+    authorizer: APIGatewayEventAuthorizer
+    stage: str
+    protocol: str
+    identity: APIGatewayEventIdentity
+    requestId: str
+    requestTime: str
+    requestTimeEpoch: datetime
+    resourceId: Optional[str]
+    resourcePath: str
+    domainName: Optional[str]
+    domainPrefix: Optional[str]
+    extendedRequestId: Optional[str]
+    httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
+    path: str
+    connectedAt: Optional[datetime]
+    connectionId: Optional[str]
+    eventType: Optional[Literal["CONNECT", "MESSAGE", "DISCONNECT"]]
+    messageDirection: Optional[str]
+    messageId: Optional[str]
+    routeKey: Optional[str]
+    operationName: Optional[str]
+
+
+class APIGatewayProxyEventModel(BaseModel):
+    version: str
+    resource: str
+    path: str
+    httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
+    headers: Dict[str, str]
+    multiValueHeaders: Dict[str, List[str]]
+    queryStringParameters: Optional[Dict[str, str]]
+    multiValueQueryStringParameters: Optional[Dict[str, List[str]]]
+    requestContext: APIGatewayEventRequestContext
+    pathParameters: Optional[Dict[str, str]]
+    stageVariables: Optional[Dict[str, str]]
+    isBase64Encoded: bool
+    body: str
+
+    @root_validator()
+    def check_message_id(cls, values):
+        message_id, event_type = values.get("messageId"), values.get("eventType")
+        if message_id is not None and event_type != "MESSAGE":
+            raise TypeError("messageId is available only when the `eventType` is `MESSAGE`")
+        return values
diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md
index 7c39b1ffd0a..7fa78a5e372 100644
--- a/docs/utilities/parser.md
+++ b/docs/utilities/parser.md
@@ -161,6 +161,7 @@ Parser comes with the following built-in models:
 | **KinesisDataStreamModel** | Lambda Event Source payload for Amazon Kinesis Data Streams        |
 | **SesModel**               | Lambda Event Source payload for Amazon Simple Email Service        |
 | **SnsModel**               | Lambda Event Source payload for Amazon Simple Notification Service |
+| **APIGatewayProxyEvent**   | Lambda Event Source payload for Amazon API Gateway                 |
 
 ### extending built-in models
 
@@ -294,16 +295,16 @@ Here's an example of parsing a model found in an event coming from EventBridge,
 
 Parser comes with the following built-in envelopes, where `Model` in the return section is your given model.
 
-| Envelope name                 | Behaviour                                                                                                                                                                                                   | Return                             |
-| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
-| **DynamoDBStreamEnvelope**    | 1. Parses data using `DynamoDBStreamModel`. 
 2. Parses records in `NewImage` and `OldImage` keys using your model. 
 3. Returns a list with a dictionary containing `NewImage` and `OldImage` keys | `List[Dict[str, Optional[Model]]]` |
-| **EventBridgeEnvelope**       | 1. Parses data using `EventBridgeModel`. 
 2. Parses `detail` key using your model and returns it.                                                                                                      | `Model`                            |
-| **SqsEnvelope**               | 1. Parses data using `SqsModel`. 
 2. Parses records in `body` key using your model and return them in a list.                                                                                          | `List[Model]`                      |
-| **CloudWatchLogsEnvelope**    | 1. Parses data using `CloudwatchLogsModel` which will base64 decode and decompress it. 
 2. Parses records in `message` key using your model and return them in a list.                                 | `List[Model]`                      |
-| **KinesisDataStreamEnvelope** | 1. Parses data using `KinesisDataStreamModel` which will base64 decode it. 
 2. Parses records in in `Records` key using your model and returns them in a list.                                         | `List[Model]`                      |
-| **SnsEnvelope**               | 1. Parses data using `SnsModel`. 
 2. Parses records in `body` key using your model and return them in a list.                                                                                          | `List[Model]`                      |
-| **SnsSqsEnvelope**            | 1. Parses data using `SqsModel`. 
 2. Parses SNS records in `body` key using `SnsNotificationModel`. 
 3. Parses data in `Message` key using your model and return them in a list.                  | `List[Model]`                      |
-
+| Envelope name                                                                                                                                | Behaviour                                                                                                                                                                                                   | Return                             |
+| -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
+| **DynamoDBStreamEnvelope**                                                                                                                   | 1. Parses data using `DynamoDBStreamModel`. 
 2. Parses records in `NewImage` and `OldImage` keys using your model. 
 3. Returns a list with a dictionary containing `NewImage` and `OldImage` keys | `List[Dict[str, Optional[Model]]]` |
+| **EventBridgeEnvelope**                                                                                                                      | 1. Parses data using `EventBridgeModel`. 
 2. Parses `detail` key using your model and returns it.                                                                                                      | `Model`                            |
+| **SqsEnvelope**                                                                                                                              | 1. Parses data using `SqsModel`. 
 2. Parses records in `body` key using your model and return them in a list.                                                                                          | `List[Model]`                      |
+| **CloudWatchLogsEnvelope**                                                                                                                   | 1. Parses data using `CloudwatchLogsModel` which will base64 decode and decompress it. 
 2. Parses records in `message` key using your model and return them in a list.                                 | `List[Model]`                      |
+| **KinesisDataStreamEnvelope**                                                                                                                | 1. Parses data using `KinesisDataStreamModel` which will base64 decode it. 
 2. Parses records in in `Records` key using your model and returns them in a list.                                         | `List[Model]`                      |
+| **SnsEnvelope**                                                                                                                              | 1. Parses data using `SnsModel`. 
 2. Parses records in `body` key using your model and return them in a list.                                                                                          | `List[Model]`                      |
+| **SnsSqsEnvelope**                                                                                                                           | 1. Parses data using `SqsModel`. 
 2. Parses SNS records in `body` key using `SnsNotificationModel`. 
 3. Parses data in `Message` key using your model and return them in a list.                  | `List[Model]`                      |
+| **ApiGatewayEnvelope**         1. Parses data using `APIGatewayProxyEventModel`. 
 2. Parses `body` key using your model and returns it. | `Model`                                                                                                                                                                                                     |
 ### bringing your own envelope
 
 You can create your own Envelope model and logic by inheriting from `BaseEnvelope`, and implementing the `parse` method.
diff --git a/tests/events/apiGatewayProxyEvent.json b/tests/events/apiGatewayProxyEvent.json
index 1fed04a25bf..8bc72b7ce78 100644
--- a/tests/events/apiGatewayProxyEvent.json
+++ b/tests/events/apiGatewayProxyEvent.json
@@ -49,10 +49,20 @@
       "cognitoIdentityId": null,
       "cognitoIdentityPoolId": null,
       "principalOrgId": null,
-      "sourceIp": "IP",
+      "sourceIp": "192.168.0.1/32",
       "user": null,
       "userAgent": "user-agent",
-      "userArn": null
+      "userArn": null,
+      "clientCert": {
+        "clientCertPem": "CERT_CONTENT",
+        "subjectDN": "www.example.com",
+        "issuerDN": "Example issuer",
+        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
+        "validity": {
+          "notBefore": "May 28 12:30:02 2019 GMT",
+          "notAfter": "Aug  5 09:36:04 2021 GMT"
+        }
+      }
     },
     "path": "/my/path",
     "protocol": "HTTP/1.1",
@@ -67,4 +77,4 @@
   "stageVariables": null,
   "body": "Hello from Lambda!",
   "isBase64Encoded": true
-}
+}
\ No newline at end of file
diff --git a/tests/functional/parser/schemas.py b/tests/functional/parser/schemas.py
index a944b4f09c0..8ff56f703a7 100644
--- a/tests/functional/parser/schemas.py
+++ b/tests/functional/parser/schemas.py
@@ -81,3 +81,8 @@ class MyKinesisBusiness(BaseModel):
 class MyCloudWatchBusiness(BaseModel):
     my_message: str
     user: str
+
+
+class MyApiGatewayBusiness(BaseModel):
+    message: str
+    username: str
diff --git a/tests/functional/parser/test_apigw.py b/tests/functional/parser/test_apigw.py
new file mode 100644
index 00000000000..333654f3f89
--- /dev/null
+++ b/tests/functional/parser/test_apigw.py
@@ -0,0 +1,102 @@
+from aws_lambda_powertools.utilities.parser import envelopes, event_parser
+from aws_lambda_powertools.utilities.parser.models import APIGatewayProxyEventModel
+from aws_lambda_powertools.utilities.typing import LambdaContext
+from tests.functional.parser.schemas import MyApiGatewayBusiness
+from tests.functional.parser.utils import load_event
+
+
+@event_parser(model=MyApiGatewayBusiness, envelope=envelopes.ApiGatewayEnvelope)
+def handle_apigw_with_envelope(event: MyApiGatewayBusiness, _: LambdaContext):
+    assert event.message == "Hello"
+    assert event.username == "Ran"
+
+
+@event_parser(model=APIGatewayProxyEventModel)
+def handle_apigw_event(event: APIGatewayProxyEventModel, _: LambdaContext):
+    assert event.body == "Hello from Lambda!"
+    return event
+
+
+def test_apigw_event_with_envelope():
+    event = load_event("apiGatewayProxyEvent.json")
+    event["body"] = '{"message": "Hello", "username": "Ran"}'
+    handle_apigw_with_envelope(event, LambdaContext())
+
+
+def test_apigw_event():
+    event = load_event("apiGatewayProxyEvent.json")
+    parsed_event: APIGatewayProxyEventModel = handle_apigw_event(event, LambdaContext())
+    assert parsed_event.version == event["version"]
+    assert parsed_event.resource == event["resource"]
+    assert parsed_event.path == event["path"]
+    assert parsed_event.headers == event["headers"]
+    assert parsed_event.multiValueHeaders == event["multiValueHeaders"]
+    assert parsed_event.queryStringParameters == event["queryStringParameters"]
+    assert parsed_event.multiValueQueryStringParameters == event["multiValueQueryStringParameters"]
+
+    request_context = parsed_event.requestContext
+    assert request_context.accountId == event["requestContext"]["accountId"]
+    assert request_context.apiId == event["requestContext"]["apiId"]
+
+    authorizer = request_context.authorizer
+    assert authorizer.claims is None
+    assert authorizer.scopes is None
+
+    assert request_context.domainName == event["requestContext"]["domainName"]
+    assert request_context.domainPrefix == event["requestContext"]["domainPrefix"]
+    assert request_context.extendedRequestId == event["requestContext"]["extendedRequestId"]
+    assert request_context.httpMethod == event["requestContext"]["httpMethod"]
+
+    identity = request_context.identity
+    assert identity.accessKey == event["requestContext"]["identity"]["accessKey"]
+    assert identity.accountId == event["requestContext"]["identity"]["accountId"]
+    assert identity.caller == event["requestContext"]["identity"]["caller"]
+    assert (
+        identity.cognitoAuthenticationProvider == event["requestContext"]["identity"]["cognitoAuthenticationProvider"]
+    )
+    assert identity.cognitoAuthenticationType == event["requestContext"]["identity"]["cognitoAuthenticationType"]
+    assert identity.cognitoIdentityId == event["requestContext"]["identity"]["cognitoIdentityId"]
+    assert identity.cognitoIdentityPoolId == event["requestContext"]["identity"]["cognitoIdentityPoolId"]
+    assert identity.principalOrgId == event["requestContext"]["identity"]["principalOrgId"]
+    assert str(identity.sourceIp) == event["requestContext"]["identity"]["sourceIp"]
+    assert identity.user == event["requestContext"]["identity"]["user"]
+    assert identity.userAgent == event["requestContext"]["identity"]["userAgent"]
+    assert identity.userArn == event["requestContext"]["identity"]["userArn"]
+    assert identity.clientCert is not None
+    assert identity.clientCert.clientCertPem == event["requestContext"]["identity"]["clientCert"]["clientCertPem"]
+    assert identity.clientCert.subjectDN == event["requestContext"]["identity"]["clientCert"]["subjectDN"]
+    assert identity.clientCert.issuerDN == event["requestContext"]["identity"]["clientCert"]["issuerDN"]
+    assert identity.clientCert.serialNumber == event["requestContext"]["identity"]["clientCert"]["serialNumber"]
+    assert (
+        identity.clientCert.validity.notBefore
+        == event["requestContext"]["identity"]["clientCert"]["validity"]["notBefore"]
+    )
+    assert (
+        identity.clientCert.validity.notAfter
+        == event["requestContext"]["identity"]["clientCert"]["validity"]["notAfter"]
+    )
+
+    assert request_context.path == event["requestContext"]["path"]
+    assert request_context.protocol == event["requestContext"]["protocol"]
+    assert request_context.requestId == event["requestContext"]["requestId"]
+    assert request_context.requestTime == event["requestContext"]["requestTime"]
+    convert_time = int(round(request_context.requestTimeEpoch.timestamp() * 1000))
+    assert convert_time == 1583349317135
+    assert request_context.resourceId == event["requestContext"]["resourceId"]
+    assert request_context.resourcePath == event["requestContext"]["resourcePath"]
+    assert request_context.stage == event["requestContext"]["stage"]
+
+    assert parsed_event.pathParameters == event["pathParameters"]
+    assert parsed_event.stageVariables == event["stageVariables"]
+    assert parsed_event.body == event["body"]
+    assert parsed_event.isBase64Encoded == event["isBase64Encoded"]
+
+    assert request_context.connectedAt is None
+    assert request_context.connectionId is None
+    assert request_context.eventType is None
+    assert request_context.messageDirection is None
+    assert request_context.messageId is None
+    assert request_context.routeKey is None
+    assert request_context.operationName is None
+    assert identity.apiKey is None
+    assert identity.apiKeyId is None