vicigeeksimple guides
Browse
All guides

Reports & results · Accurate reporting

Make agent time detail match reality

Reproduce a 25-minute clipped interval fixture, then require a verified native duration/login adapter before reconciling an actual VICIdial report.

Reader setup

Before you diagnose

  1. Choose one synthetic agent session and record the report timezone, interval start and interval end.
  2. Obtain authorized read-only event/login data with personal identifiers replaced by an opaque fixture label.
  3. Keep the existing report query and expected login duration so every proposed formula can be compared and reversed.
Expected result
Retain partial overlaps correctly, reproduce the 1,500-second fixture and leave a precise source-to-interval handoff for an actual report.
Before making changes
Work on synthetic or approved aggregated data. Do not rewrite raw history or change access filters merely to force totals to match.

Confirm the native source before deriving intervals

First check whether the documented agent_stats_export already supplies the required totals for the exact agent, campaign grouping, timezone and report window. Use the installed Non-Agent API reference and the protected API setup; this fixture does not certify that export’s internal formula.

vicidial_agent_log contains duration/epoch fields; sorting event_time or treating sub_status as a generic READY/PAUSED state stream is not a verified adapter. A report owner must map the installed *_epoch/*_sec semantics and the actual login/session source before a native calculation.

Ask for one minimized synthetic row plus its verified session/login boundaries. Required adapter output is session identity, state, interval start,end and source-row reference. If the owner cannot establish that mapping, stop at the offline fixture and hand off those missing fields; do not invent logout or a preceding boundary state.

Before you use it
Run in the verified read-only SQL client. This lists definitions only; it does not establish the installed report’s derivation.
Inspect duration fields, not customer rows
SHOW COLUMNS FROM vicidial_agent_logWHERE Field IN ('event_time','pause_epoch','pause_sec','wait_epoch','wait_sec','talk_epoch','talk_sec','dispo_epoch','dispo_sec','dead_epoch','dead_sec','sub_status','pause_type');
Reader-run example · not executed for this guide

This example has no recorded result here. Follow its preparation, expected result and stop conditions before using it.

Success looks like
The owner can compare actual columns with the source/report implementation and supply a verified synthetic adapter.
Stop if
Missing or different fields and uncertain login/session mapping block native interval reconstruction.

You should seeUse documented export totals or a reviewed native adapter. The next exercise is explicitly fictional.

Prepare a protected API read

Prepare the read-only client

Trace path · read left to right
01Raw events02Login-window clipping03Visible report totals
Reference screenshots 3 images

Reference capture

Reference screens from the demo

Captured on an isolated VICIdial demo: Administration screens on September 24, 2026, and the idle Agent screen on August 11, 2026. Each caption states its own capture time, and every sanitized image helps you recognize a related screen; none proves that this article's call, command, or result occurred.
Step 1 · Separate counts from reports

Treat home-page counts as orientation

Open to enlarge
Sanitized VICIdial Administration home page with navigation and aggregate system counts
Captured September 24, 2026 at 21:54:37 UTC on the authorized isolated demo.
Capture detailsThis is an orientation page with aggregate counts only; it is not a report and does not prove production activity or a completed call.
Step 2 · Choose a report family

Use the Reports index

Open to enlarge
Sanitized VICIdial Server Stats and Reports index showing report categories without report rows
Captured September 24, 2026 at 21:53:36 UTC on the authorized isolated demo.
Capture detailsThe server-status row was removed. This is a report index, not a generated report, delivery record, or performance result.
Step 3 · Recognize the live-format report layout

See the Real-Time report layout

Open to enlarge
Sanitized VICIdial Real-Time Main Report in a live-format layout with zero agent or call activity
Captured September 24, 2026 at 21:54:28 UTC on the authorized isolated demo.
Capture detailsThis is a live-format report layout filtered to the fixture campaign with zero activity; it does not prove production call volume or agent performance.

Treat state as intervals, not labels

Fast answer: use the following clipping model to investigate a report mismatch. The available documentation does not establish that agent_stats_export implements this exact formula internally. A state change has a start but often no explicit end; derive its end from the next event, then intersect (clip) that interval with the agent's actual login window and report boundary.

An agent who never logs out cleanly — a crashed browser tab, a lost network connection — leaves a final state change with no next event to derive an end from at all. Treat that last open interval as ending at either the report boundary or a documented forced-logout time, whichever is earlier and actually knowable, and say plainly in the report which one you used; silently picking one without disclosing it is how two people reconciling the same day arrive at two different totals.

Rows outside the window must not become visible simply because their state label matches the current filter.

See VICIdial terminology for complete beginners: users, phones, campaigns and leads for the rest of this glossary.

Before you use it
Use this as pseudocode in a worksheet or reviewed query, not as a command. All timestamps must share one named timezone; next_event_start is the following state-change time for the same synthetic session.
Interval clipping rule
visible_start = max(event_start, login_start, report_start)visible_end   = min(next_event_start, logout_time, report_end)visible_secs  = max(0, visible_end - visible_start)
Not executed · worksheet or reference text

This sample is a template or reading aid, not a terminal command. There is no output to show.

Success looks like
Every visible interval begins no earlier than login/report start, ends no later than logout/report end, and negative durations become zero.
Stop if
Stop if the next event belongs to another session, logout is unknown, timezone conversion is ambiguous, or overlapping login windows have not been separated.

Run the complete fictional duration-row fixture

This fixture assumes the adapter has already established start_epoch plus duration_seconds for each interval and one UTC login session. It does not read a database. The fictional raw row has PAUSED09:00–09:12, WAIT09:12–09:20 and TALK09:20–09:40; login09:05–09:30 clips the first and last.

The same three item identities must produce420,480 and600 seconds. The partial PAUSED interval is retained even though its raw start predates login. An actual report needs the reviewed adapter above, including any event that begins before report_start.

Before you use it
Run locally with Python 3. The input labels and UTC timestamps are invented; no server, account or report is contacted.
Execute the local interval fixture
python3 - <<'PYMODEL'from datetime import datetime,timezoneT=lambda text:int(datetime.fromisoformat("2026-11-07T"+text+"+00:00").timestamp())# Fictional duration-row adapter, not a captured database export.raw=[("PAUSED",T("09:00:00"),720),("WAIT",T("09:12:00"),480),("TALK",T("09:20:00"),1200)]login,logout,report_start,report_end=map(T,["09:05:00","09:30:00","09:00:00","10:00:00"])visible=[]for state,start,duration in raw:    end=start+duration    left=max(start,login,report_start); right=min(end,logout,report_end)    seconds=max(0,right-left); visible.append(seconds)    print(state,seconds,"seconds",("partly clipped" if seconds and seconds<duration else "whole or excluded"))assert visible==[420,480,600] and sum(visible)==logout-login==1500print("PASS total 1500 seconds = 25 minutes; partial overlap retained")print("Fictional UTC interval fixture only; no native report calculation certified.")PYMODEL
Evidence · Local fictional fixture · actual Python execution; no PBX/database/provider operation

Captured local fixture result · 2026-11-07T20:35:06.594890+00:00. Any filtering, hidden values or test-only data are identified in the capture label. Select Replay transcript to read the recorded output.

Command output line: python3 - <<'PYMODEL' from datetime import datetime,timezone T=lambda text:int(datetime.fromisoformat("2026-11-07T"+text+"+00:00").timestamp()) # Fictional duration-row adapter, not a captured database export. raw=[("PAUSED",T("09:00:00"),720),("WAIT",T("09:12:00"),480),("TALK",T("09:20:00"),1200)] login,logout,report_start,report_end=map(T,["09:05:00","09:30:00","09:00:00","10:00:00"]) visible=[] for state,start,duration in raw: end=start+duration left=max(start,login,report_start); right=min(end,logout,report_end) seconds=max(0,right-left); visible.append(seconds) print(state,seconds,"seconds",("partly clipped" if seconds and seconds<duration else "whole or excluded")) assert visible==[420,480,600] and sum(visible)==logout-login==1500 print("PASS total 1500 seconds = 25 minutes; partial overlap retained") print("Fictional UTC interval fixture only; no native report calculation certified.") PYMODEL
PAUSED 420 seconds partly clipped
WAIT 480 seconds whole or excluded
TALK 600 seconds partly clipped
PASS total 1500 seconds = 25 minutes; partial overlap retained
Fictional UTC interval fixture only; no native report calculation certified.
Success looks like
The three durations are420,480,600 and the assertion accepts1,500 seconds. This verifies the model arithmetic only.
Stop if
A failed assertion leaves the fixture unaccepted. For real data, unknown session identity, timezone or native adapter means stop before comparing totals.
Fictional adapter input and clipped outputScroll sideways to compare columns
StateRaw intervalClipped intervalSeconds
PAUSED09:00–09:1209:05–09:12420
WAIT09:12–09:2009:12–09:20480
TALK09:20–09:4009:20–09:30600
TotalUTC fixture25-minute login window1,500

Local interval overlap arithmetic model

Duration 0:11
Actual local fixture execution

Actual local fixture execution with fictional input. No VICIdial, database, carrier or provider operation.

Steps and result3 steps

Fictional UTC duration-row adapter only;no native Agent Time report or installed schema calculation certified. Actual localhost browser capture,November7,2026;fixed source command executed by Run fixture. Video/still include ViciGeek attribution;this is not native VICIdial UI.

Observed local fixture result420+480+600=1500seconds:25minutes of fictional overlap.

Read the chapter notes
  1. Local fictional scope

    Actual local fixture execution with fictional input. No VICIdial, database, carrier or provider operation.

  2. Click Run fixture

    420+480+600=1500seconds:25minutes of fictional overlap.

  3. Actual stdout and model limits

    420+480+600=1500seconds:25minutes of fictional overlap.

2026-11-07T20:35:06.594890+00:00 · Local Python fixture / actual browser run. fictional UTC duration-row arithmetic only Use fullscreen to read the actual local inputs and results.

View a still screenshot

Observed local fictional model

Open to enlarge
Local interval overlap arithmetic model with the actual successful fixture output and a LOCAL FICTIONAL FIXTURE label.
Actual localhost browser capture, November 7, 2026.
Capture detailsFictional UTC duration-row adapter only; no native Agent Time report or installed schema calculation certified. The Run fixture action executed the exact adjacent command; its exit code and stdout were retained. This is a local model interface, not native VICIdial UI.

You should seeYou have reproduced partial-overlap clipping and can explain what the native adapter still must establish.

Exclude intervals by overlap, not by their starting label

Keep the raw interval unchanged and derive the visible overlap separately. A raw start before login/report start does not make the whole row invisible: retain the part inside the verified bounds.

Classify a fully excluded row by its end/start relative to the boundaries. Policy-hidden time is a separate permission/report rule, not a timing shortcut.

You should seeThe exclusion rule agrees with the 420-second partial interval and the 1,500-second total.

  • Fully before: event_end is at or before max(login_start,report_start). Visible duration is0.
  • Fully after: event_start is at or after min(logout_time,report_end). Visible duration is0.
  • Partial overlap: visible_end exceeds visible_start, even if the raw start is earlier or raw end later. Retain only the positive clipped part.
  • Hidden by policy: explain the independent access rule; preserve raw audit evidence and do not count it as a clipping error.

Reconcile daily totals

For a controlled agent day, sum clipped intervals and compare them with login duration, pause detail and call timestamps. Gaps and overlaps should be explainable.

Test midnight boundaries and an agent with multiple login sessions. Those cases reveal most interval mistakes quickly.

Allow a small, named rounding tolerance rather than demanding an exact match to the second — first identify the timestamp precision and rounding in both calculations; a difference can also indicate a real mismatch. State the tolerance you are using explicitly, though: an undisclosed tolerance is indistinguishable from a report that simply does not reconcile.

Stop on an unexplained second and reverse the query change

Do not release a revised report while synthetic interval totals exceed the login window, cross session boundaries or differ between repeated runs at the same as-of time. Record the smallest failing fixture and preserve the old query/version.

Rollback means restoring the prior report calculation or view without altering event history. Fix the interval derivation in a test copy, repeat midnight and multi-login cases, then ask an independent reviewer to reproduce the arithmetic.

  • Old and proposed query definitions remain versioned and reversible.
  • Synthetic normal, midnight and multiple-login sessions reconcile independently.
  • Visible and hidden durations remain separate from raw audit evidence.

Checks and sources

What was checked

  • The duration-row/login fixture is fictional and runs locally. Its result verifies interval arithmetic only.
  • No native agent_stats_export formula, historical report total, user session or database conversion was executed or certified for this repair.
  • The installed report/source owner must verify epoch/duration and login-session mapping before applying this model to real data.
  • The exact local fictional model command was executed through the recorded browser on November 7, 2026; command/stdout hashes and exit 0 match the capture provenance. This establishes only the model scope stated beside that exercise.

Primary references

Sources

  1. Inconsistency Agent Time DetailVICIdial forum · accessed September 23, 2026
  2. VICIdial Non-Agent APIVICIdial · accessed September 23, 2026

Follow without guesswork

Get the next article

RSS is live now. Email delivery below is an explicit local preview and sends nothing.Open the RSS feed
Email preview only. The address stays in this browser and is never transmitted.