Your Messaging Inbox

Find, assign, and manage all customer conversations in one shared inbox.

Beginnerownermanageradminsales repUpdated 2026-09-24

Your Messaging Inbox

The Inbox is your shared communication hub. Customer SMS and email, internal notes, and supported automated follow-ups live in one conversation so your team can review the message history before responding. The web timeline also shows the supported estimate, invoice, payment, maintenance-agreement, customer request, scheduling, and job activity described below. The portal-view engagement card is the remaining system-event parity work.

Call activity is part of that same record. V2's authoritative inbound-call lifecycle records connected calls, missed calls, and voicemail events in the customer's thread, so the web Inbox can show what happened without inferring a call from message text. Completed call cards now provide V1's Call back action for teammates with Place phone calls. It rings the configured office forwarding phone first and then bridges the saved customer number through the shared company line. Free-form dialing, call scores, coaching, and AI summaries remain separate parity work.

Go to Inbox in the sidebar to open it.

Screenshot placeholder
Inbox page showing the conversation list on the left and an open thread on the right

Clean Estimate V2 native mobile Inbox

In the V2 native mobile app, owners, admins, office teammates, and sales reps open More > Inbox from the Road workspace. This current V2 destination uses the Road-role boundary described under Communications permissions, not the older web/V1 messaging default. Crew-only members do not receive the customer Inbox destination. The focused mobile Inbox uses the established customer-card workflow without copying the full web administration surface.

The list contains only conversations in the signed-in member's organization and assigned locations. Each compact card shows the linked customer when the thread is matched. An unmatched inbound thread shows its latest customer phone number or email address instead, so the conversation remains recognizable without claiming it belongs to a customer record. Cards also show the latest message preview, channel, time, location, unread state, and whether the latest customer message still needs a reply. The quick rail keeps All, Needs reply, and Unread with whole-scope counts. Open Filters to combine All / Needs reply / Replied, unread-only, multi-select Text / Email, Human reply / Automation as the last outbound kind, and Normal / High message priority. Filter groups combine with AND; Text and Email combine with OR. The Filters button shows how many individual constraints are active. An internal note can be the newest timeline preview without changing the thread's latest external customer channel, so a team-only note does not make a Text or Email conversation disappear from that channel filter. In this focused native slice, High means a conversation is both unread and waiting for a human reply over Text or Email. The web-only Calls and Missed calls release described below does not change this native control, label, or priority behavior.

The focused V2 default is Latest inbound; the current V1 default is Latest activity, which remains available in the Sort sheet. It also provides Our last message, Oldest unanswered, Latest activity, Latest human reply, Oldest human reply, and Longest waiting for reply. V2 sorts human replies from customer inbound messages and actual staff replies; automation does not masquerade as a human reply. Filter and sort state remains local to the current Inbox screen, matching the actual V1 behavior. The V1 Save as a view control did not persist views, so V2 does not claim a saved view contract that does not exist.

Search customer, sender identity, location, channel, and SMS or email message content across the complete authorized Inbox. Internal-note text is not included in V2 mobile search yet. External message-history text uses an indexed, partial-word search so an incremental query such as appoint can find appointment without rescanning every stored message body. Ordinary short customer replies such as no and not yet remain searchable too. Search accepts up to 100 characters. The list loads 50 conversations at a time with Load older conversations. Search and the focused filter run on the server before paging, while the waiting and unread counts cover the whole organization/location-scoped result instead of only the cards already loaded. If a refresh overtakes an older-page request, the app discards the stale page so a shifted boundary cannot hide a conversation. Load older conversations also refreshes and merges the newest page after the older request. A thread that received new activity and crossed above the captured page boundary is therefore restored immediately instead of remaining hidden behind a newer unread or waiting count. After the final older page loads, the action disappears instead of fetching those same conversations again.

Open a card to see the chronological thread. Customer messages align left, team replies align right, and amber Internal note cards are visibly marked team-only with their author. The customer icon opens the existing mobile client record when the conversation is matched to one.

On a conversation matched to a customer, the composer supports Text, Email, and Internal note. An unmatched inbound conversation exposes only Internal note until it is linked to a customer:

  • Text and email are online-only. They use the same live contact, consent,

company-sender, provider, and idempotency checks as the web Inbox.

  • A newly arrived message makes an older draft stale. Mobile refreshes the

thread and keeps the draft for review instead of silently changing its recipient.

  • A definite provider failure keeps its logical identity for a safe retry.

Email also reuses its provider-idempotent identity when a response is lost. An ambiguous SMS keeps its identity and draft but blocks the unchanged send, because the SMS provider cannot deduplicate a retry after its lease expires. That blocked state is where the attempt stays: the draft and its logical identity are held, and editing the text starts a different message rather than settling this one. Nothing here is waiting on a delivery confirmation — for a text, none is ever coming. The screen reports sent, recorded-only, queued, provider-failed, no-contact, no-consent, and no-sender outcomes separately.

  • If the thread changes while a prior delivery is still uncertain, V2 retains

that original send identity instead of minting a duplicate. Edit the draft only when you intend to create a new message.

  • In-flight, queued, and lost-response identities, destination boundaries, and

retained drafts are encrypted in account- and conversation-scoped device storage. Back navigation, reopening the thread, and restarting the app therefore restore the same logical attempt. If mobile cannot restore or save that safety state, the composer blocks Send and shows Retry instead of risking a second provider attempt. Generation checks also stop a late result from an older screen from deleting a newer screen's saved attempt.

  • If the provider definitively failed before the thread changed, V2 discards

that obsolete snapshot after refreshing. The unchanged draft can then retry from the newly displayed thread instead of repeating a stale-thread warning.

  • Inbound email and text rows receive their timeline time only after acquiring

the same conversation boundary used by staff replies. A webhook that waited behind a reply therefore remains newer in the thread, unread, needs-reply, and stale-draft checks instead of sorting behind the reply it followed.

  • Automated customer messages use that conversation boundary too. An

automation that waited behind a staff reply receives its timeline time only after the wait, so it cannot appear before the reply even if its database transaction began first.

  • Read state uses the full message time and message ID boundary. If two inbound

