Envelopes extract nested payloads from AWS event wrappers and validate the inner data.
AWS events wrap business data in service-specific metadata. Envelopes automatically extract and validate the nested payload.
Example: SQS event has data in Records[].body, EventBridge in detail, API Gateway in body.
| Type | Returns | Use Case |
|---|---|---|
| ObjectEnvelope | Single object | Events with one payload (API Gateway, EventBridge) |
| ArrayEnvelope | Array of objects | Events with multiple records (SQS, Kinesis, SNS) |
| DynamoDBArrayEnvelope | Array with NewImage/OldImage | DynamoDB Streams with before/after snapshots |
| Envelope | Type | Extracts From | Returns | Common With |
|---|---|---|---|---|
| ApiGatewayEnvelope | Object | event.body | T | JSONStringified |
| ApiGatewayV2Envelope | Object | event.body | T | JSONStringified |
| CloudWatchEnvelope | Array | event.awslogs.data.logEvents[].message | T[] | JSONStringified |
| DynamoDBStreamEnvelope | DynamoDB | event.Records[].dynamodb.{NewImage,OldImage} | {NewImage?: T, OldImage?: T}[] | DynamoDBMarshalled |
| EventBridgeEnvelope | Object | event.detail | T | - |
| KafkaEnvelope | Array | event.records[topic][].value | T[] | JSONStringified |
| KinesisEnvelope | Array | event.Records[].kinesis.data | T[] | Base64Encoded, JSONStringified |
| KinesisFirehoseEnvelope | Array | event.records[].data | T[] | Base64Encoded, JSONStringified |
| LambdaFunctionUrlEnvelope | Object | event.body | T | JSONStringified |
| SnsEnvelope | Array | event.Records[].Sns.Message | T[] | JSONStringified |
| SnsSqsEnvelope | Array | JSON.parse(event.Records[].body).Message | T[] | JSONStringified |
| SqsEnvelope | Array | event.Records[].body | T[] | JSONStringified |
| VpcLatticeEnvelope | Object | event.body | T | JSONStringified |
| VpcLatticeV2Envelope | Object | event.body | T | JSONStringified |
import { parse } from '@aws-lambda-powertools/parser';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { z } from 'zod';
const schema = z.object({ orderId: z.string(), amount: z.number() });
// Throws on error
const order = parse(event, EventBridgeEnvelope, schema);
// Safe parsing
const result = parse(event, EventBridgeEnvelope, schema, true);
if (result.success) console.log(result.data);import { parser } from '@aws-lambda-powertools/parser';
import { SqsEnvelope } from '@aws-lambda-powertools/parser/envelopes';
class Handler {
@parser({ schema: taskSchema, envelope: SqsEnvelope })
async handler(event: Task[], _context: Context) {
// event is Array<Task> (extracted from SQS records)
event.forEach(task => console.log(task.taskId));
}
}import { parser } from '@aws-lambda-powertools/parser/middleware';
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import middy from '@middy/core';
export const handler = middy()
.use(parser({ schema: orderSchema, envelope: EventBridgeEnvelope }))
.handler(async (event) => {
// event is Order (extracted from EventBridge detail)
console.log(event.orderId);
});import { SqsEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
// Throws on error
const tasks = SqsEnvelope.parse(event, JSONStringified(taskSchema));
// Safe parsing
const result = SqsEnvelope.safeParse(event, JSONStringified(taskSchema));
if (result.success) {
console.log(`Parsed ${result.data.length} tasks`);
} else {
console.error(result.error.message);
}import { SqsEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
const tasks = SqsEnvelope.parse(event, JSONStringified(taskSchema));import { KinesisEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { Base64Encoded, JSONStringified } from '@aws-lambda-powertools/parser/helpers';
const clicks = KinesisEnvelope.parse(
event,
Base64Encoded(JSONStringified(clickSchema))
);import { DynamoDBStreamEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { DynamoDBMarshalled } from '@aws-lambda-powertools/parser/helpers/dynamodb';
const records = DynamoDBStreamEnvelope.parse(
event,
DynamoDBMarshalled(productSchema)
);
records.forEach(record => {
if (record.NewImage) console.log('New:', record.NewImage);
if (record.OldImage) console.log('Old:', record.OldImage);
});import { SnsSqsEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
// Handles JSON.parse(sqs.body).Message
const alerts = SnsSqsEnvelope.parse(event, JSONStringified(alertSchema));const result = SqsEnvelope.safeParse(event, JSONStringified(schema));
if (!result.success) {
console.error('Parse error:', result.error.message);
console.error('Error cause:', result.error.cause);
console.error('Original event:', result.originalEvent);
}interface ArrayEnvelope {
parse<T>(data: unknown, schema: ZodType<T>): T[];
safeParse<T>(data: unknown, schema: ZodType<T>): ParsedResult<unknown, T[]>;
}
interface ObjectEnvelope {
parse<T>(data: unknown, schema: ZodType<T>): T;
safeParse<T>(data: unknown, schema: ZodType<T>): ParsedResult<unknown, T>;
}
interface DynamoDBArrayEnvelope {
parse<T>(data: unknown, schema: ZodType<T>): DynamoDBStreamEnvelopeResponse<T>[];
safeParse<T>(data: unknown, schema: ZodType<T>): ParsedResult<unknown, DynamoDBStreamEnvelopeResponse<T>[]>;
}
interface DynamoDBStreamEnvelopeResponse<T> {
NewImage?: T;
OldImage?: T;
}