The handoff button isn't the hard part. A customer types "I want to speak to a human." The chat sets a flag, your team gets a row in their dashboard, and the customer waits. That part takes thirty lines of code.
Then the next two minutes happen.
Did anyone notice the row? Is the team online? What does the customer see while they wait? When the staff member picks up, do they understand what was happening five seconds ago? Five hours from now, when nobody replied, what does the customer see?
The button is easy. The two minutes around it are the product.
I rebuilt Emporiqa's handoff three times before the operational layer felt right. Here are the five questions I had to answer, and what I shipped for each.
Who gets notified, and how?
The first version was just an in-app dashboard notification. A customer asks for help, a row appears, end of story.
It works fine if your team lives in the dashboard. Most don't. They check it twice a day, then go back to running the store.
Now every team member with the email opt-in gets an email when a customer needs help. The first email goes out immediately. If five more handoffs hit the same store in the next five minutes, no more emails fire, just dashboard notifications. Once the five-minute window is quiet, the next handoff resumes emailing.
Urgent handoffs (refund, complaint, explicit escalation) bypass the cooldown. A complaint at 3 AM gets the email at 3 AM.
Each email has a one-click unsubscribe (RFC 8058, the modern Gmail and Yahoo standard) and a per-store opt-out toggle in the user profile. Staff who want emails for store A but not store B can do that.
What does the staff member see when they pick up?
Not just the question. The whole picture.
When you click "Take over" on a handoff, the chat detail page shows a "What happened so far" card with a summary of the customer's journey: what they were searching for, what the assistant tried, where it gave up. The full message history is below. The reason the handoff fired sits at the top with an urgency badge.
The customer doesn't have to repeat themselves. The staff member doesn't have to scroll fifty messages.
What does the customer see while waiting?
Three things:
A status indicator that says "Waiting for support team..." with an estimated wait time pulled from the median of recent assigned handoffs in this store, capped at 30 minutes so a single outlier doesn't show "typically replies in 4 hours."
A "Support is typing..." bubble that fires when the staff member starts composing a reply. This was the bit customers told me mattered most. The wait feels different when you can see someone is working on it.
A cancel button. If they change their mind, they go back to the assistant.
What if no one is online?
This is where I shipped a bug.
The first version of business hours did the right thing on the staff side: no email, no dashboard ping. But on the customer side, the chat still showed "Waiting for support team..." for a few seconds before flipping the handoff to the off-hours away message. The two contradicted each other.
The fix bypasses the regular handoff create path during off-hours. The conversation never publishes a "pending" status to the widget. The customer just sees the away message you configured ("Our team is offline right now. Leave your question and we'll follow up in the morning.") and keeps chatting with the assistant.
The handoff is still recorded for analytics, with outcome="off_hours" so you can see, in your dashboard, which questions came in outside hours.
Business hours are configured per store in IANA timezone format (Europe/Sofia, America/New_York). Empty days mean closed. Empty whole table means always-on.
What happens after?
When the staff member ends the session, three things happen:
The customer sees a system message in their language: "Support session ended. The assistant is back to help." No silent disappearance.
The handoff record gets a resolution outcome (resolved, escalated, or follow_up) that you (or you in three months) can use to figure out which handoffs fixed the customer's issue versus which got bounced upward.
After two seconds, the customer sees a thumbs-up / thumbs-down rating prompt. Cancellations get the prompt too, with a different source tag, because customers who gave up after waiting too long are the most useful feedback signal you have.
What I haven't built yet
No SMS notifications. If your team has alert fatigue from email, the answer today is "go look at the dashboard." A push integration with Slack or webhooks is the next step.
No mobile push notifications.
Business hours is a single weekly schedule, not a vacation calendar. If your team takes the week off, you turn handoff off entirely or accept that customers see the away message.
No "transfer with a private note." When you transfer to a teammate, the new handler sees the conversation summary and message history, but not your private context. Send it as a regular message before transferring.
The point
The button is fifteen minutes of work. The operational layer is the product.
If you're evaluating chat tools, ignore the demo where someone types "I want a human" and a person waves at the camera. Ask what happens at minute three, at hour three, at 3 AM. The answer tells you whether the system earns the customer's trust or burns it.
Emporiqa includes the full handoff lifecycle on every plan: confidence-based escalation, email notifications with one-click unsubscribe, business hours, transfer between teammates, saved replies, and resolution outcomes. Create a free Emporiqa account and you get $25 of signup credit (about 100 conversations), no card required. Or try the live demo first. The demo is a stocked electronics store, and the chat behaves the same way on any catalog.