messages receive the same timeline time, opening the first cannot hide the later one: its card, Unread filter, and whole-Inbox count remain unread until that exact later message is displayed and marked read.

  • Internal notes use no SMS or email provider and remain available on unmatched

conversations. They are never sent to the customer.

  • Offline conversations already loaded on the device remain visible, but V2

does not queue customer messages or internal notes for later delivery.

This V2 release restores the message-backed part of the V1 filter and sort workflow. The remaining exact V1 catalog is still required parity, not removed functionality:

  • Assignment: All team, Assigned to me, and Unassigned require a durable

conversation-owner model before mobile can filter them safely.

  • Calls: V2 now has an authoritative, scoped inbound call and voicemail

lifecycle, and the web Inbox uses it for the Calls and Missed calls controls, call cards, and permission-gated callback-first action described below. Bringing those controls, call cards, web quick counts, scores, coaching, or AI summaries into the approved native mobile UI still requires a separately reviewed mobile change. This web release makes no native layout, navigation, control, label, styling, information-hierarchy, interaction, route-contract, or PowerSync change.

  • Engagement: The web Inbox now provides Estimate viewed, **Invoice

viewed, Viewed multiple times, and Viewed in 24 hours**, plus the combined and document-type-specific latest-view sorts and supported timeline cards and global quick counts. Bringing these controls, cards, or counts into the approved native mobile UI still requires separate review.

  • AI assistance: the web Inbox now restores V1's editable AI Draft

suggestions for SMS and email as described under Compose Area. Call summaries, scores, and coaching remain separate parity work. Bringing any AI control into the approved native mobile UI still requires separate review.

  • Remaining system-event types and separately authorized campaigns remain

follow-up work. Photos and PDFs now move in both directions on the web thread — texted and emailed pictures persist, an emailed PDF is verified and opens from a document chip, and teammates can attach either to a reply, though a PDF can only be emailed. Offline outbound delivery remains excluded until V2 has a safe delivery contract.

The web Inbox now restores V1's Needs reply, Estimate views, Invoice views, and Missed calls quick counts. Its full ten-sort catalog is the seven message-backed sorts above plus the three document-view sorts listed above. Its two empty states remain separate: a constrained zero result is No filter matches, while a truly empty Inbox is Inbox clear. V2 currently uses the equivalent No conversations match wording for the constrained state.


Web Inbox layout

The sections below describe the two-panel web Inbox. They do not describe the focused V2 native surface above; V1 mobile capabilities remain a separate parity baseline where explicitly labeled.

The inbox uses a two-panel split view. The left panel lists your conversations. The right panel shows the full thread for whichever conversation you select.

Completed call and voicemail cards with a validated customer number include Call back. The server derives the destination from the saved call and rechecks the teammate's permission and location before spending a provider request. The office forwarding phone rings first; answering it connects the customer through the shared company number. The call attempt and signed provider outcome remain in this same conversation. Voicemail-only voice setups need a forwarding destination before this action becomes available.

On smaller browser widths, the web Inbox shows one panel at a time. Open a conversation from the list, then use Back to conversations to return. This responsive web behavior does not change the approved native mobile Inbox.

Starting a new conversation

Select New Message in the web Inbox header to open Start a Conversation. This dialog chooses the customer context for the existing thread composer; it does not contain a message field and does not send anything.

  1. Use Search clients by name, phone, or email to find an active customer

or service site that you can access. Results stay inside your organization and location scope. Inactive records and portfolio rollups are not messaging targets; select the individual service site instead. The picker returns up to 25 customers at a time, so refine the search if the customer is not in the current results.

  1. Select the customer. If the customer is active at one accessible location,

Clean Estimate uses it automatically. If more than one location is available, choose Location before continuing. The Inbox does not guess a location because each conversation and sending identity belongs to one location.

  1. Choose SMS or Email under Channel. The To line shows the

exact saved phone number or email address that the server resolved for that channel. When a thread already exists, this preview follows that conversation's established reply destination instead of silently replacing it with a different primary contact. This destination is read-only. Correct an outdated destination on the customer record, then review it again before sending.

  1. Select Open conversation. Clean Estimate creates or reuses the one

location-bound customer thread, closes the dialog, opens that thread, and focuses its established composer with the reviewed channel active. The composer repeats the reviewed recipient in a read-only To line. Every email or SMS send remains bound to the exact contact and destination shown there, including safe retries of a delivery with an uncertain result. On a narrow browser, Back to conversations returns to the list.

An unavailable channel explains whether a usable destination or customer consent is missing. A customer with no usable phone or email cannot be opened for an external message. If search fails, use Retry. If the customer, location, recipient, or consent changes while the dialog is open, Clean Estimate clears the stale choice, refreshes the results, and asks you to select and review the current target again instead of silently switching it. That same refusal applies when an existing thread's established reply destination no longer matches the destination that was previewed. If it changes after the composer opens but before a send, the message is not delivered, the draft remains available, and the current recipient is refreshed for review.

Opening or retrying New Message does not clear a draft already saved in a conversation. Reopening an existing thread restores its draft, and a failed or uncertain send keeps the established per-thread draft and delivery identity for safe review or retry. Completing Open conversation means only that the composer is ready; it never claims that SMS or email was sent.

When you select Send, Clean Estimate checks the exact thread activity, recipient, active contact, consent, customer and location access, teammate role, and service-site status again while the delivery provider accepts the message. If any of those details changed after the composer opened, the message is not sent. A new customer reply or call update asks you to read the latest activity before replying. A contact or consent change asks you to review the current recipient. An access, service-site, or location change asks you to refresh the Inbox and continue only from an eligible location and teammate account. Web Inbox sending remains available to active owners, admins, and office teammates; the approved road-sales mobile Inbox continues to support eligible reps without changing its interface. Web delivery-refusal guidance is also announced to assistive technology when it appears.

This is a web-only V1 parity workflow. It does not change the approved native mobile Inbox layout, navigation, controls, labels, styling, information hierarchy, response contract, or PowerSync exposure. The mobile provider-boundary validation is backend-only.

Ownership and response workflow

