Real-Time Task Tracking for Workforce Management: Integrating Amazon Connect Tasks with Kinesis Agent Event Streams
Learn how to integrate Amazon Connect Tasks with Kinesis Agent Event Streams to give workforce management systems real-time visibility into task assignments, pauses and completions; enabling Extended Work Distribution (EWD) patterns that automatically fill agent idle time with productive work.
Modern contact centers assign agents more than just phone calls. Between handling callbacks, resolving cases, and completing follow-up tasks, agents spend a significant portion of their day on non-real-time work. Workforce management (WFM) tools need visibility into all agent activities, not just voice and chat, to make accurate scheduling and staffing decisions.
Amazon Connect Tasks provides a native task channel that lets you prioritize, assign, and track work items alongside voice and chat contacts. However, third-party WFM systems need a real-time event feed to understand when agents are working tasks versus being available for new contacts.
In this post, I'll walk through how to integrate Amazon Connect Tasks with Kinesis Agent Event Streams to give your WFM system real-time visibility into task lifecycle events, enabling a pattern known as Extended Work Distribution (EWD).
The Use Case: Extended Work Distribution (EWD)
Extended Work Distribution (EWD) is a workforce optimization strategy where non-real-time tasks are dynamically assigned to agents during idle periods between customer interactions. Instead of agents sitting idle between calls or manually checking a backlog, EWD systems automatically push work items: email responses, case updates, training modules or compliance tasks to agents based on their skills, availability and schedule adherence.
WFM tools orchestrate this by:
- Detecting agent idle time via real-time event feeds
- Selecting appropriate tasks from a work queue
- Pushing tasks to agents via the Amazon Connect
StartTaskContactAPI - Tracking task completion to update schedule adherence metrics
The critical gap: without an event feed, the WFM system doesn't know when a task is accepted, in-progress, paused, or completed. The agent appears "available" in the WFM system while actively working a task; leading to double-assignments, inaccurate schedule adherence and poor agent experience.
Amazon Connect's Agent Event Stream solves this by publishing every agent state change, including task-related state transitions, to a Kinesis Data Stream in near real-time.
Architecture Overview
The integration is bidirectional: the WFM system creates tasks via the Connect API and receives state changes via Kinesis.

Key components:
- Task Queue - Dedicated queue for EWD tasks, separate from voice/chat queues
- Routing Profile - Multi-channel profile enabling concurrent task handling alongside voice
- Agent Event Stream - Kinesis-backed stream capturing all agent state transitions
- Lambda Consumer - Filters task-specific events and transforms them into WFM-compatible payloads
Setting Up the Task Channel
Step 1: Create a Task-Specific Queue
Create a dedicated queue for EWD tasks. This separation allows you to manage task SLAs independently from voice/chat and gives you clean metrics.
In the Amazon Connect console:
- Navigate to Routing → Queues → Add new queue
- Name it (e.g.,
EWD-Tasks) - Set hours of operation (typically aligned with agent schedules)
Step 2: Configure the Routing Profile
Your routing profile must enable the TASK channel alongside VOICE. Key settings:
- Channel: Add TASK to the routing profile
- Cross-channel concurrency: Set tasks to "Allow other channels concurrently" so agents receive tasks during idle time. Voice typically set to "No other channels while on voice" to avoid interruptions
- Priority & Delay: Set task queue priority lower than voice queues so calls always take precedence
Example configuration:

