Queued does not mean sent
The single most important thing to understand about campaigns is what the Fire button does, because the word on the status badge afterwards is misleading if you read it the way an email tool would mean it.
Firing a campaign resolves an audience, then writes one delivery row per recipient into a delivery table, then updates the campaign counters. That is the whole operation. No message is transmitted. The campaign moves to queued, which means the rows exist and are waiting, not that anything has left the building.
What turns a queued row into an actual email, SMS or push message is a webhook receiver that you build and host. Each delivery is expressed as a campaign.delivery event carrying the campaign id, the visitor id, the subject, the body, the visitor email and the segment id. Your receiver takes that and calls whichever provider you already use. The dashboard says this in as many words on the campaigns screen, and the body field even notes that Markdown is supported in your webhook receiver, because the rendering decision is yours too.
This is a deliberate design rather than a gap. It means campaigns inherit whatever sending reputation, templating, unsubscribe handling and compliance posture your existing provider already has, instead of asking you to trust a second sender. But it does mean a campaign fired without a receiver subscribed produces delivery rows and complete silence, and everything on screen will look like it worked.
How the audience is resolved
A campaign either points at a saved visitor segment or points at nothing.
With a segment, firing evaluates that segment's filter fresh at fire time. This is worth saying explicitly: the audience is computed when you fire, not when you authored the campaign, so a segment that has grown or shrunk in between gives you a different audience than the estimate you saw last week.
With no segment, the campaign targets every addressable visitor, and addressable has a precise meaning here: a visitor record with a non-empty email address. Visitors who have chatted but never given an email are not in the audience, which is usually what you want and occasionally a surprise when the count comes back far lower than your visitor total.
If the segment a campaign points at has been deleted, the fire is refused outright with a message saying so, rather than silently falling back to everybody. That is the right failure: a deleted segment turning into a send-to-all would be the worst possible default.
The five thousand ceiling
Both audience paths are capped at 5,000 recipients per fire.
For the no-segment path the cap is applied by taking the 5,000 most recently seen addressable visitors, so if you have more than that, the campaign reaches your most recent contacts and silently omits the rest. The segment path is bounded the same way when it evaluates matches.
There is no warning on screen that a larger audience was trimmed. If your contact list is anywhere near five thousand, check the queued count against what you expected rather than assuming the whole list was covered. For genuinely large sends, segmenting into several campaigns is not just tidier, it is the only way to be sure you covered everyone.
What a second fire does
Campaigns can be fired more than once, and the behaviour on the second fire is one of the more useful things in the system.
Delivery rows are unique per campaign and visitor. When you fire again, every visitor who already has a row for this campaign is skipped, and only newly matching visitors get one. So re-firing a segment-backed campaign is effectively a top-up: it reaches the people who have joined the segment since last time and nobody else.
If nothing new matches, the fire completes and tells you plainly that there were no new recipients because every matching visitor was already queued. That message is a normal outcome rather than an error.
Two statuses are terminal. A campaign marked completed or cancelled refuses to fire at all, with a message naming the status. If you want to reach the same audience again from scratch, that is a new campaign, not a re-fire of an old one.
One honest caveat on the counters: the fire reports how many rows it queued and how many it skipped, and the skipped figure covers both already-queued visitors and any row that failed to insert. It is a count of things not newly queued, not strictly a count of duplicates.
Scheduling runs on UTC
A campaign fires either manually or at a scheduled time, and scheduled times are held and interpreted as UTC.
This is the trap most likely to catch a team outside that zone. A time entered without an explicit offset is read as UTC, not as your local clock, so a campaign scheduled for what you think of as nine in the morning may go out in the middle of your night. The dashboard is upfront about it, describing scheduled sends as firing at a future UTC time, but it is easy to skim past. Convert deliberately, and for anything time-sensitive, fire the first one manually and watch it.
A scheduled campaign also requires a time that actually parses. Saving a scheduled campaign without a usable time is rejected rather than quietly converted to manual.
How scheduled campaigns get picked up
A background worker sweeps for due campaigns on a one-minute cadence. It starts with the application and waits a full interval before its first sweep, so it deliberately does not hit the database the instant a recycled application takes its first request.
Each sweep takes at most fifty due campaigns. A backlog therefore drains across several sweeps rather than being processed in one burst, which keeps a long outage from turning into a thundering send the moment things recover.
The worker is also safe across restarts in the way that matters. Campaigns whose scheduled moment passed while the application was recycling are still due afterwards and fire on the next sweep, so they are delayed rather than dropped. And because firing moves the status forward, a campaign that has fired is not picked up again by later sweeps.
The practical read: a scheduled campaign fires within about a minute of its time under normal conditions, and within a minute or two of the application coming back if it was down. Do not schedule as if it were second-accurate.
Deleting a campaign
Deleting a campaign removes its delivery rows along with it, in one operation. That keeps the data tidy, and it also means the record of who was queued goes away.
If those rows are your evidence of who you contacted and when, export or otherwise capture what you need before deleting, because there is no undo. It is also worth noting that deleting a campaign removes the dedup memory with it: recreating the same campaign afterwards and firing it will queue everyone again, including the people the original had already reached.
How MyLiveChat fits
Campaigns live in the automation area of the dashboard and are built on the same visitor data as the rest of the platform, which is the real reason to use them: the audience is people who have actually been on your site and talked to you, described by the same segment rules you already use elsewhere. Building visitor segments for live chat is the prerequisite, because a campaign is only as good as the segment behind it, and the segment is evaluated at fire time.
Because delivery happens through your own integrations, treat the webhook receiver as part of the campaign rather than as infrastructure that already exists. Subscribe a receiver to the campaign delivery event before the first real send, and test it with a small segment you control. What the chat-end webhook actually sends is a good model for how these payloads are shaped, and when your webhook does not arrive covers the failure modes you will want to recognise quickly.
Finally, keep the addressable-visitor rule in mind when you look at the numbers. A campaign audience is bounded by how many of your visitors have given you an email address at all, so contact quality upstream sets the ceiling on everything downstream. Keeping your contact list clean and deduplicated is the unglamorous work that makes a campaign worth firing.