The web Inbox restores the V1 ownership and triage controls on V2's scoped data model:

  • Search uses customer name, sender phone or email, location, property address,

customer messages, and internal notes. Search runs on the server before paging, so older matching conversations are not hidden by the first page.

  • All, Mine, and Unassigned are mutually exclusive ownership

filters. Unread is an independent toggle. Under Reply status, choose All, Needs reply, or Replied; the reply choice combines with ownership, Unread, and the other filters described below.

  • An amber Needs reply badge identifies a customer thread waiting on the

team. Assigned rows also show the teammate's name. Unassigned rows stay visually quiet instead of repeating an Unassigned badge on every row.

  • The conversation header provides an Owner selector followed by the

response action. The selector can assign active owners, admins, office teammates, and sales reps only where their location access permits it. Owners, admins, and office teammates operate these web controls; a sales rep remains a mobile-role assignment target rather than receiving the web admin surface. Choose Unassigned to release the conversation.

  • Waiting on us means the latest qualifying customer activity still needs a

human response. Waiting on customer means the latest successful human reply or connected-call outcome has answered it. Use Mark Responded or Mark Needs Response for the V1 manual workflow.

A manual response choice is anchored to the exact latest customer or staff event. Empty and automation-only conversations can also be marked Needs response; that choice is anchored to the conversation's current activity version. A newer inbound message, successful staff reply, changed phone-call outcome, or later activity on an event-free thread automatically supersedes the older manual choice, preventing a stale "responded" label from hiding new work. Two teammates editing the same owner or response state receive a conflict notice and the current state is reloaded for review.

When an owner or response update removes the current row from the active filter, the open conversation and its draft remain on screen. The list updates around it, allowing the teammate to finish reading or composing before moving on.

Personal saved views on web

The web Inbox restores V1's personal saved-view workflow on V2's scoped data model. Set the search, ownership, reply status, channels, customer engagement, last-outbound type, priority, sort order, unread-only, and missed-call choices you want, then select Save view. Enter a name such as Hot estimate views and select Save.

The view appears in Saved views above the quick counts. Selecting it restores the entire saved combination, including search and sort—not only the currently visible filter chips. The view follows the signed-in teammate across web browsers and devices. It is personal to that teammate: it does not become an organization-wide default and another teammate cannot read, overwrite, or delete it.

Clean Estimate shows Delete when the current choices exactly match a saved view. Delete removes only that named personal preset; it does not clear the active filters or remove any conversations. Names are case-insensitively unique for each teammate, and each teammate can keep up to 20 Inbox views. If a view cannot load, save, or delete, the current Inbox filters and conversation list remain usable.

This is a web-only parity release. It does not add, remove, rename, or restyle any approved native mobile control.

Quick counts

Four compact counts below Search conversations summarize the caller's complete authorized web Inbox:

  • Needs reply counts conversations in the same current Waiting on us

state used by the list and selected conversation.

  • Estimate views and Invoice views count conversations with at least one

authoritative view of that document type. They count conversations, not raw page opens, so repeated views of one document do not inflate the tile.

  • Missed calls counts conversations whose latest linked phone-call outcome

is missed or voicemail. A later connected call clears that conversation from the count.

These are whole-Inbox totals; search and the current list filters do not narrow them. Select a count to turn its matching filter on, or select the active count again to turn that filter off. The choice composes with any search, ownership, unread, channel, engagement, outbound, priority, and sort selections already in place.

Counts load independently once when the Inbox opens and refresh after relevant staff workflow changes, including creation through New Message, saved internal notes, send-snapshot conflict recovery, and every saved send outcome even when delivery is queued, fails, or is refused. They do not run a recurring full-Inbox database scan in each open browser tab. Reload the page to request fresh totals after external customer activity. If counts cannot load, the page says Quick counts are temporarily unavailable. The last successful values remain visible and the conversation list continues to work. Select Retry to request the totals again without reloading the Inbox; the button is disabled while that request is running. Retry is user-initiated and does not add background count polling.

For staff actions, count reconciliation starts as soon as the server confirms the state change. A later thread or list refresh error cannot suppress that count request.

Filter and sort conversations

The web Inbox restores this V1 filter and sort workflow from scoped message and phone-call records without changing the approved native mobile UI. Open Filters & sort to combine these groups:

  • Reply status: All, Needs reply, or Replied. Needs reply follows

the same current Waiting on us state shown in the conversation header; Replied selects conversations that are not waiting for a human response.

  • Channel: select Text, Calls, Email, or any combination. The

selected values use either-match behavior inside this group. Calls folds both call and voicemail activity into one list choice. Channel follows the conversation's latest external activity: a newer call or voicemail matches Calls, while a newer Text or Email moves the conversation to that newer external channel. Internal notes never change the external channel.

  • Missed calls: turn on Missed calls to select conversations whose

authoritative latest phone-call outcome is missed or voicemail. This is independent of the latest external channel, so a later Text, Email, or internal note does not rewrite the call outcome. A later connected call clears the missed-call state.

  • Customer engagement: select Estimate viewed, Invoice viewed, or

both to find conversations connected to an authoritative customer document view. Viewed multiple times requires one estimate's stored view count to be greater than one; it does not infer repeat interest from messages or from multiple different documents. Viewed in 24 hours requires the newest authorized estimate or invoice view to fall inside the trailing 24-hour window. Selected values use either-match behavior inside this group. The trailing window and document-view order are frozen at the first page's timestamp. A new customer view appears after refresh instead of entering or reordering an in-progress Load older sequence.

  • Last outbound: Human reply or Automation. A human reply is a

successful external message sent deliberately by a teammate. An automation stays automation activity and never counts as a human reply.

  • Priority: Normal or High. High always requires the authoritative

conversation state to still need a human response. Within that state, an unresolved missed call or voicemail is High, as is an unread customer Text or Email. Mark Responded or a successful teammate response removes High; an explicit responded state is never kept High merely because an older missed call remains in history. Priority is not an inferred lead score. Normal selects conversations outside that High set.

