diff --git a/Call_Automation_GCCH/README.md b/Call_Automation_GCCH/README.md
new file mode 100644
index 0000000..0452404
--- /dev/null
+++ b/Call_Automation_GCCH/README.md
@@ -0,0 +1,59 @@
+|page_type| languages |products
+|---|---------------------------------------|---|
+|sample|
|| azure | azure-communication-services |
|
+
+# Call Automation - Quick Start Sample
+
+# Design
+
+
+
+## Prerequisites
+
+- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
+- A deployed Communication Services resource. [Create a Communication Services resource](https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource).
+- A [phone number](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/telephony/get-phone-number) in your Azure Communication Services resource that can make outbound calls. NB: phone numbers are not available in free subscriptions.
+- Create Azure AI Multi Service resource. For details, see [Create an Azure AI Multi service](https://learn.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account).
+- [Java Development Kit (JDK) Microsoft.OpenJDK.17](https://learn.microsoft.com/en-us/java/openjdk/download)
+- [Apache Maven](https://maven.apache.org/download.cgi)
+- Create and host a Azure Dev Tunnel. Instructions [here](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started)
+- (Optional) A Microsoft Teams user with a phone license that is `voice` enabled. Teams phone license is required to add Teams users to the call. Learn more about Teams licenses [here](https://www.microsoft.com/microsoft-teams/compare-microsoft-teams-bundle-options). Learn about enabling phone system with `voice` [here](https://learn.microsoft.com/microsoftteams/setting-up-your-phone-system). You also need to complete the prerequisite step [Authorization for your Azure Communication Services Resource](https://learn.microsoft.com/azure/communication-services/how-tos/call-automation/teams-interop-call-automation?pivots=programming-language-javascript#step-1-authorization-for-your-azure-communication-services-resource-to-enable-calling-to-microsoft-teams-users) to enable calling to Microsoft Teams users.
+
+## Before running the sample for the first time
+
+- Open the application.yml file in the resources folder to configure the following settings
+
+ - `connectionstring`: Azure Communication Service resource's connection string.
+ - `callerphonenumber`: Phone number associated with the Azure Communication Service resource.
+ - `targetphonenumber`: Target Phone number.
+
+ Format: "OutboundTarget(Phone Number)".
+
+ For e.g. "+1425XXXAAAA"
+ - `basecallbackuri`: Base url of the app. For local development use dev tunnel url.
+ - `cognitiveServiceEndpoint`: Cognitive Service Endpoint.
+ - `targetTeamsUserId`: (Optional) update field with the Microsoft Teams user Id you would like to add to the call. See [Use Graph API to get Teams user Id](../../../how-tos/call-automation/teams-interop-call-automation.md#step-2-use-the-graph-api-to-get-microsoft-entra-object-id-for-teams-users-and-optionally-check-their-presence). Uncomment the below snippet in ProgramSample.java to enable Teams Interop scenario.
+ ```
+ client.getCallConnection(callConnectionId).addParticipant(
+ new CallInvite(new MicrosoftTeamsUserIdentifier(appConfig.getTargetTeamsUserId()))
+ .setSourceDisplayName("Jack (Contoso Tech Support)"));
+ ```
+
+### Setup and host your Azure DevTunnel
+
+[Azure DevTunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/overview) is an Azure service that enables you to share local web services hosted on the internet. Use the commands below to connect your local development environment to the public internet. This creates a tunnel with a persistent endpoint URL and which allows anonymous access. We will then use this endpoint to notify your application of calling events from the ACS Call Automation service.
+
+```bash
+devtunnel create --allow-anonymous
+devtunnel port create -p 8080
+devtunnel host
+```
+
+### Run the application
+
+- Navigate to the directory containing the pom.xml file and use the following mvn commands:
+ - Compile the application: mvn compile
+ - Build the package: mvn package
+ - Execute the app: mvn exec:java
+- Access the Swagger UI at http://localhost:8080/swagger-ui.html
+ - Try the GET /outboundCall to run the Sample Application
diff --git a/Call_Automation_GCCH/pom.xml b/Call_Automation_GCCH/pom.xml
new file mode 100644
index 0000000..a28d028
--- /dev/null
+++ b/Call_Automation_GCCH/pom.xml
@@ -0,0 +1,177 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.6
+
+
+
+ com.communication.callautomation
+ Call_Automation_GCCH_Test_App
+ 1.0-SNAPSHOT
+
+ Call_Automation_GCCH_Test_App
+ CallAutomation Sample application for instructional usage
+
+
+ 17
+ 17
+ UTF-8
+ 1.18.26
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.vaadin.external.google
+ android-json
+
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ com.azure
+ azure-core
+ 1.39.0
+
+
+ com.azure
+ azure-identity
+ 1.9.0
+
+
+ com.azure
+ azure-communication-identity
+ 1.4.5
+
+
+ com.azure
+ azure-communication-common
+
+
+
+
+ com.azure
+ azure-communication-callautomation
+ 1.4.0-alpha.20250408.1
+
+
+ com.azure
+ azure-messaging-eventgrid
+ 4.16.0
+
+
+ com.azure
+ azure-communication-common
+ 2.0.0-beta.1
+
+
+ org.projectlombok
+ lombok
+ provided
+ ${lombok.version}
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure-processor
+ true
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 2.0.0
+
+
+
+
+ azure-sdk-for-java
+ https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-java/maven/v1
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.2.0
+
+
+ maven-resources-plugin
+ 3.3.1
+
+
+ maven-compiler-plugin
+ 3.11.0
+
+
+ maven-surefire-plugin
+ 3.1.0
+
+
+ maven-jar-plugin
+ 3.3.0
+
+
+ maven-deploy-plugin
+ 3.1.1
+
+
+ maven-site-plugin
+ 3.12.1
+
+
+ maven-project-info-reports-plugin
+ 3.4.3
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+
+ java
+
+
+
+
+ com.communication.callautomation.Main
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ConfigurationRequest.java b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ConfigurationRequest.java
new file mode 100644
index 0000000..d5bfdc9
--- /dev/null
+++ b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ConfigurationRequest.java
@@ -0,0 +1,66 @@
+package com.communication.callautomation;
+
+import java.util.Map;
+import lombok.Getter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+
+@ConfigurationProperties(prefix = "acs")
+@Getter
+public class ConfigurationRequest {
+ private String acsConnectionString;
+ private String cognitiveServiceEndpoint;
+ private String acsPhoneNumber;
+ private String callbackUriHost;
+ private Map botRouting;
+ private String defaultBotId;
+
+ // Getters and Setters
+ public String getAcsConnectionString() {
+ return acsConnectionString;
+ }
+
+ public void setAcsConnectionString(String acsConnectionString) {
+ this.acsConnectionString = acsConnectionString;
+ }
+
+ public String getCognitiveServiceEndpoint() {
+ return cognitiveServiceEndpoint;
+ }
+
+ public void setCognitiveServiceEndpoint(String cognitiveServiceEndpoint) {
+ this.cognitiveServiceEndpoint = cognitiveServiceEndpoint;
+ }
+
+ public String getAcsPhoneNumber() {
+ return acsPhoneNumber;
+ }
+
+ public void setAcsPhoneNumber(String acsPhoneNumber) {
+ this.acsPhoneNumber = acsPhoneNumber;
+ }
+
+ public String getCallbackUriHost() {
+ return callbackUriHost;
+ }
+
+ public void setCallbackUriHost(String callbackUriHost) {
+ this.callbackUriHost = callbackUriHost;
+ }
+
+ public Map getBotRouting() {
+ return botRouting;
+ }
+
+ public void setBotRouting(Map botRouting) {
+ this.botRouting = botRouting;
+ }
+
+ public String getDefaultBotId() {
+ return defaultBotId;
+ }
+
+ public void setDefaultBotId(String defaultBotId) {
+ this.defaultBotId = defaultBotId;
+ }
+}
diff --git a/Call_Automation_GCCH/src/main/java/com/communication/callautomation/Main.java b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/Main.java
new file mode 100644
index 0000000..85a3ed8
--- /dev/null
+++ b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/Main.java
@@ -0,0 +1,13 @@
+package com.communication.callautomation;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+
+@SpringBootApplication
+@EnableConfigurationProperties(value = ConfigurationRequest.class)
+public class Main {
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class, args);
+ }
+}
\ No newline at end of file
diff --git a/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ProgramSample.java b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ProgramSample.java
new file mode 100644
index 0000000..c4287e7
--- /dev/null
+++ b/Call_Automation_GCCH/src/main/java/com/communication/callautomation/ProgramSample.java
@@ -0,0 +1,1886 @@
+package com.communication.callautomation;
+
+import com.azure.communication.callautomation.CallAutomationAsyncClient;
+import com.azure.communication.callautomation.CallAutomationClient;
+import com.azure.communication.callautomation.CallAutomationClientBuilder;
+import com.azure.communication.callautomation.CallAutomationEventParser;
+import com.azure.communication.callautomation.CallConnection;
+import com.azure.communication.callautomation.CallDialog;
+import com.azure.communication.callautomation.CallMedia;
+import com.azure.communication.callautomation.implementation.models.PowerVirtualAgentsDialog;
+import com.azure.communication.callautomation.models.*;
+import com.azure.communication.callautomation.models.events.*;
+import com.azure.communication.common.CommunicationIdentifier;
+import com.azure.communication.common.CommunicationUserIdentifier;
+import com.azure.communication.common.MicrosoftTeamsUserIdentifier;
+import com.azure.communication.common.PhoneNumberIdentifier;
+import com.azure.communication.identity.implementation.models.CommunicationErrorResponseException;
+import com.azure.core.http.rest.PagedIterable;
+import com.azure.core.http.rest.Response;
+import com.azure.core.models.CloudEvent;
+import com.azure.core.util.Context;
+import com.azure.messaging.eventgrid.EventGridEvent;
+import com.azure.messaging.eventgrid.systemevents.AcsIncomingCallEventData;
+import com.azure.messaging.eventgrid.systemevents.AcsRecordingFileStatusUpdatedEventData;
+import com.azure.messaging.eventgrid.systemevents.SubscriptionValidationEventData;
+
+import lombok.extern.slf4j.Slf4j;
+import net.minidev.json.JSONObject;
+import reactor.core.publisher.Mono;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+
+@RestController
+@Slf4j
+public class ProgramSample {
+
+ private final ConfigurationRequest appConfig;
+ private CallAutomationClient client;
+ private final CallAutomationAsyncClient asyncClient;
+ // Configuration state variables
+ private String acsConnectionString = "";
+ private String cognitiveServicesEndpoint = "";
+ private String acsPhoneNumber = "";
+ private String callbackUriHost = "";
+ private String fileSourceUri = "";
+
+ private String callConnectionId = "";
+ private String recordingId = "";
+ private String recordingLocation = "";
+ private String recordingFileFormat = "";
+ private URI eventCallbackUri;
+
+ private String callerId = "";
+ private String calleeId = "";
+
+ private Map botRouting = new HashMap<>();
+ private String defaultBotId = "";
+ private static final String INCOMING_CALL_CONTEXT = "incomingCallContext";
+ private ConfigurationRequest configuration = new ConfigurationRequest();
+ private String confirmLabel = "Confirm";
+ private String cancelLabel = "Cancel";
+ public ProgramSample(final ConfigurationRequest appConfig) {
+ this.appConfig = appConfig;
+ client = initClient();
+ asyncClient = initAsyncClient();
+ }
+
+ @PostMapping(path = "/api/callback")
+ public ResponseEntity callbackEvents(@RequestBody final String reqBody) {
+ List events = CallAutomationEventParser.parseEvents(reqBody);
+ for (CallAutomationEventBase event : events) {
+ String callConnectionId = event.getCallConnectionId();
+ log.info(
+ "Received call event callConnectionID: {}, serverCallId: {}",
+ callConnectionId,
+ event.getServerCallId());
+
+ if (event instanceof CallConnected) {
+ // handle CallConnected
+ } else if (event instanceof RecognizeCompleted) {
+ // handle RecognizeCompleted
+ } else if (event instanceof RecognizeFailed) {
+ // handle RecognizeFailed
+ } else if (event instanceof PlayCompleted || event instanceof PlayFailed) {
+ // handle PlayCompleted or PlayFailed
+ }
+ }
+ return ResponseEntity.ok().body("");
+ }
+
+ @PostMapping("/api/setConfigurations")
+ public ResponseEntity setConfigurations(@RequestBody ConfigurationRequest configurationRequest) {
+ // Reset variables
+ acsConnectionString = "";
+ cognitiveServicesEndpoint = "";
+ acsPhoneNumber = "";
+ callbackUriHost = "";
+ fileSourceUri = "";
+
+ if (configurationRequest != null) {
+ configuration.setAcsConnectionString(
+ Optional.ofNullable(configurationRequest.getAcsConnectionString())
+ .filter(s -> !s.isEmpty())
+ .orElseThrow(() -> new IllegalArgumentException("AcsConnectionString is required"))
+ );
+
+ configuration.setCognitiveServiceEndpoint(
+ Optional.ofNullable(configurationRequest.getCognitiveServiceEndpoint())
+ .filter(s -> !s.isEmpty())
+ .orElseThrow(() -> new IllegalArgumentException("CognitiveServiceEndpoint is required"))
+ );
+
+ configuration.setAcsPhoneNumber(
+ Optional.ofNullable(configurationRequest.getAcsPhoneNumber())
+ .filter(s -> !s.isEmpty())
+ .orElseThrow(() -> new IllegalArgumentException("AcsPhoneNumber is required"))
+ );
+
+ configuration.setCallbackUriHost(
+ Optional.ofNullable(configurationRequest.getCallbackUriHost())
+ .filter(s -> !s.isEmpty())
+ .orElseThrow(() -> new IllegalArgumentException("CallbackUriHost is required"))
+ );
+
+ configuration.setBotRouting(
+ Optional.ofNullable(configurationRequest.getBotRouting())
+ .orElse(new HashMap<>())
+ );
+
+ configuration.setDefaultBotId(
+ Optional.ofNullable(configurationRequest.getDefaultBotId())
+ .filter(s -> !s.isEmpty())
+ .orElseThrow(() -> new IllegalArgumentException("DefaultBotId is required"))
+ );
+ }
+
+ // Assign to global variables
+ acsConnectionString = configuration.getAcsConnectionString();
+ cognitiveServicesEndpoint = configuration.getCognitiveServiceEndpoint();
+ acsPhoneNumber = configuration.getAcsPhoneNumber();
+ callbackUriHost = configuration.getCallbackUriHost();
+ botRouting = configuration.getBotRouting();
+ defaultBotId = configuration.getDefaultBotId();
+ fileSourceUri = "https://sample-videos.com/audio/mp3/crowd-cheering.mp3";
+
+ client = new CallAutomationClientBuilder()
+ .connectionString(acsConnectionString)
+ .buildClient();
+
+ log.info("Initialized call automation client.");
+ return ResponseEntity.ok("Configuration set successfully. Initialized call automation client.");
+ }
+ @PostMapping("/api/events")
+ public ResponseEntity