With SDK version 1.0.11, AgentClient.onStateChanged() fired for all agent state transitions, including undocumented internal CCP states such as CallingCustomer, Busy, FailedConnectCustomer, FailedConnectAgent, etc. These states were the only reliable mechanism to detect when an outbound voice call entered the dialing phase.
In version 1.0.12, onStateChanged is marked as deprecated in favour of onAvailabilityStateChanged. However, onAvailabilityStateChanged fires exclusively for configured availability state changes (e.g. Available → Offline, custom states). It does not fire for internal CCP states. As a result, after migrating to the new API, it is impossible to detect outbound call dialing, customer no-answer, or agent-side hang-up during the dialing phase.
Neither ContactClient nor VoiceClient exposes lifecycle events for outbound voice contacts comparable to what ContactClient already provides for inbound contacts (onIncoming, onConnected, onStartingAcw, onMissed, onCleared). This gap makes outbound call tracking only achievable through the now-deprecated onStateChanged, which is being removed with no equivalent replacement.
Environment
- SDK packages:
@amazon-connect/contact, @amazon-connect/voice
- Affected version: 1.0.12 (regression from 1.0.11)
- Integration type: Amazon Connect Agent Workspace third-party app (iframe)
Behaviour in v1.0.11 (working)
Subscribing to onStateChanged yielded the following event sequence for an outbound call that was initiated by the agent and then hung up before the customer answered:
onStateChanged → { state: "CallingCustomer", previous: { state: "Available" } }
onStateChanged → { state: "FailedConnectAgent", previous: { state: "CallingCustomer" } }
onStateChanged → { state: "Offline", previous: { state: "FailedConnectAgent" } }
And for a successful outbound call:
onStateChanged → { state: "CallingCustomer", previous: { state: "Available" } }
onStateChanged → { state: "Busy", previous: { state: "CallingCustomer" } }
// ContactClient.onConnected fires here
onStateChanged → { state: "Available", previous: { state: "Busy" } }
This allowed me to implement a reliable outbound call lifecycle tracker:
// v1.0.11 — worked correctly
agentClient.onStateChanged((event) => {
const { state, previous } = event;
if (isDialingState(state) && previous?.state !== state) {
showOutboundDialingBanner();
} else if (isFailureState(state)) {
showMissedCallBanner(state); // kept until dismissed by the user
} else if (state === "Busy" && isDialing()) {
// customer answered — hand off to ContactClient.onConnected
hideOutboundDialingBanner();
}
});
Behaviour in v1.0.12 (broken)
After migrating to onAvailabilityStateChanged as recommended:
// v1.0.12 — fires only for availability state changes
agentClient.onAvailabilityStateChanged((event) => {
// Never receives "CallingCustomer", "Busy", "FailedConnectAgent", etc.
// Outbound dialing is completely invisible.
console.log(event.state.name); // only: "Available", "Offline", custom states
});
The internal CCP states are no longer surfaced through any public API. The outbound dialing banner never appears, and the missed-call banner flashes momentarily then disappears (because the contact lifecycle resolves before the app can react).
Root causes
onStateChanged exposed two distinct categories of state in a single stream:
- Availability states — agent-configurable states (Available, Offline, custom). Now correctly surfaced by
onAvailabilityStateChanged.
- Internal CCP states — transient states driven by telephony events (
CallingCustomer, Busy, FailedConnectCustomer, etc.). No longer surfaced by any API in v1.0.12.
Deprecating onStateChanged without providing a replacement for category (2) creates a capability regression.
What we expected
Either:
Option A — dedicated outbound voice contact events on ContactClient or VoiceClient (preferred)
// analogous to existing inbound contact events
voiceClient.onOutboundDialing((event) => {
// { contactId, type: "voice", subtype: "connect:Telephony" }
});
voiceClient.onOutboundDialingFailed((event) => {
// { contactId, reason: "no-answer" | "agent-hang-up" | ... }
});
This would align with the existing event model (onIncoming, onConnected, onMissed, etc.) and make outbound tracking a first-class citizen.
Option B — preserve internal CCP states in onAvailabilityStateChanged (acceptable)
Document and guarantee that onAvailabilityStateChanged fires for internal CCP states (CallingCustomer, Busy, etc.) in addition to availability states, so migrating from onStateChanged is a true drop-in replacement.
Option C — new dedicated onCcpStateChanged event on AgentClient (acceptable)
Expose a non-deprecated API that preserves the full state stream from onStateChanged, clearly documenting the internal CCP states and their lifecycle.
Why this matters
Outbound call UX is a core use case for contact centre agents. Without visibility into the dialing phase, third-party apps embedded in the Agent Workspace cannot:
- Show a dialing spinner/banner while the customer's phone is ringing
- Detect that a call was not answered vs. answered
- Distinguish agent-initiated hang-up from customer no-answer
- Implement missed-call notifications that persist until the agent acknowledges them
- Other custom logic to be performed during outbound call dialing
All of these were achievable in v1.0.11 via onStateChanged. The v1.0.12 deprecation removes this capability with no migration path.
Steps to reproduce
- Install
@amazon-connect/contact@1.0.12
- Subscribe to
onAvailabilityStateChanged on AgentClient
- Initiate an outbound voice call from the Agent Workspace CCP
- Observe that no event fires while the customer's phone is ringing (
CallingCustomer state)
- Hang up before the customer answers and observe that no failure event fires
Expected: events corresponding to the dialing and failure states
Actual: no events fired; onAvailabilityStateChanged remains silent throughout.
With SDK version 1.0.11,
AgentClient.onStateChanged()fired for all agent state transitions, including undocumented internal CCP states such asCallingCustomer,Busy,FailedConnectCustomer,FailedConnectAgent, etc. These states were the only reliable mechanism to detect when an outbound voice call entered the dialing phase.In version 1.0.12,
onStateChangedis marked as deprecated in favour ofonAvailabilityStateChanged. However,onAvailabilityStateChangedfires exclusively for configured availability state changes (e.g.Available→Offline, custom states). It does not fire for internal CCP states. As a result, after migrating to the new API, it is impossible to detect outbound call dialing, customer no-answer, or agent-side hang-up during the dialing phase.Neither
ContactClientnorVoiceClientexposes lifecycle events for outbound voice contacts comparable to whatContactClientalready provides for inbound contacts (onIncoming,onConnected,onStartingAcw,onMissed,onCleared). This gap makes outbound call tracking only achievable through the now-deprecatedonStateChanged, which is being removed with no equivalent replacement.Environment
@amazon-connect/contact,@amazon-connect/voiceBehaviour in v1.0.11 (working)
Subscribing to
onStateChangedyielded the following event sequence for an outbound call that was initiated by the agent and then hung up before the customer answered:And for a successful outbound call:
This allowed me to implement a reliable outbound call lifecycle tracker:
Behaviour in v1.0.12 (broken)
After migrating to onAvailabilityStateChanged as recommended:
The internal CCP states are no longer surfaced through any public API. The outbound dialing banner never appears, and the missed-call banner flashes momentarily then disappears (because the contact lifecycle resolves before the app can react).
Root causes
onStateChangedexposed two distinct categories of state in a single stream:onAvailabilityStateChanged.CallingCustomer,Busy,FailedConnectCustomer, etc.). No longer surfaced by any API in v1.0.12.Deprecating
onStateChangedwithout providing a replacement for category (2) creates a capability regression.What we expected
Either:
Option A — dedicated outbound voice contact events on
ContactClientorVoiceClient(preferred)This would align with the existing event model (
onIncoming,onConnected,onMissed, etc.) and make outbound tracking a first-class citizen.Option B — preserve internal CCP states in
onAvailabilityStateChanged(acceptable)Document and guarantee that
onAvailabilityStateChangedfires for internal CCP states (CallingCustomer,Busy, etc.) in addition to availability states, so migrating fromonStateChangedis a true drop-in replacement.Option C — new dedicated
onCcpStateChangedevent onAgentClient(acceptable)Expose a non-deprecated API that preserves the full state stream from
onStateChanged, clearly documenting the internal CCP states and their lifecycle.Why this matters
Outbound call UX is a core use case for contact centre agents. Without visibility into the dialing phase, third-party apps embedded in the Agent Workspace cannot:
All of these were achievable in v1.0.11 via
onStateChanged. The v1.0.12 deprecation removes this capability with no migration path.Steps to reproduce
@amazon-connect/contact@1.0.12onAvailabilityStateChangedonAgentClientCallingCustomerstate)Expected: events corresponding to the dialing and failure states
Actual: no events fired;
onAvailabilityStateChangedremains silent throughout.