These groups combine with one another and with search, All / Mine / Unassigned, and Unread. In other words, each active group must match, except that multiple selected channel values match Text, Calls, or Email and multiple selected customer-engagement values match any selected engagement condition. For example, combining Calls with Missed calls requires both the latest external channel to be a call or voicemail and the latest phone-call outcome to be missed or voicemail. Clear the filter choices to return to the full ownership view.

Under Sort conversations, choose one of ten restored V1 orders. Qualifying inbound call and voicemail activity participates in the same directional and activity orders; there is no invented call-only sort:

  • Latest activity is the default and keeps the newest overall conversation

activity first.

  • Latest inbound orders by the newest customer activity.
  • Our last message orders by the newest successful external message from a

teammate or automation.

  • Oldest unanswered puts the oldest conversation still waiting for a human

response first.

  • Latest human reply and Oldest human reply order by the greatest

qualifying human event across customer inbound activity and a successful teammate reply. Automations and internal notes are excluded.

  • Longest waiting for reply puts the conversation that has waited longest

for a human reply first.

  • Latest estimate/invoice view puts conversations with the newest stored

customer document view first. Conversations with no recorded document view remain after those results instead of being hidden.

  • Latest estimate view orders by estimate activity only. Invoice views do

not move a conversation ahead in this order.

  • Latest invoice view orders by invoice activity only. Estimate views do

not move a conversation ahead in this order.

Search, every active filter, and the selected sort run on the server before paging. Load older therefore continues the exact selected view instead of filtering or reordering only the rows already loaded in the browser. Automatic refreshes reconcile the complete prefix you have loaded, even after more than 500 conversations are visible.

Opening a conversation marks only the message boundary you actually received as read, then refreshes the list from the server. If a newer customer message or call update arrived during that handoff, the conversation stays in the appropriate Unread, Needs reply, or High state instead of disappearing prematurely.

When the authorized Inbox has no conversations, the web page says Your inbox is empty and New customer conversations will appear here. When search or filters produce no result, it says No matching conversations and Try changing or clearing your filters., with Clear filters to restore the unconstrained view.

If the conversation list cannot load, the left panel shows Couldn’t load conversations with Try again. It does not mislabel a loading failure as an empty Inbox or hide the failure in the conversation panel. A successful refresh or Load older request clears the prior list error.

The web Calls control follows the thread's latest durable external channel; call and voicemail activity fold into Calls. Missed calls uses the scoped phone-call outcome linked to the latest durable call activity as its source of truth, not timeline copy. Call activity and its phone-call record must also belong to the same organization, location, and conversation. Recording playback is available from retained voicemail cards. The separate read-only web Phone workspace now provides the broader location-scoped call history. Connected-call transcripts, scores, and coaching remain parity work. The compose-area AI Draft described below is available for SMS and email, and personal web saved views are described above.

Left Panel: Conversation List

At the top of the list is Search conversations. Type a customer name, sender phone or email, location, property address, or words from a customer message or internal note to filter the Inbox.

Below the search bar you can narrow the Inbox with the ownership and workflow filters described above, including:

  • Mine to see conversations assigned to you
  • Unassigned to find threads no one owns yet
  • Unread to focus on new inbound activity
  • Needs reply under Reply status to see conversations that still

require follow-up

Use Filters & sort for reply, channel, customer engagement, last-outbound, priority, and the ten available ordering options. When that section is collapsed, its active-count badge still shows that the list is narrowed; expand it to review the selected controls or choose Clear filters.

Each row in the list shows:

  • Customer name in bold
  • Last message preview - a short snippet of the most recent activity
  • Unread dot and bold text when new inbound activity has not been read
  • Channel badge for SMS, email, calls, voicemail, or internal notes
  • An amber Needs reply badge when the customer is waiting on the team
  • A factual Missed call indicator when the latest phone-call outcome is

missed or voicemail

  • A factual Estimate viewed or Invoice viewed indicator, including the

stored view count when it is greater than one

  • The assigned teammate's name when the conversation has an owner

Conversations are grouped by contact, not by channel. If the same customer has both a phone number and an email address on file, their texts and emails appear in one shared row in the inbox instead of splitting into separate conversations.

With the default Latest activity order, conversations are sorted by most recent customer, staff, note, or supported call activity and the Inbox loads the newest conversations first. If you select another order, the list and each Load older page follow that selected order. In either case, choose Load older at the end of the list to continue through the same search, filter, and sort set without duplicates.

Click any row to load the conversation in the right panel.

Screenshot placeholder
Contact list showing customers with unread badges, message previews, and workflow filters

Right Panel: Conversation Thread

The top of the right panel shows the customer name, the current Owner, and whether the conversation is Waiting on us or Waiting on customer. You can update the owner and response state without leaving the conversation.

Screenshot placeholder
Conversation header showing customer name, Owner selector, Waiting on us status, and Mark Responded

Below the header is a timeline of the currently loaded communication in chronological order. Use the V1-style All, Texts, Emails, Calls, Voicemail, Notes, and System controls to focus the selected conversation. Each visible control includes its factual count; empty channel controls stay hidden. Choosing another conversation resets the timeline to All.

Every time in the web Inbox reads in the time zone of the conversation's own service location, not the time zone of whoever opened it. That covers the conversation list as well as the open thread: the "Viewed …" time on a list row is on that row's own location's clock, so a row and the thread it opens into always name the same day. Where the row is about an invoice, both use the time zone the invoice was issued in. A thread about a job in Denver reads in Denver time from a desk in Boston, and the day a proposal deadline falls on matches the day the customer sees on their own quote page. Proposal and invoice cards go one step further and use the time zone the document itself was sent with, which is the one the customer's own copy renders in, so changing a location's time zone later cannot move the dates on quotes and invoices already out.

When you set a due date on a post-call follow-up, the time you type is read on that same clock, and the field names it — Due (MST) — for the date you picked, so there is no guessing which zone you are entering. What you type is what the card says. Once a year, where daylight saving applies, the clocks skip an hour: that hour does not exist in that location, so the composer says so and asks for a time on either side of the change rather than saving a different one.

