Skip to content

Ball-in-court model

The ball-in-court model is the heart of EstimateIQ. It answers one question at a glance for every estimate: whose move is it?

The estimate is the collection

An estimate is not a single document — it’s a collection. The estimate header (claim, carrier, insured, estimator, RCV/ACV, phase, loss type) is the anchor, and around it accumulate the full timeline of the claim:

  • Revisions — each outbound submission and each inbound auditor return, as a numbered round.
  • Line items — the Xactimate scope, each with a status (accepted, challenged, …).
  • Follow-ups — the estimator’s task queue for this file.
  • Events — an append-only per-estimate timeline (opened, submitted, revision, rule fired, …).
  • Emails — carrier correspondence attached to the estimate.

The estimate’s current state — its status, its ball, its aging — is derived from that collection, never stored ambiguously.

The ball

Every estimate has a ball-in-court value derived from its status:

BallMeaning
usThe ball is with GRS — an estimator needs to act (draft, respond to a revision).
carrierThe ball is with the carrier — we’re waiting on them (submitted, in review, responded).
doneThe claim has resolved — nothing left to do (approved, settled, closed).

The ball is a pure function of status, so it can never drift out of sync with where the estimate actually is.

Status state machine

Statuses are canonical and internal. External systems (carrier portals, CRMs, XactAnalysis, Power Automate) map into these — see Webhooks & integrations.

draft ─▶ submitted ─▶ in_review ─▶ revision_requested ─▶ responded ─▶ approved ─▶ settled
StatusBallNotes
draftusEstimator is writing the estimate (round 0).
submittedcarrierRound 1 sent to the carrier; awaiting acknowledgement / audit.
in_reviewcarrierCarrier desk audit in progress.
revision_requestedusCarrier kicked it back — supplement / revision needed.
respondedcarrierWe resubmitted our revised answer; ball back to carrier.
approveddoneCarrier approved as revised.
settleddonePaid / closed out.
closeddoneTerminal close-out.

The revision_requested → responded → in_review → revision_requested … cycle can repeat as many times as the negotiation requires. Each pass is a full lap of the loop, recorded on the estimate’s timeline and incrementing the round counter.

Two clocks

EstimateIQ runs two independent timers so both sides of the loop stay accountable. Which one is running is decided by the ball:

  • SLA clock — runs when the ball is with us. It measures how long GRS has held a revision request before responding, against the carrier’s slaResponseDays (scaled by the phase multiplier). This drives the estimator’s daily follow-up queue.
  • Desk-audit clock — runs when the ball is with the carrier. It measures how long the carrier has held the estimate, against the carrier’s typicalAuditDays, so overdue audits can be chased.

Because the ball is derived from status, the correct clock is always the one that’s running — the moment a status change flips the ball, the active timer resets (clockStartedAt) and switches with it.

Aging states

Each clock reports an aging state by comparing time-held against the budget. The thresholds are configurable via the SLA policy (warnPct / escalatePct) and the per-phase multiplier:

StateRule (share of budget)Meaning
freshbelow warnPct (≈0.5)Plenty of runway.
warmat/above warnPctApproaching the window.
dueat/above duePct (≈0.8)Act now.
overdueat/above escalatePct (≈1.0)Past the window — escalate.
doneResolved; no clock.

These states color the worklist, feed the dashboard rollups (overdue estimates, overdue follow-ups), and — when the ball is with us — drive the SlaTimerDO alarm that fires an escalation nudge if the response window elapses with no movement.