AWS announces preview of AWS Interconnect - multicloud
AWS announces AWS Interconnect – multicloud (preview), providing simple, resilient, high-speed private connections to other cloud service providers. AWS Interconnect - multicloud is easy to configure and provides high-speed, resilient connectivity with dedicated bandwidth, enabling customers to interconnect AWS networking services such as AWS Transit Gateway, AWS Cloud WAN, and Amazon VPC to other cloud service providers with ease.
How to Create Campaigns via API for Amazon Connect Outbound Campaigns
This guide explains how to programmatically create Amazon Connect Outbound Campaigns using AWS APIs. Since Campaign Flows (Type: CAMPAIGN) cannot be created through the UI, this article provides a complete workflow for extracting Campaign Flows from UI-created campaigns and reusing them in API-based campaign creation. It includes step-by-step AWS CLI commands, sample outputs, parameter explanations, workflow diagrams, and bash automation scripts for end-to-end campaign creation via API.
Understanding Campaign Flows vs Contact Flows
Amazon Connect outbound campaigns require two separate flows:
1. Campaign Flow (Type: CAMPAIGN)
- Manages campaign execution and engagement logic
- Contains retry/reattempt logic, delivery receipt evaluation, and engagement preference cycling
- Referenced via
connectCampaignFlowArnin CreateCampaign API - Cannot be created through the UI flow designer
2. Contact Flow (Type: CONTACT_FLOW)
- Defines customer experience when call is answered
- Contains Polly, Lex, business logic, and conversation flow
- Referenced via
connectContactFlowIdin campaign configuration
Key Point: When a call is answered, Amazon Connect automatically routes the customer to the connectContactFlowId. No transfer block is needed in the Campaign Flow.
Architecture Diagram
Understanding the Architecture:
This diagram illustrates the relationship between Campaign Flow and Contact Flow in Amazon Connect Outbound Campaigns:
Campaign Flow (Blue Section - Type CAMPAIGN):
- Step 1: Campaign starts and initiates the first dial attempt using PutDialRequest
- Step 2: System waits for a fixed period to allow the call to complete
- Step 3: Evaluates delivery receipts to determine call outcome (invalid number, busy, answered, etc.)
- Step 4-5: If invalid number or busy signal detected, waits before retry and attempts next engagement preference
- Step 6: Terminates execution with EndFlowExecution
Contact Flow (Orange Section - Type CONTACT_FLOW):
- This is an example only - you define your own customer experience
- When a call is answered, Amazon Connect automatically routes the customer here
- Can contain any blocks needed for your use case (Polly, Lex, business logic, etc.)
- The example shows a simple flow, but yours can be much more complex
Key Integration Point:
- The dotted line "Call Answered" shows the automatic routing from Campaign Flow to Contact Flow
- No transfer block is needed - Amazon Connect handles this automatically
- The Campaign Flow manages dialing and retries; the Contact Flow handles the conversation
Complete Workflow Diagram
Understanding the Workflow:
This sequence diagram shows the complete 8-step process for extracting and reusing Campaign Flows:
Phase 1: Extract Existing Campaign Flow (Steps 1-2)
- Step 1: Create a template campaign through the Amazon Connect UI with your desired retry settings
- Step 2: Use AWS CLI to describe the campaign and extract the connectCampaignFlowArn
- Purpose: Get the ARN of an existing Campaign Flow that contains the retry logic you want to reuse
Phase 2: Get Flow Content (Steps 3-5)
- Step 3: Extract the flow ID from the ARN
- Step 4: Use describe-contact-flow to retrieve the complete flow definition
- Step 5: Save the Content JSON to a file for reuse
- Purpose: Extract the actual flow definition (blocks, transitions, parameters) that you'll use to create new flows
Phase 3: Create New Campaign Flow (Steps 6-7)
- Step 6: Use create-contact-flow with type CAMPAIGN to create your reusable flow
- Step 7: Verify the flow is PUBLISHED and ACTIVE
- Purpose: Create a new Campaign Flow that you can use across multiple campaigns
Phase 4: Create Campaign (Step 8)
- Step 8: Use create-campaign with your new Campaign Flow ARN
- Purpose: Create a new campaign programmatically using your reusable Campaign Flow
Implementation Steps
Step 1: Create a Template Campaign via UI
- Log into Amazon Connect console
- Navigate to Outbound campaigns
- Create a new campaign with your desired retry settings
- Configure reattempt rules (e.g., retry on busy, invalid number)
- Save the campaign
Step 2: Describe the Campaign to Get Flow ARN
Command:
aws connectcampaignsv2 describe-campaign \ --id your-campaign-id
Sample Output:
{ "campaign": { "id": "campaign-id-example", "arn": "arn:aws:connect-campaigns:us-east-1:123456789012:campaign/campaign-id-example", "name": "my-test-campaign", "connectInstanceId": "instance-id-example", "connectCampaignFlowArn": "arn:aws:connect:us-east-1:123456789012:instance/instance-id-example/contact-flow/flow-campaign-example", "channelSubtypeConfig": { "telephony": { "capacity": 1.0, "connectQueueId": "queue-id-example", "defaultOutboundConfig": { "connectContactFlowId": "contact-flow-id-example", "connectSourcePhoneNumber": "+1-555-0100", "answerMachineDetectionConfig": { "enableAnswerMachineDetection": true, "awaitAnswerMachinePrompt": true } }, "outboundMode": { "agentless": {} } } }, "source": { "customerProfilesSegmentArn": "arn:aws:profile:us-east-1:123456789012:domains/domain-id/segments/segment-name" }, "schedule": { "startTime": "2025-12-02T19:30:00Z", "endTime": "2025-12-03T20:30:00Z" } } }
Key Parameters Explained:
id: Unique identifier for the campaignconnectCampaignFlowArn: ARN of the CAMPAIGN flow that manages execution logic (THIS IS WHAT YOU NEED)connectContactFlowId: ID of the CONTACT_FLOW that handles customer experiencecapacity: Dialing capacity allocation (0.01 to 1.0)answerMachineDetectionConfig: AMD settings for detecting voicemailoutboundMode.agentless: Indicates agentless campaign mode
Record the connectCampaignFlowArn
Step 3: Extract the Contact Flow ID
From the ARN, extract the flow ID (the last segment after /contact-flow/).
Using bash to extract:
FLOW_ID=$(echo "your-campaign-flow-arn" | awk -F'/' '{print $NF}') echo $FLOW_ID
Step 4: Describe the Contact Flow to Get Content
Command:
aws connect describe-contact-flow \ --instance-id your-instance-id \ --contact-flow-id flow-id-from-step-3
Sample Output:
{ "ContactFlow": { "Arn": "arn:aws:connect:us-east-1:123456789012:instance/instance-id-example/contact-flow/flow-campaign-example", "Id": "flow-campaign-example", "Name": "flow-campaign-example", "Type": "CAMPAIGN", "State": "ACTIVE", "Status": "PUBLISHED", "Description": "Flow designed to handle execution for the outbound campaign", "Content": "{\"Version\":\"2019-10-30\",\"StartAction\":\"FirstMessageSend\",\"Actions\":[...]}", "Tags": {}, "FlowContentSha256": "abc123def456", "LastModifiedTime": "2025-12-01T04:14:13.693000+00:00", "LastModifiedRegion": "us-east-1" } }
Key Parameters Explained:
Type: Must be "CAMPAIGN" for campaign flowsState: "ACTIVE" means the flow is available for useStatus: "PUBLISHED" means the flow is ready for campaignsContent: JSON string containing the flow definition (this is what you'll reuse)FlowContentSha256: Hash for version trackingLastModifiedTime: Timestamp of last modification
Step 5: Extract and Save the Content
Using jq to extract just the Content field:
aws connect describe-contact-flow \ --instance-id your-instance-id \ --contact-flow-id flow-id-from-step-3 \ --query 'ContactFlow.Content' \ --output text > campaign-flow-content.json
The saved file contains the complete flow definition with all blocks, transitions, and parameters.
Step 6: Create Your Own Campaign Flow
Command:
aws connect create-contact-flow \ --instance-id your-instance-id \ --name "my-reusable-campaign-flow" \ --content file://campaign-flow-content.json \ --type CAMPAIGN \ --description "Reusable campaign flow with retry logic"
Sample Output:
{ "ContactFlowId": "new-flow-id-example", "ContactFlowArn": "arn:aws:connect:us-east-1:123456789012:instance/instance-id-example/contact-flow/new-flow-id-example" }
Output Parameters Explained:
ContactFlowId: Unique identifier for the newly created flowContactFlowArn: Full ARN of the flow (use this inconnectCampaignFlowArn)
Record the ContactFlowArn - this is what you'll use in your campaigns.
Step 7: Verify Your Campaign Flow
Command:
aws connect describe-contact-flow \ --instance-id your-instance-id \ --contact-flow-id ContactFlowId-from-step-6
Verification Checklist:
- ✅
Type: "CAMPAIGN" - ✅
Status: "PUBLISHED" - ✅
State: "ACTIVE"
Step 8: Create a Campaign Using Your Campaign Flow
Once you have created your Campaign Flow, you can use it to create campaigns programmatically.
channel-config.json:
{ "telephony": { "capacity": 1.0, "connectQueueId": "queue-id-example", "outboundMode": { "agentless": {} }, "defaultOutboundConfig": { "connectContactFlowId": "contact-flow-id-example", "connectSourcePhoneNumber": "+1-555-0100", "answerMachineDetectionConfig": { "enableAnswerMachineDetection": true, "awaitAnswerMachinePrompt": true } } } }
source-config.json:
{ "customerProfilesSegmentArn": "arn:aws:profile:us-east-1:123456789012:domains/domain-id/segments/segment-name" }
schedule-config.json:
{ "startTime": "2025-12-02T19:30:00Z", "endTime": "2025-12-03T20:30:00Z" }
time-config.json:
{ "localTimeZoneConfig": { "defaultTimeZone": "America/New_York", "localTimeZoneDetection": ["AREA_CODE", "ZIP_CODE"] }, "telephony": { "openHours": { "dailyHours": { "MONDAY": [{"startTime": "T09:00", "endTime": "T17:00"}], "TUESDAY": [{"startTime": "T09:00", "endTime": "T17:00"}], "WEDNESDAY": [{"startTime": "T09:00", "endTime": "T17:00"}], "THURSDAY": [{"startTime": "T09:00", "endTime": "T17:00"}], "FRIDAY": [{"startTime": "T09:00", "endTime": "T17:00"}] } }, "restrictedPeriods": { "restrictedPeriodList": [ { "name": "Holiday Period", "startDate": "2025-12-24", "endDate": "2025-12-26" } ] } } }
limits-config.json:
{ "allChannelSubtypes": { "communicationLimitsList": [ { "maxCountPerRecipient": 3, "frequency": 1, "unit": "DAY" } ] }, "instanceLimitsHandling": "OPT_OUT" }
Complete Command:
aws connectcampaignsv2 create-campaign \ --name "my-automated-campaign" \ --connect-instance-id your-instance-id \ --connect-campaign-flow-arn "ContactFlowArn-from-step-6" \ --channel-subtype-config file://channel-config.json \ --source file://source-config.json \ --schedule file://schedule-config.json \ --communication-time-config file://time-config.json \ --communication-limits-override file://limits-config.json \ --tags owner=arn:aws:connect:us-east-1:123456789012:instance/your-instance-id
Sample Output:
{ "id": "campaign-id-example", "arn": "arn:aws:connect-campaigns:us-east-1:123456789012:campaign/campaign-id-example", "tags": { "owner": "arn:aws:connect:us-east-1:123456789012:instance/instance-id-example" } }
Output Parameters Explained:
id: Unique campaign identifier (use this to start/stop/manage the campaign)arn: Full ARN of the campaigntags: Tags associated with the campaign
Understanding Engagement Preference Cycling
Campaign Flows automatically cycle through customer engagement preferences defined in Amazon Connect Customer Profiles.
What are Engagement Preferences?
Engagement preferences specify the customer's preferred contact methods in priority order:
- HomePhoneNumber
- MobilePhoneNumber
- BusinessPhoneNumber
- PersonalEmailAddress
- BusinessEmailAddress
How Automatic Cycling Works:
This sequence diagram illustrates how Amazon Connect automatically manages engagement preference progression using a 3-preference example scenario:
Example Scenario (3 Preferences):
Attempt 1 (Index 0):
- Campaign Flow requests the first engagement preference (index 0)
- Customer Profiles returns MobilePhoneNumber
- Campaign Flow dials the number
- Customer responds with SIT_TONE_INVALID_NUMBER (invalid number detected)
- System waits before next attempt
Attempt 2 (Index 1):
- Campaign Flow automatically requests the next preference (index 1)
- Customer Profiles returns HomePhoneNumber
- Campaign Flow dials the number
- Customer responds with SIT_TONE_BUSY (line is busy)
- System waits before next attempt
Attempt 3 (Index 2):
- Campaign Flow automatically requests the next preference (index 2)
- Customer Profiles returns BusinessPhoneNumber
- Campaign Flow dials the number
- Customer answers the call successfully
- Customer is automatically connected to the Contact Flow for the conversation
Important Notes:
- This is an example - Customers may have 1, 2, 3, or more engagement preferences
- Single preference customers - If a customer has only one preference, the system will retry that preference based on delivery receipt evaluation
- Empty PutDialRequest parameters ({}) - Amazon Connect automatically manages preference progression regardless of how many preferences exist
- Per-recipient tracking - Each customer's preference cycling is independent based on their profile
- Wait periods between attempts allow for proper retry timing
- Delivery receipt evaluation determines when to retry vs. when to move to next preference
Complete End-to-End Bash Script
#!/bin/bash set -e # Configuration - REPLACE WITH YOUR VALUES INSTANCE_ID="your-instance-id" EXISTING_CAMPAIGN_ID="your-existing-campaign-id" NEW_FLOW_NAME="my-reusable-campaign-flow" NEW_CAMPAIGN_NAME="my-automated-campaign" QUEUE_ID="your-queue-id" CONTACT_FLOW_ID="your-contact-flow-id" SOURCE_PHONE="your-phone-number" SEGMENT_ARN="your-segment-arn" echo "=========================================" echo "Campaign Flow Extraction and Creation" echo "=========================================" # Step 1: Describe existing campaign echo "" echo "[Step 1] Describing existing campaign..." aws connectcampaignsv2 describe-campaign --id $EXISTING_CAMPAIGN_ID > campaign-details.json echo "✓ Campaign details saved" # Step 2: Extract campaign flow ARN echo "" echo "[Step 2] Extracting campaign flow ARN..." CAMPAIGN_FLOW_ARN=$(jq -r '.campaign.connectCampaignFlowArn' campaign-details.json) echo "Campaign Flow ARN: $CAMPAIGN_FLOW_ARN" # Step 3: Extract flow ID echo "" echo "[Step 3] Extracting flow ID..." FLOW_ID=$(echo $CAMPAIGN_FLOW_ARN | awk -F'/' '{print $NF}') echo "Flow ID: $FLOW_ID" # Step 4: Get flow content echo "" echo "[Step 4] Retrieving flow content..." aws connect describe-contact-flow --instance-id $INSTANCE_ID --contact-flow-id $FLOW_ID > flow-details.json echo "✓ Flow details saved" # Step 5: Extract content echo "" echo "[Step 5] Extracting flow content..." jq -r '.ContactFlow.Content' flow-details.json > campaign-flow-content.json echo "✓ Flow content saved" # Step 6: Create new campaign flow echo "" echo "[Step 6] Creating new campaign flow..." CREATE_RESPONSE=$(aws connect create-contact-flow --instance-id $INSTANCE_ID --name "$NEW_FLOW_NAME" --content file://campaign-flow-content.json --type CAMPAIGN --description "Reusable campaign flow with retry logic") NEW_FLOW_ARN=$(echo $CREATE_RESPONSE | jq -r '.ContactFlowArn') NEW_FLOW_ID=$(echo $CREATE_RESPONSE | jq -r '.ContactFlowId') echo "✓ New Flow ARN: $NEW_FLOW_ARN" # Step 7: Verify echo "" echo "[Step 7] Verifying flow..." aws connect describe-contact-flow --instance-id $INSTANCE_ID --contact-flow-id $NEW_FLOW_ID > new-flow-verification.json FLOW_TYPE=$(jq -r '.ContactFlow.Type' new-flow-verification.json) FLOW_STATUS=$(jq -r '.ContactFlow.Status' new-flow-verification.json) FLOW_STATE=$(jq -r '.ContactFlow.State' new-flow-verification.json) echo "✓ Flow Type: $FLOW_TYPE" echo "✓ Flow Status: $FLOW_STATUS" echo "✓ Flow State: $FLOW_STATE" # Step 8: Create campaign configuration files echo "" echo "[Step 8] Creating campaign..." # Create channel config cat > channel-config.json <<EOF { "telephony": { "capacity": 1.0, "connectQueueId": "$QUEUE_ID", "outboundMode": { "agentless": {} }, "defaultOutboundConfig": { "connectContactFlowId": "$CONTACT_FLOW_ID", "connectSourcePhoneNumber": "$SOURCE_PHONE", "answerMachineDetectionConfig": { "enableAnswerMachineDetection": true, "awaitAnswerMachinePrompt": true } } } } EOF # Create source config cat > source-config.json <<EOF { "customerProfilesSegmentArn": "$SEGMENT_ARN" } EOF # Create schedule config TOMORROW=$(date -u -d "+1 day" +"%Y-%m-%dT19:30:00Z") DAY_AFTER=$(date -u -d "+2 days" +"%Y-%m-%dT20:30:00Z") cat > schedule-config.json <<EOF { "startTime": "$TOMORROW", "endTime": "$DAY_AFTER" } EOF # Create campaign CAMPAIGN_RESPONSE=$(aws connectcampaignsv2 create-campaign --name "$NEW_CAMPAIGN_NAME" --connect-instance-id $INSTANCE_ID --connect-campaign-flow-arn "$NEW_FLOW_ARN" --channel-subtype-config file://channel-config.json --source file://source-config.json --schedule file://schedule-config.json --tags owner=arn:aws:connect:us-east-1:123456789012:instance/$INSTANCE_ID) CAMPAIGN_ID=$(echo $CAMPAIGN_RESPONSE | jq -r '.id') CAMPAIGN_ARN=$(echo $CAMPAIGN_RESPONSE | jq -r '.arn') echo "✓ Campaign created successfully" echo " Campaign ID: $CAMPAIGN_ID" echo " Campaign ARN: $CAMPAIGN_ARN" echo "" echo "=========================================" echo "✅ Process completed successfully!" echo "=========================================" echo "" echo "Campaign Flow ARN:" echo "$NEW_FLOW_ARN" echo "" echo "Campaign ID:" echo "$CAMPAIGN_ID" echo "" echo "Files created:" echo " - campaign-details.json" echo " - flow-details.json" echo " - campaign-flow-content.json" echo " - new-flow-verification.json" echo " - channel-config.json" echo " - source-config.json" echo " - schedule-config.json"
Troubleshooting: Common Bash Script Issues
If you encounter errors when running the bash script, try these solutions:
Issue 1: Windows Line Endings (CRLF)
Symptoms:
: invalid option
$'\r': command not found
Cause: Script was created/edited on Windows with CRLF line endings instead of Unix LF line endings.
Solution 1 - Using dos2unix (Recommended):
# Install dos2unix sudo yum install dos2unix # Amazon Linux/RHEL/CentOS # or sudo apt-get install dos2unix # Ubuntu/Debian # Convert the file dos2unix your-script.sh # Run the script bash your-script.sh
Solution 2 - Using sed:
sed -i 's/\r$//' your-script.sh bash your-script.sh
Solution 3 - Using tr:
tr -d '\r' < your-script.sh > your-script-fixed.sh chmod +x your-script-fixed.sh bash your-script-fixed.sh
Solution 4 - Recreate on Linux:
# Create new file directly on Linux nano your-script.sh # Paste content, save with Ctrl+X, Y, Enter chmod +x your-script.sh bash your-script.sh
Issue 2: Missing jq Command
Symptoms:
jq: command not found
Solution:
# Amazon Linux/RHEL/CentOS sudo yum install jq # Ubuntu/Debian sudo apt-get install jq # macOS brew install jq
Issue 3: AWS CLI Not Configured
Symptoms:
Unable to locate credentials
Solution:
aws configure # Enter your AWS Access Key ID # Enter your Secret Access Key # Enter default region (e.g., us-east-1) # Enter default output format (json)
Issue 4: Permission Denied
Symptoms:
bash: ./your-script.sh: Permission denied
Solution:
chmod +x your-script.sh ./your-script.sh
Issue 5: Script Debugging
To see detailed execution (helpful for troubleshooting):
bash -x your-script.sh
To check for syntax errors without running:
bash -n your-script.sh
Best Practices
- Reuse Campaign Flows: One Campaign Flow can be shared across multiple campaigns
- Separate Concerns: Keep campaign execution logic in CAMPAIGN flows, customer experience in CONTACT_FLOW
- Test Thoroughly: Create a test campaign via UI first to validate retry logic
- Document Your Flows: Add meaningful descriptions when creating flows
- Monitor Performance: Use CloudWatch metrics to track campaign execution
- Tag for UI Visibility: Add instance ID as a tag to make campaigns visible in the UI
Documentation References
- DescribeCampaign API: https://docs.aws.amazon.com/connect/latest/APIReference/API_connect-outbound-campaigns_DescribeCampaign.html
- CreateCampaign API (V2): https://docs.aws.amazon.com/connect/latest/APIReference/API_connect-outbound-campaigns-v2_CreateCampaign.html
- CreateContactFlow API: https://docs.aws.amazon.com/connect/latest/APIReference/API_CreateContactFlow.html
- DescribeContactFlow API: https://docs.aws.amazon.com/connect/latest/APIReference/API_DescribeContactFlow.html
- Customer Profiles Engagement Preferences: https://docs.aws.amazon.com/customerprofiles/latest/APIReference/API_EngagementPreferences.html
- Contact Preference Structure: https://docs.aws.amazon.com/customerprofiles/latest/APIReference/API_ContactPreference.html
- Profile API: https://docs.aws.amazon.com/customerprofiles/latest/APIReference/API_Profile.html
- Outbound Campaigns Overview: https://aws.amazon.com/connect/outbound/
- How to Create Campaigns: https://docs.aws.amazon.com/connect/latest/adminguide/how-to-create-campaigns.html
- Outbound Campaigns Workshop (Agentless): https://catalog.workshops.aws/amazon-connect-outbound-campaigns/en-US/3-voice/2-lab-voice/4-3-agentless
Relevant content
- Accepted Answerasked 12 days ago
AWS OFFICIALUpdated 4 months ago
AWS OFFICIALUpdated 4 years ago
AWS OFFICIALUpdated 2 years ago