Saved calendar dates are left as written. A job scheduled for March 4 is March 4 everywhere, so job and appointment-request cards show the stored day rather than converting it. If a location's time zone is missing or unrecognized, the timeline falls back to UTC rather than failing to open.

The timeline shows these entries:

  • SMS messages display as chat bubbles. Inbound messages from the customer appear on the left. Outbound messages from you appear on the right, each with the delivery status pill described under Delivery status below.
  • Email messages show the subject and body, each with the same colored

delivery-status pill next to the time that SMS messages have: Delivered, Opened, Clicked, Bounced, Spam complaint, Suppressed, Failed, or Delivery delayed. Opened and clicked messages include the stored activity time; repeated opens and clicks include their count. An email open is a tracking image being fetched, which is not the same event as a person reading the message — and it is wrong in both directions: mail clients and privacy services load the image automatically when nobody has read anything, and clients that block images record nothing when someone genuinely has. Treat it as a weak signal in either direction. These email facts remain distinct from estimate and invoice page views.

  • Internal notes appear with a distinct style so your team can share context without sending anything to the customer.
  • Other outcomes read in plain words. A message that didn't simply send

now labels its own outcome instead of a raw status code: Not sent — sending is off, Refused — no consent, Refused — notification preference, Failed, No contact method on file, No sender number configured, Still sending, or Refused — recipient changed. The same wording is used in the delivery report below, so the thread and the report never describe the same outcome two different ways.

  • Calls and voicemail use factual call cards. A card shows the stored

connected, missed, or voicemail outcome; caller number; and duration when available. Voicemail shows its retained transcript and an audio player when the recording is still available. Playback stays inside Clean Estimate: the browser never receives the provider's private recording URL or credentials. Each playback request rechecks the signed-in office teammate, their location access, the exact conversation and call, and the recording-retention window. Normal browser range requests are supported. Returned partial audio must match the browser's exact request and byte count and cover the complete span selected from a known total recording length. A seek past the end receives a private, bodyless retry response only when that length proves the request cannot be satisfied. After the configured retention boundary, the card says Voicemail recording expired instead of presenting stale transcript or recording data.

  • Customer document activity uses factual timeline cards for proposal

send, withdrawal, expiry, view, acceptance, or decline and for invoice send, view, payment, or void. View cards show the stored count and first-view time when useful. Acceptance shows the selected option and amount when stored; decline shows the saved decline reason when present; payment and initial invoice send show the recorded invoice amount. Each card links to the authorized estimate or invoice workspace. The System control includes these cards and any durable system-channel entry. The cards are derived only from immutable event timestamps and records for the conversation's exact organization, location, and matched customer. Proposal cards name their version once there is more than one to tell apart: a customer sent a single quote sees no numbering, and from the second revision onward each send, withdrawal, expiry, decline and acceptance says which one it was — including the acceptance, so the record shows which version the customer actually signed. A sent proposal also shows the deadline it went out with, when one was set, and gets a Proposal expired card once the proposal is over without being accepted. That happens two ways, and the card is dated at whichever actually occurred: your office can end a proposal early, or the deadline you set can simply arrive — the quote page already refuses an acceptance past it. Ending one early is recorded at the moment you end it, so a proposal closed weeks before its deadline is not dated at that later date; ending one whose deadline has already passed keeps the deadline, since that is when it really stopped being acceptable. The card appears only where the proposal really reached that point: one withdrawn, declined or accepted first ended another way, and one replaced by a newer version before then was superseded rather than expired. Proposals your office marked expired before this release have no recorded moment, so they are dated at their deadline where they had one and show no card where they did not.

  • Job activity uses factual timeline cards for job creation, scheduling,

rescheduling, removal from the schedule, work start, completion, and cancellation. Scheduled cards show the saved date and arrival time. A reschedule or cancellation card includes its saved reason when available, and office changes identify the teammate who made them. Each card links to the authorized job workspace.

  • Maintenance-agreement activity uses the same durable card treatment for

each agreement's lifecycle: started, renewed (automatic sweep renewals say so), paused, resumed, extended, cancelled with the recorded reason, and auto-renew changes — each naming the acting teammate when a person made the change. The card carries the agreement name the customer saw at the time, even if the plan's option is later relabeled.

  • Payment activity shows each payment received — including partial

payments, proposal deposits, membership signup and installment charges, and manually recorded tenders with their saved method — and each refund, with its amount and a link to the invoice or estimate it settled. These cards derive from the durable payment record itself, so they never disagree with the money ledger; the existing Invoice paid milestone card stays.

  • Customer request activity shows the customer's own asks and the

office's answers. A portal service request appears with the requested service, preferred day, and the customer's notes, linking to the lead it created. A reschedule or cancellation request appears with the requested day and arrival-window preference and the customer's reason, linking to the job — and the office's decision is its own card, approved or declined, with the recorded decision reason and the deciding teammate. A still-pending request shows only the ask.

  • Lead pipeline activity shows where this customer's leads have moved.

Each card names the lead by its own number, says which stage it went to and which it came from, and carries the reason typed at the time, the teammate who moved it, and what the lead was worth at that moment. A lead created straight into a stage reads as added rather than moved, since it had not been anywhere yet. Two details worth knowing: stage names are read as they are today, so renaming a stage also renames it on cards for moves that already happened; and deleting a stage does not delete the history — those cards remain and describe the stage as removed.

  • Photos your team sends. A photo attached in the composer is stored the

same way an inbound one is — verified, stripped of hidden metadata, and kept with the message — and appears on the reply's own bubble in the thread, so the record shows exactly what was sent. The bubble itself is not a receipt — but the message entry beside it can be, and the two channels still differ in how much they tell you: an emailed photo picks up the same provider-confirmed delivery, bounce and complaint lifecycle as any other email, while a texted one carries the same Queued / Sent / Delivered / Failed pill as any other text — though carrier coverage varies, so some texted photos only ever confirm Sent. See Delivery status above and Did your messages land? below.

  • Consent changes. When a customer's permission to be contacted changes,