Step 3: Build the Task Contact Flow
Create a contact flow for incoming tasks:
- Set working queue →
EWD-Tasks - Check queue status → (optional) verify agent availability before queuing
- Transfer to queue → routes the task to an available agent
For EWD, keep the flow simple. The WFM system handles the intelligence of when to create tasks. The flow just needs to route them correctly.
Step 4: Create Tasks via API
The WFM system uses the
StartTaskContact API to create tasks:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const { ConnectClient, StartTaskContactCommand } = require("@aws-sdk/client-connect");
const client = new ConnectClient({ region: "us-east-1" });
const response = await client.send(new StartTaskContactCommand({
InstanceId: "your-instance-id",
ContactFlowId: "your-task-flow-id",
Name: "EWD: Complete compliance training module",
Description: "Agent has 15 minutes of idle time - assigning training task",
Attributes: {
TaskType: "EWD",
SourceSystem: "ExampleSouceSystem",
Priority: "Normal",
ExternalTaskId: "INT-2026-0608-001"
}
}));
const taskContactId = response.ContactId;Key considerations:
- Store the
ContactIdreturned, you'll need it to correlate Kinesis events back to the WFM task - Use
Attributesto pass metadata your Lambda consumer can use for routing/enrichment - Consider async invocation for high-volume scenarios to avoid Lambda idle wait time
Configuring Agent Event Streams for Task Tracking
Enable Data Streaming
- In the Connect console, go to Data streaming
- Under Agent Events, select your Kinesis Data Stream
- Save - events will begin flowing immediately
Understanding the Event Schema for Tasks
When a task is routed to an agent, the Agent Event Stream publishes
STATE_CHANGE events. Here's what a task assignment event looks like:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
"AWSAccountId": "123456789012",
"AgentARN": "arn:aws:connect:us-east-1:123456789012:instance/.../agent/agent-id",
"CurrentAgentSnapshot": {
"AgentStatus": {
"Name": "Available",
"Type": "ROUTABLE",
"StartTimestamp": "2026-06-08T14:30:00.000Z"
},
"Contacts": [
{
"ContactId": "abc12345-def6-7890-ghij-klmnopqrstuv",
"Channel": "TASK",
"InitiationMethod": "API",
"State": "CONNECTED",
"StateStartTimestamp": "2026-06-08T14:32:15.000Z",
"ConnectedToAgentTimestamp": "2026-06-08T14:32:15.000Z",
"Queue": {
"Name": "EWD-Tasks",
"ARN": "arn:aws:connect:us-east-1:123456789012:instance/.../queue/queue-id"
}
}
],
"Configuration": {
"Username": "jsmith",
"RoutingProfile": {
"Name": "Sales-MultiChannel",
"Concurrency": [
{"Channel": "VOICE", "AvailableSlots": 1, "MaximumSlots": 1},
{"Channel": "TASK", "AvailableSlots": 0, "MaximumSlots": 1}
]
}
}
},
"EventTimestamp": "2026-06-08T14:32:15.123Z",
"EventType": "STATE_CHANGE"
}Task Lifecycle States
The
Contact.State field tracks the full task lifecycle:| State | Meaning | WFM Mapping |
|---|---|---|
CONNECTING | Task is being offered to agent | Task Pending |
CONNECTED | Agent accepted/is working the task | Agent Busy (Task) |
PAUSED | Agent paused the task (unique to tasks) | Agent Available (partial) |
ENDED | Task completed or transferred | Agent Available |
MISSED | Agent didn't accept in time | Task Reassign |
REJECTED | Agent rejected the task | Task Reassign |
The
PAUSED state is particularly important for EWD; it means the agent temporarily set the task aside (perhaps to take a phone call) and will resume later. Your WFM system should treat paused tasks differently from completed ones.Building the Consumer
Lambda Function: Filter, Transform, Forward
The Lambda consumer processes Kinesis records, filters for task-relevant events and forwards them to the WFM system:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const WFM_WEBHOOK_URL = process.env.WFM_WEBHOOK_URL;
exports.handler = async (event) => {
for (const record of event.Records) {
const payload = JSON.parse(Buffer.from(record.kinesis.data, "base64").toString());
// Only process STATE_CHANGE events
if (payload.EventType !== "STATE_CHANGE") continue;
const snapshot = payload.CurrentAgentSnapshot || {};
const contacts = snapshot.Contacts || [];
// Filter for TASK channel contacts
const taskContacts = contacts.filter((c) => c.Channel === "TASK");
if (taskContacts.length === 0) continue;
// Build and forward WFM event payload
for (const task of taskContacts) {
const wfmEvent = {
eventType: "TASK_STATE_CHANGE",
timestamp: payload.EventTimestamp,
agentId: snapshot.Configuration.Username,
contactId: task.ContactId,
taskState: task.State,
queueName: task.Queue?.Name,
connectedAt: task.ConnectedToAgentTimestamp,
stateChangedAt: task.StateStartTimestamp,
};
const res = await fetch(WFM_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(wfmEvent),
});
if (!res.ok) {
console.error(`WFM webhook failed: ${res.status}`);
throw new Error(`Failed to deliver event: ${res.status}`);
}
}
}
return { statusCode: 200 };
};
Detecting Task Completion via Snapshot Comparison
A common pattern: compare
CurrentAgentSnapshot.Contacts with PreviousAgentSnapshot.Contacts to detect when a task disappears (completed):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function detectTaskCompletions(payload) {
const getTaskIds = (snapshot) =>
new Set(
(snapshot?.Contacts || [])
.filter((c) => c.Channel === "TASK")
.map((c) => c.ContactId)
);
const currentTasks = getTaskIds(payload.CurrentAgentSnapshot);
const previousTasks = getTaskIds(payload.PreviousAgentSnapshot);
// Tasks that disappeared = completed
const completed = [...previousTasks].filter((id) => !currentTasks.has(id));
return completed;
}
Operational Considerations
Task Concurrency
Setting task concurrency requires balancing agent utilization against customer experience:
- 1 task + 1 voice: Agent works tasks between calls. When a call comes in, the task is auto-paused (if agent has auto-accept). Recommended for most EWD use cases.
- Multiple tasks + 1 voice: Agent can juggle multiple tasks. Use when tasks are short (< 5 min) and interruptible.
- Tasks only: For dedicated back-office agents. No voice channel needed.
Monitoring
Key CloudWatch metrics to monitor:
TasksCreated- Volume of tasks created via APITasksCompleted- Throughput of completed tasksQueueSizefor task queue - Detects backlog buildupOldestContactAgefor task queue - SLA tracking
Kinesis Scaling
For a 500-agent contact center with active EWD:
- Expect ~2-5 events per agent per minute during busy periods
- One Kinesis shard handles ~1,000 records/second
- For larger deployments (1000+ agents), consider 2-3 shards
Error Handling
- Dead Letter Queue: Configure a DLQ on your Lambda for failed processing
- Idempotency: Agent Event Streams may publish duplicate events (heartbeats). Use
EventIdfor deduplication. - Ordering: Events within a shard are ordered. Use the agent ARN as partition key to ensure per-agent ordering.
By integrating Amazon Connect Tasks with Kinesis Agent Event Streams, you give your WFM system real-time visibility into the complete agent work picture; not just voice and chat but every task assignment, pause and completion. This enables true Extended Work Distribution where idle time is automatically filled with productive work and your WFM system maintains accurate schedule adherence metrics across all channels.
The pattern is straightforward: create tasks via
StartTaskContact, consume state changes via a Lambda-backed Kinesis consumer and map task states to your WFM system's agent activity model. The PAUSED state, unique to tasks, is your key differentiator for handling interruptions gracefully.Next Steps
- Review the Agent Event Stream data model for the complete schema reference
- Explore Amazon Connect Tasks documentation for advanced task features (templates, scheduling, linked tasks)
- Consider adding Contact Lens for analytics on task handling patterns
📢 Published by the ES-TAM-Builder community.
Follow our ES-TAM-Builder Space for more tools, guides, and technical deep-dives from fellow TAMs
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article