Mpathic logo
Menu
Back to Blog

Why your CRM undercounts the calls that matter most

Joe Sullivan, VP of Product DevelopmentJoe Sullivan, VP of Product Development
Title Card

The weekly contact report goes to your executive team with a call count on it. That number comes out of your CRM, and if your call center CRM integration is written inside the contact flow, the number is wrong in one specific direction: it is missing the calls that ended badly. A caller who hung up in queue. A callback request that never went out. A routing branch that disconnected a contact before it reached a logging step. None of those produce a CRM record, so none of them reach the report. This post covers where those records go missing and how to build a logging path that cannot drop them.

Call center CRM integration gap between calls handled and calls logged

Where call center CRM integration loses the calls that matter

Most contact center logging is built the obvious way: a step inside the contact flow writes an interaction record to the CRM, placed after the caller has been identified and routed. It works for the calls that behave, because the caller reaches the queue, connects to an agent, and the flow runs the logging step on the way through.

The calls that do not behave never get there. A caller waits, gives up, and hangs up while still in queue. Amazon Connect records that as an abandoned contact: a contact record carrying a Queue and an EnqueueTimestamp but no ConnectedToAgentTimestamp. The platform knows exactly what happened. The CRM does not, because the caller never reached the branch that writes the record. A queued callback that is created and never completed has the same shape, as does a contact that hits an error path and disconnects.

Flow-based logging captures the calls that went well and quietly discards the calls that went wrong. That is the worst possible bias to build into a reporting chain. Your abandonment rate, your callback backlog, and your routing defects are precisely the contacts an executive report built on CRM records cannot see.

Log from the contact record stream, not the contact flow

Diagram comparing contact flow logging with contact record stream logging

Stop treating the contact flow as the logging mechanism. Amazon Connect produces a contact record for every contact and delivers it through an Amazon Kinesis data stream. The record carries what an operator needs: channel, initiation method (inbound, outbound, transfer, callback, queue transfer, disconnect), initiation and enqueue timestamps, queue, disconnect reason, agent, hold and after-contact-work durations, and the recording and transcript locations. Records are retained for 24 months from initiation.

A consumer attached to that stream writes one CRM interaction per contact. Nothing depends on a caller reaching a particular branch, because the platform emits the record after the contact ends, however it ended. Abandoned calls arrive with their wait time. Callbacks arrive labeled as callbacks. Errored contacts arrive with a disconnect reason. Our internal name for the result is a guaranteed call ledger: one row per voice contact, with disposition, queue, wait time, and transcript attached.

We built this during roughly six weeks of engineering in July and August 2026, on a live Amazon Connect environment supporting a state education benefits program, inside the longer contact center engagement described in our case study on building and running a state agency's contact center.

The plumbing that makes stream logging trustworthy

Write path showing idempotent writes, dead letter queue, and stub contact records

Moving the write out of the flow solves the coverage problem and creates three new ones. A stream consumer can be handed the same record twice, can fail mid-write, or can meet a caller it cannot match. Each needs an answer before you trust the ledger.

Idempotent writes keyed on the contact identifier

Kinesis delivery is at-least-once, so a consumer can receive duplicate copies of the same contact record, and the documented approach is to deduplicate on ContactId using LastUpdateTimestamp to identify the newer copy. Key the CRM write on that contact identifier and make the write idempotent, so a redelivery updates the existing interaction instead of creating a second one. The general pattern is documented: a unique caller-provided request token makes an operation safe to retry, the token and the mutation must be recorded atomically, and a retry presenting the same token with different parameters should be rejected rather than applied. Without it, every retry inflates your volume, which is the same reporting failure in the opposite direction.

A dead letter queue for writes that fail

A CRM will refuse a write sometimes. Rate limits, validation errors, a field that changed. If the failure path is a log line, the contact is gone. Send failed messages to a dead letter queue instead, which holds what a consumer could not process so it can be examined rather than lost, configured with a redrive policy and a maxReceiveCount, with retention set longer than the source queue and a redrive path to move messages back out once the cause is fixed. Watch the depth of that queue: a non-zero depth is a count of calls your report is currently missing.

Stub contact records for callers you cannot match

Some callers will not match an existing contact record. A number that is not on file, a blocked caller ID, a family member calling on someone else's behalf. If your integration requires a match before it writes, those calls fall out of the ledger, and first-time callers are a population you especially want to count. Create a stub contact from the available caller data and attach the interaction to it. The call is logged, and an analyst can merge the stub into a real record later.

Test your own call logging this week

This takes an hour. Pick a single day last week. In your platform's own reporting, count the contacts that abandoned in queue. Then count how many CRM interactions exist for that day with an abandoned disposition. Compare the two numbers.

If the second number is zero or close to it, your logging runs inside the contact flow and your reported volume excludes your abandoned calls. Run the same comparison for callbacks and for contacts with an error disconnect reason. Those gaps are usually the whole difference between what your platform knows and what your leadership sees.

Fix the count before you interpret it

Reporting arguments in a contact center are usually treated as disagreements about interpretation when they are really disagreements about coverage. Get call center CRM integration onto the platform's contact record stream, make the writes idempotent, preserve the failures in a dead letter queue, and stub the callers you cannot match. Then every voice contact has a row, and the abandonment and callback numbers in front of your leadership are the same ones your platform reports. This is work we do inside CCaaS implementation and platform migration engagements, because a migration is the moment logging usually breaks and nobody notices for a quarter. If you want help auditing or rebuilding your own logging path, talk to our team.

Frequently asked questions

What is call center CRM integration?+

Call center CRM integration connects your contact center platform to your CRM so that customer interactions, call details, and outcomes appear on the customer record. The important design question is where the write originates. Logging from inside the contact flow captures only calls that reach that step, while logging from the platform's contact record stream captures every contact.

How does a CRM record an abandoned call?+

Only if something writes it. In Amazon Connect, an abandoned contact is one the customer disconnected while in queue, and its record carries a Queue and an EnqueueTimestamp but no ConnectedToAgentTimestamp. A consumer reading the contact record stream sees that contact and can log it. A logging step placed inside the contact flow never runs, because the caller never reached it.

Why do call volumes differ between my contact center platform and my CRM?+

Usually because the two count different things. The platform counts every contact it handled. The CRM counts only the contacts that reached whatever step writes to it, which excludes abandoned calls, incomplete callbacks, and contacts that disconnected on an error path. Duplicate writes from retries can also push the CRM number the other way.

How do you prevent duplicate call records in a CRM?+

Make the write idempotent and key it on the contact identifier, so a redelivered record updates the existing interaction instead of adding a second one. Amazon Connect delivers contact records with at-least-once semantics, and the documented approach is to deduplicate on ContactId using LastUpdateTimestamp to identify the newer copy.

What data should a call log include?+

Enough to answer a question without opening the platform. Disposition, queue, initiation method, wait time, handle time, agent, disconnect reason, and a link to the recording or transcript. Amazon Connect contact records carry these fields, including recording and transcript locations, and retain them for 24 months from initiation.