the thread says so. Until now you saw only the consequence — a channel the composer would not send on — and had to remember, or ask around, why. The card names the channel, which way it moved, the number or address it applies to, and what the record says caused it: the customer replied STOP, the customer used an unsubscribe link, consent was already on file when the contact was added, or a named teammate recorded it on a stated basis such as agreed on the phone or in writing. It reports the record and nothing else — no advice about whether the customer can be asked to opt back in. An email unsubscribe shows on a text thread too, because that is exactly where somebody is about to try emailing. A decision that moves only one kind of permission says which: a customer who is off marketing is still reachable about their own job.

  • Consent required blocks Send before you try, not after. Every new

contact starts with texting and email consent on file (see Contacts and consent), so this mainly comes up after an explicit revoke. When the selected channel has a known contact method but no current consent, the composer marks it Consent required next to the channel name and, for a thread linked to a client, adds a Record consent link straight to that client's Contacts panel. The Send button is disabled for that channel until consent is recorded, instead of letting you compose and send a reply the server will refuse.

  • Portal visits. When a customer opens their customer account, the thread

says so. The card reports what was recorded and nothing more: that they opened it, when, and how many times within that hour — not which pages they read, how long they stayed, or what they were looking for. Repeated opens inside the same hour are one card with a count rather than a stream of entries, so a customer clicking around their account does not bury the conversation. Opens of a proposal or an invoice keep their own cards, which name the document.

  • Customer-sent photos. When a customer texts photos to the company

number, or emails them to your reply address, the pictures are saved with the message and shown on its bubble. Each photo is verified to actually be an image and re-encoded before it is stored — hidden picture metadata, including the sender's location data, is stripped — and it is served only to signed-in teammates authorized for that conversation's location, never through a public link.

  • Customer-sent PDFs. A PDF a customer emails you now arrives as a

document you can open, shown on the thread as a chip naming their file with a Download button. It used to be recorded as received and nothing more.

The button says Download rather than View deliberately, and the reason is worth knowing: a document is handed to you as a file to save, never opened inside Clean Estimate. That is the protection. A PDF can carry active content, so nothing checks it for safety and nothing claims to — what is checked is only that the file really is a PDF and arrived complete. Open it with the same care you would give any attachment from a customer.

  • The kind is decided by the file, not by its name. A phone's file picker

mislabels attachments often enough that trusting the label would lose real paperwork, so Clean Estimate reads the bytes. A PDF a customer's phone called an image is still treated as the PDF it is.

  • An attachment that did not arrive says which problem it was. Rather than

one sentence for every situation, the thread distinguishes a file that was too large to keep, one the messaging provider no longer holds, and one our own retrieval could not reach — and names the sender's own file when one was provided, so "estimate.pdf was too large to keep" tells you exactly what to ask the customer for.

Whose problem it is decides what you say next, which is the whole point: a customer whose scan was refused for size should be asked for a smaller one, and a customer whose file our own system could not fetch should not be told anything about their file at all. Nothing here ever claims a file arrived damaged, because nothing we can measure separates a damaged file from a transfer that was cut short.

Delivery status

Every outbound text carries a status pill next to its time: Queued, Sent, Delivered, or Failed. The pill only ever moves forward — a later "sent" report from the carrier never replaces a "delivered" or "failed" pill already showing, and some carriers report only as far as Sent and never confirm what happened at the handset. A Failed bubble also shows a short red line naming the carrier's error code when one was reported. These reports arrive from the carrier automatically; there is nothing to configure. See Did your messages land? below for the Inbox-wide delivery summary these per-message statuses feed into.

New job events are saved as append-only history in the same operation as the job change; they are not reconstructed later from current status or message wording. When a crew records a start or completion offline, the timeline uses the validated device tap time rather than the later sync time. Existing jobs receive their exact creation event, and already completed jobs receive their exact completion event. Clean Estimate does not invent older schedule or reschedule events when no authoritative timestamp was stored. Remaining V1 system-event types remain parity work.

A card for a recorded call also offers Add follow-up, which raises an ordinary task from that call. Give it a title, an optional due date, and an owner — left blank, it is yours. The task carries the call's customer automatically and links back to the call itself, so the reminder can always be traced to the call that produced it, along with whatever recording, transcript, or review that call holds. It appears in the Tasks workspace with its due date and owner like any other task.

Each person gets one follow-up per call, so a double click or a retried submission produces the same reminder rather than two; the Inbox says the follow-up already exists instead of filing a duplicate. Two teammates who were both on a call can each raise their own, and the card lists every follow-up on that call — including a colleague's — so two people do not end up ringing the same customer. Raising a follow-up sends no notification; it is a task, and creating a task has never alerted anyone.

The Inbox provides Call back for eligible completed call cards, but it does not expose free-form dialing, call scores, coaching, or AI summaries. Use the separate web Phone workspace for broader call history. Those remaining call actions and intelligence require their own permission, provider, retention, and review contracts; their absence is not represented by a placeholder control.

Screenshot placeholder
Conversation thread showing SMS, email, and an internal note

At the bottom of a matched customer thread, Linked Estimates restores the V1 estimate-history handoff. It shows the customer's 25 most recently updated estimates, newest first, with the estimate number, service type, updated date, status, and total. Select an estimate to open it directly. When the customer has additional history, select View full customer history to continue in the customer profile. The list follows the signed-in teammate's location access, so estimates from unauthorized locations do not appear.

Screenshot placeholder
Linked Estimates section showing estimate numbers, statuses,

totals, updated dates, and the full customer history action]


Compose Area

The compose area sits at the bottom of the right panel. Use it to send a new SMS or email directly from the conversation, or add an internal note for your team.

A toggle lets you switch between SMS, Email, and Note mode.

Screenshot placeholder
Compose area toggle showing SMS, Email, and Note options

When you switch to a different conversation, the compose area now resets to that contact before the thread reload finishes. This prevents an SMS, email subject, email body, or internal note draft from carrying over from the previous customer.

In the V2 native mobile app, choose Text, Email, or Internal note above the composer. The target line shows the exact saved destination or the reason that channel is unavailable. Internal notes show Visible to: Team only and appear as distinct amber entries in the timeline. The V2 mobile composer currently has no AI Draft control.

Current web composer controls

