diff --git a/appsync-events-bedrock-cdk/.gitignore b/appsync-events-bedrock-cdk/.gitignore
new file mode 100644
index 000000000..e69e6fe04
--- /dev/null
+++ b/appsync-events-bedrock-cdk/.gitignore
@@ -0,0 +1,9 @@
+*.js
+!jest.config.js
+*.d.ts
+node_modules
+
+# CDK asset staging directory
+.cdk.staging
+cdk-outputs.json
+cdk.out
diff --git a/appsync-events-bedrock-cdk/.npmignore b/appsync-events-bedrock-cdk/.npmignore
new file mode 100644
index 000000000..c1d6d45dc
--- /dev/null
+++ b/appsync-events-bedrock-cdk/.npmignore
@@ -0,0 +1,6 @@
+*.ts
+!*.d.ts
+
+# CDK asset staging directory
+.cdk.staging
+cdk.out
diff --git a/appsync-events-bedrock-cdk/README.md b/appsync-events-bedrock-cdk/README.md
new file mode 100644
index 000000000..57871f657
--- /dev/null
+++ b/appsync-events-bedrock-cdk/README.md
@@ -0,0 +1,94 @@
+# Stream Amazon Bedrock completions via AWS AppSync Events API
+
+This pattern shows how to stream Amazon Bedrock completions via AWS AppSync Events API.
+
+Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/appsync-events-bedrock
+
+Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
+
+
+## Requirements
+* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
+* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
+* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
+* [Node and NPM](https://nodejs.org/en/download/) installed
+* [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) (AWS CDK) installed
+* Make sure to enable the **Anthropic - Claude 3 Haiku** model on the [Bedrock console](https://console.aws.amazon.com/bedrock/home#/modelaccess).
+
+
+## How it works
+
+1. The client connects to the WebSocket using the AWS Amplify client or a custom made library following the [instructions described in the documentation](https://docs.aws.amazon.com/appsync/latest/eventapi/event-api-websocket-protocol.html);
+2. The client chooses a namespace or a channel (or a segment) and subscribes to it. [Additional info the documentation](https://docs.aws.amazon.com/appsync/latest/eventapi/event-api-websocket-protocol.html);
+3. The client performs a request towards the Amazon API Gateway that exposes a `/chat` route passing the `userId` and `prompt` parameters. The `userId` will be used as a segment for the channel. The prompt will be used for GenAI completions on Bedrock;
+4. The triggered Lambda function receives payload;
+5. The Lambda function proceeds to invoke a Bedrock model using the streaming API;
+6. The Lambda function will receive the completion `chunks` as soon as they are available;
+7. For each completion chunk, the Lambda function will publish them through the [Publish HTTP API on AppSync Events](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-http.html);
+8. The client is now able to retrieve the completion chunks from AppSync Events;
+9. The client can finally unsubscribe from the channel and close the Websocket connection.
+
+### Permissions and Security
+In this demo the client is only able to subscribe to the AppSync Event WebSocket via the API_KEY. The same API_KEY will be used by the Lambda function to perform publish requests.
+
+
+## Deployment Instructions
+
+1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
+```sh
+git clone https://github.com/aws-samples/serverless-patterns
+```
+2. Change directory to the pattern directory:
+```sh
+cd appsync-events-bedrock-cdk
+```
+3. Install the required dependencies:
+```sh
+npm install
+```
+4. Deploy the stack to your default AWS account and region:
+```sh
+npm run deploy
+```
+5. Export the environment variables for the demo web app:
+```sh
+npm run export-outputs
+```
+6. Install dependencies for the demo web app:
+```sh
+cd demo-app && npm install
+```
+7. Launch the demo web app
+```sh
+npm run dev
+```
+
+## Testing
+Integration tests can be ran with jest from the pattern's root directory:
+```sh
+npm run test
+```
+
+From the demo app it's possible to see all connection events and data events in a structured way.
+First of all connect to the WebSocket
+
+
+Then subscribe to the namespace. Please note: The default namespace is `BedrockChat`. By inserting `BedrockChat/*` you will be able to receive all the messages in the sub-segments.
+
+
+Finally, insert your username (the final segment will become `BedrockChat/username`) and your prompt.
+
+
+By clicking on the `realtime` entry on the networking tab and selecting `messages` you will see all the messages exchanged between the client demo app and AppSync Event API. For convienence I've setup two scrollable boxes that display the same data.
+
+
+## Cleanup
+Close the demo web app by hitting `^C` on MacOs.
+
+Return to the pattern's root folder and delete the stack:
+```sh
+cdk destroy --all
+```
+----
+Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: MIT-0
diff --git a/appsync-events-bedrock-cdk/appsync-events-bedrock-cdk.json b/appsync-events-bedrock-cdk/appsync-events-bedrock-cdk.json
new file mode 100644
index 000000000..5e3929369
--- /dev/null
+++ b/appsync-events-bedrock-cdk/appsync-events-bedrock-cdk.json
@@ -0,0 +1,90 @@
+{
+ "title": "Stream Amazon Bedrock completions via AWS AppSync Events API",
+ "description": "Leverage AppSync Events API to stream completions from Amazon Bedrock.",
+ "language": "TypeScript",
+ "level": "200",
+ "framework": "CDK",
+ "introBox": {
+ "headline": "How it works",
+ "text": [
+ "In this pattern the end user is able to provide a prompt that will be used to invoke an Amazon Bedrock model from via a Lambda middleware.",
+ "The client will receive the model's completions through WebSocket provided by AppSync Events."
+ ]
+ },
+ "gitHub": {
+ "template": {
+ "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/appsync-events-bedrock-cdk",
+ "templateURL": "serverless-patterns/appsync-events-bedrock-cdk",
+ "projectFolder": "appsync-events-bedrock-cdk",
+ "templateFile": "lib/appsync-events-bedrock-cdk-stack.ts"
+ }
+ },
+ "resources": {
+ "bullets": [
+ {
+ "text": "AppSync Events API",
+ "link": "https://docs.aws.amazon.com/appsync/latest/eventapi/event-api-welcome.html"
+ },
+ {
+ "text": "Amazon Bedrock - Generative AI",
+ "link": "https://aws.amazon.com/bedrock/"
+ },
+ {
+ "text": "Bedrock's Response Stream API",
+ "link": "https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html"
+ }
+ ]
+ },
+ "deploy": {
+ "text": [
+ "npm run deploy"
+ ]
+ },
+ "testing": {
+ "text": [
+ "npm run test"
+ ]
+ },
+ "cleanup": {
+ "text": [
+ "cdk destroy"
+ ]
+ },
+ "authors": [
+ {
+ "name": "Gabriele Biagini",
+ "bio": "Solutions Architect @ AWS",
+ "linkedin": "gbiagini97"
+ }
+ ],
+ "patternArch": {
+ "icon1": {
+ "x": 20,
+ "y": 50,
+ "service": "apigw",
+ "label": "Amazon API Gateway"
+ },
+ "icon2": {
+ "x": 50,
+ "y": 50,
+ "service": "lambda",
+ "label": "AWS Lambda"
+ },
+ "icon3": {
+ "x": 80,
+ "y": 50,
+ "service": "bedrock",
+ "label": "Amazon Bedrock"
+ },
+ "line1": {
+ "from": "icon1",
+ "to": "icon2",
+ "label": "WebSocket"
+ },
+ "line2": {
+ "from": "icon2",
+ "to": "icon3",
+ "label": ""
+ }
+ }
+}
diff --git a/appsync-events-bedrock-cdk/bin/appsync-events-bedrock-cdk.ts b/appsync-events-bedrock-cdk/bin/appsync-events-bedrock-cdk.ts
new file mode 100644
index 000000000..bdd9465a1
--- /dev/null
+++ b/appsync-events-bedrock-cdk/bin/appsync-events-bedrock-cdk.ts
@@ -0,0 +1,21 @@
+#!/usr/bin/env node
+import 'source-map-support/register';
+import * as cdk from 'aws-cdk-lib';
+import { AppsyncEventsBedrockCdkStack } from '../lib/appsync-events-bedrock-cdk-stack';
+
+const app = new cdk.App();
+new AppsyncEventsBedrockCdkStack(app, 'AppsyncEventsBedrockCdkStack', {
+ /* If you don't specify 'env', this stack will be environment-agnostic.
+ * Account/Region-dependent features and context lookups will not work,
+ * but a single synthesized template can be deployed anywhere. */
+
+ /* Uncomment the next line to specialize this stack for the AWS Account
+ * and Region that are implied by the current CLI configuration. */
+ // env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
+
+ /* Uncomment the next line if you know exactly what Account and Region you
+ * want to deploy the stack to. */
+ // env: { account: '123456789012', region: 'us-east-1' },
+
+ /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
+});
\ No newline at end of file
diff --git a/appsync-events-bedrock-cdk/cdk.json b/appsync-events-bedrock-cdk/cdk.json
new file mode 100644
index 000000000..705e36c4f
--- /dev/null
+++ b/appsync-events-bedrock-cdk/cdk.json
@@ -0,0 +1,80 @@
+{
+ "app": "npx tsx bin/appsync-events-bedrock-cdk.ts",
+ "watch": {
+ "include": [
+ "**"
+ ],
+ "exclude": [
+ "README.md",
+ "cdk*.json",
+ "**/*.d.ts",
+ "**/*.js",
+ "tsconfig.json",
+ "package*.json",
+ "yarn.lock",
+ "node_modules",
+ "test"
+ ]
+ },
+ "context": {
+ "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
+ "@aws-cdk/core:checkSecretUsage": true,
+ "@aws-cdk/core:target-partitions": [
+ "aws",
+ "aws-cn"
+ ],
+ "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
+ "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
+ "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
+ "@aws-cdk/aws-iam:minimizePolicies": true,
+ "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
+ "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
+ "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
+ "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
+ "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
+ "@aws-cdk/core:enablePartitionLiterals": true,
+ "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
+ "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
+ "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
+ "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
+ "@aws-cdk/aws-route53-patters:useCertificate": true,
+ "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
+ "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
+ "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
+ "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
+ "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
+ "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
+ "@aws-cdk/aws-redshift:columnId": true,
+ "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
+ "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
+ "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
+ "@aws-cdk/aws-kms:aliasNameRef": true,
+ "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
+ "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
+ "@aws-cdk/aws-efs:denyAnonymousAccess": true,
+ "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
+ "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
+ "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
+ "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
+ "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
+ "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
+ "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
+ "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
+ "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
+ "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
+ "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
+ "@aws-cdk/aws-eks:nodegroupNameAttribute": true,
+ "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
+ "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
+ "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
+ "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
+ "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
+ "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
+ "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
+ "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
+ "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
+ "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
+ "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
+ "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true
+ }
+}
diff --git a/appsync-events-bedrock-cdk/demo-app/.gitignore b/appsync-events-bedrock-cdk/demo-app/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/appsync-events-bedrock-cdk/demo-app/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/appsync-events-bedrock-cdk/demo-app/README.md b/appsync-events-bedrock-cdk/demo-app/README.md
new file mode 100644
index 000000000..ba94e3c72
--- /dev/null
+++ b/appsync-events-bedrock-cdk/demo-app/README.md
@@ -0,0 +1 @@
+Follow instructions in the pattern's root folder [README](../README.md).
\ No newline at end of file
diff --git a/appsync-events-bedrock-cdk/demo-app/index.html b/appsync-events-bedrock-cdk/demo-app/index.html
new file mode 100644
index 000000000..e4b78eae1
--- /dev/null
+++ b/appsync-events-bedrock-cdk/demo-app/index.html
@@ -0,0 +1,13 @@
+
+
+