In SMS mode:

  • A text area for your message
  • The customer's phone number, auto-filled from their record
  • A V1-style counter showing the current draft length out of 160 characters
  • An Attach button that adds pictures to the reply
  • An AI Draft button that adds an editable suggestion
  • A Send button

The counter matches V1's current length / 160 characters format. Longer drafts remain editable and sendable, but the counter changes to an amber warning because the carrier may split the text into multiple messages.

The Send button reads Sending… and stays disabled while a message is in flight, so a slow send cannot be double-clicked into two messages.

New SMS and email compositions on web use V1's 30-send-per-teammate, 15-minute protection window. V2 also pauses a burst above 10 new sends per minute to the same customer conversation and channel. Stable retries of an existing delivery attempt remain available because they cannot create a new message row. A paused new send never reaches the provider, and its draft stays in the composer for a later retry.

In Email mode:

  • A subject line field
  • A body text area
  • The customer's email address, auto-filled from their record
  • An Attach button that adds pictures or PDFs to the reply
  • An AI Draft button that adds an editable subject and body
  • A Send button

In Note mode:

  • A plain text field for internal context
  • An Add Note button
  • Team-only visibility so the customer never sees the entry

Sending photos and documents

Choose Attach in SMS or Email mode to add files to a reply. Up to ten go on one message, and each appears above the composer with an × to remove it before you send.

A few things worth knowing:

  • Photos anywhere, PDFs by email only. A photo can go by text or email. A

PDF can only be emailed — see below, because this is the part that changes what you do.

  • The two are checked differently, and it matters. A photo is proven real

by re-encoding it, and that same step strips hidden picture metadata, including your location, before anything leaves the platform. A PDF is checked only to be a genuine, complete PDF and is then sent exactly as you chose it: nothing is re-encoded and nothing is stripped, so what leaves the platform is the file you attached, metadata and all. Check what you are sending.

  • Resized to fit. Photos are re-encoded to a size within the limits

carriers publish, which removes the most common reason a large phone picture is rejected outright. It does not promise the picture arrives, and what you can find out afterwards still depends on the channel: an emailed photo reports back like any other email — a bounce or a complaint lands on the thread — while a texted photo follows its message's own delivery status pill, and some carriers never move a text past Sent even when they filtered or rejected it. See Delivery status above and Did your messages land? below. Large photos are also shrunk in your browser before upload, so attaching one from a phone works normally. A document is never resized — an ordinary invoice PDF is larger than the photo limit and is meant to be.

  • Texted photos share a size budget. A carrier limits everything on one

picture message, not just each picture, so a few large photos can be too much together even though each is fine alone. The composer says so and holds Send until you remove one — or switch to Email, which allows a much larger set, though not an unlimited one.

  • All or nothing. If a photo is no longer available when you press Send —

a teammate's device already sent it, or it sat unsent for a day — the whole message is held back and your draft is kept, rather than a reply going out without the picture it promised.

  • Drafts do not linger. A photo you attach and never send is cleaned up

automatically, along with its stored file. Removing one from the composer usually deletes it right away. The exception is a photo that came back to the composer because a send was refused at the last moment: Clean Estimate holds that one for a few minutes in case the original attempt is still landing, and says so if you try to remove it. Wait a moment and remove it again.

  • Threads must be matched. Attach a file only after the conversation is

matched to a client, the same rule that governs sending at all.

Switching between SMS and Email keeps your attached files, the same way it keeps your draft text. Switching to Note keeps them too, and says so — an internal note is never delivered to the customer, so it never carries them. They are still there, and still removable, when you switch back.

Why a PDF cannot be texted

Text messaging carries pictures reliably and documents unreliably: support varies by carrier and handset, and a file that silently arrives as a broken download for some customers is worse than one that was never sent. So Clean Estimate does not text documents at all rather than sometimes.

Because attachments follow the thread rather than the channel — the same way your draft text does — you can end up in this position honestly: attach a PDF while composing an email, then switch to SMS. The composer tells you before you send, and if you send anyway the message is refused and names the file, so you know which one to move rather than being told something vague about the whole reply.

Nothing is lost either way. The document stays attached, so switching back to Email is a click rather than a re-upload.

Screenshot placeholder
Compose area with a photo thumbnail and a PDF chip attached above the text area

Did your messages land?

Delivery in the Inbox header opens a summary of what happened to the messages your team sent, over a date range and optionally one location. It answers the question you would otherwise have to open threads one at a time to ask.

For each channel it shows what was attempted and then what became of it: accepted by the provider, refused because the customer had not consented, suppressed by a notification preference, failed, or held up because there was no contact method or no sender number. Everything adds up to what was attempted, so the figures always account for every message.

The two channels do not tell you the same things, and the page says so rather than papering over it.

  • Email is reported back to us. You get confirmed deliveries, bounces, spam

complaints, provider delays, blocked addresses, and messages the provider accepted and then failed to send — that last one matters, because it is a real failure on a message that otherwise looks sent.

  • Text messages now report back too, but not as completely as email. Once a

text is accepted, the carrier's own delivery report can confirm it reached the handset or that it failed, and this summary counts those alongside email's outcomes. Coverage still varies by carrier: some confirm only that the text was sent and never say what happened after. So a missing delivered/failed number here is not the same as nothing having arrived — it may simply be a carrier that never told us the rest of the story.

Two more things the page is careful about:

  • "Open signals" are not readers. An open means a tracking image was

fetched, which is wrong in both directions: privacy services fetch it when nobody has read anything, and mail apps that block images stay silent when someone genuinely has. Treat it as a weak signal. A click is stronger, because a link was followed rather than fetched, though link-checking scanners can produce those too.

  • "No outcome recorded" is not "failed". Occasionally a send is

interrupted before anything wrote down what happened. The message may well have reached your customer — what is true is only that we do not know. Those are counted separately and labelled honestly rather than being folded in with real failures.

In an email thread, delivery outcome is separate from opens and clicks. A later open or click does not clear a recorded bounce or complaint. When both delivery history and a failure are available, the failure stays primary and the prior delivery or engagement detail remains visible; an open or click alone is not a delivery confirmation.

Everything is counted by the day the message was sent, in the service location's own time zone, and the page tells you which range and zone the figures came from.

Screenshot placeholder
Message delivery summary showing email and text message columns side by side

AI Draft on web

Select AI Draft in SMS or Email mode to prepare a concise follow-up from the matched customer, the newest estimate at that conversation's exact service location when one exists, and up to eight recent customer-facing SMS or email messages. The drafting boundary excludes internal notes, calls, unsuccessful sends, provider metadata, saved recipient addresses, other-location estimates, and secure URLs from message bodies.

The result fills the ordinary subject and message fields. Read and edit it, then deliberately select Send. Generating a draft never sends anything and does not bypass the existing recipient, consent, company sender, current-thread, provider, or duplicate-send protections. If you change the draft, conversation, or channel while a suggestion is being prepared, the late result does not replace your newer work.

AI provider calls are limited to 50 per workspace in each 24-hour window. A generated link is rejected because drafting context never contains an approved secure customer URL. If the provider is not configured, is temporarily unavailable, returns an invalid result, or the workspace reaches that limit, Clean Estimate inserts a safe editable template and labels it clearly instead of failing the compose action. The approved V2 native mobile composer remains unchanged and still has no AI Draft control. Call scores, coaching, and AI call summaries remain parity work.


Unread Message Badge

The Inbox link in the web sidebar shows your unread customer-conversation count across the locations you can access. Counts above 99 display as 99+. The badge refreshes in the background, when the browser regains focus, and immediately after you open and mark a conversation read. Unread state remains per teammate: opening a conversation does not clear it for anyone else.

Real-Time Popup and Sound Alerts

The web app raises a toast popup and a short sound for a new inbound text, email, call, or voicemail, restoring V1's own Inbox alert behavior. It checks for new activity on the same 20-second cadence as the unread badge, so an alert never lags far behind the conversation list itself. Opening the app for the first time in a session establishes a baseline instead of replaying your existing backlog as a wave of alerts.

  • Supported message notifications open back into the matching Inbox thread.
  • Customer-engagement alerts pop live when Resend reports an email open or when a customer opens a current V2 quote, proposal, estimate, maintenance proposal, or invoice. Invoice-view notifications follow the organization's configured notification routes and are deduplicated by the hourly customer-view event. Supported estimate and invoice activity also appears as the factual conversation cards described above.
  • Operational alerts such as stale deals or overdue follow-up items open to the related record.
  • If your browser allows desktop notifications and the tab is hidden, the same

alert also appears outside the tab. If your browser blocks the sound or the desktop notification for any reason, the toast still appears -- the toast is what carries the news, and the other two are best-effort on top of it.

V1's fuller missed-call, voicemail-specific, and customer-engagement alert styling is not fully ported yet; the alerts above cover the same underlying events through this one shared popup/sound/desktop-notification path instead of V1's separate per-event treatments.


How Messages Get Into the Inbox

You do not need to manually log conversations. Messages appear in the inbox automatically from these sources:

  • Estimate delivery. When you send an estimate, the SMS and email are logged to the customer's conversation.
  • Customer SMS replies. When a customer replies to one of your text messages, the reply arrives through the active telecom provider webhook and appears in the thread. Photos attached to the text are saved durably and shown on the same bubble once verified.
  • Customer email replies. When a customer replies to an email, the reply is routed through your organization's email slug and logged to the thread. Photos attached to the email are saved durably and shown on the same bubble once verified, the same as texted pictures.
  • Customer portal replies. A signed-in customer can choose an authorized

service location and send a message from the customer portal. It appears as normal inbound activity in that location's shared office thread, so the office can answer through the existing email workflow. The message subject preserves the selected service address. The portal does not claim an external email or text send for the customer's own submission.

  • Phone calls and voicemails. Provider-powered call activity, including Twilio AI Voice Agent summaries when that path is enabled, is logged to the same customer thread.
  • Automated follow-ups. Messages sent by follow-up sequences are logged here so you can see what your automations have sent.
  • Internal notes. Team members can leave private notes on the thread for handoffs, phone call summaries, and next steps.
  • Customer document events. Supported proposal send, withdrawal, view,

acceptance, or decline and invoice send, view, payment, or void appear as dedicated cards in the matched web conversation. Remaining V1 system events stay parity work.

  • Job events. Job creation, scheduling, rescheduling, removal from the

schedule, work start, completion, and cancellation appear as durable cards in the matched web conversation.

  • Maintenance-agreement and payment events. Agreement lifecycle changes

(started, renewed, paused, resumed, extended, cancelled, auto-renew) and every payment received or refunded appear as cards in the matched web conversation's System activity.

  • Customer request events. Portal service requests and appointment-change

requests — with their office approvals or declines — appear as cards in the matched web conversation's System activity.

  • Sent estimate and proposal email/SMS messages remain in the thread. Tracked

estimate and invoice page views also appear in the supported document activity history. Provider-confirmed email delivery, open, click, delay, and failure activity appears on the outbound email bubble rather than masquerading as a customer document-view card. Resend open and click activity is available only when tracking is enabled for the sending domain and the signed Resend webhook is subscribed to those lifecycle events.


Tips

  • The web conversation list refreshes every 20 seconds and after staff actions.

Manual sends and notes refresh the open thread immediately. If you have loaded older conversations, the refresh reconciles the full loaded section so activity moving between pages does not create a gap.

  • Per-thread drafts remain isolated by conversation. Switching threads shows

that conversation's own draft instead of carrying another customer's text into the composer.

  • A single customer thread combines SMS and email history. Use the per-thread

timeline filters to focus that history on Texts, Emails, Calls, Voicemail, Notes, or System activity.

  • Use the search bar to find conversations by customer name, phone number, or email address.
  • Use assignment and response filters during busy periods so no conversation gets missed.
  • Add an internal note before handing a thread to another rep so they have the right context.
  • Write or paste the message you want to send; AI-assisted web drafts remain

V1 parity work.

  • Review call summaries after AI voice-agent conversations so your team can see qualification details before calling the customer back.

Was this article helpful?

Still need help? Contact support