Export Chat, Chat Stage History, Contact, Ticket, Call-Log, Goal, Booking, Follow-up, Survey-response, and Flow-response data as CSV — filtered as precisely as the module page that owns the data, generated in the background, and delivered via a time-limited download link.

TL;DR

  • What it is — an admin-only CSV export surface. Pick a report type, apply filters as rich as the underlying module's own filter UI, trigger generation, come back when it's ready, download.
  • Who it's for — Admins and Account Owners only. Users are blocked at the page and at the API.
  • Top outcome — get raw data into Excel, BI, or another system — with the same filter precision as the module pages — without keeping a browser tab open for the whole run.

At a glance

Plan tierAll paid tiers.
Who can use itAccount Owners and Admins only. Users see an Access Restricted message on the page.
Report typesChat, Chat Stage History, Contact, Ticket, Call-Log, Goal, Booking, Follow-ups, Survey Responses, Flow Responses.
IntegrationsCSV stored on Lodgestory and delivered via a time-limited download URL (expires after 1 hour).
Top limits1 report per type per organisation per 5 minutes. Large exports are streamed, so there's no hard row cap.
APIYes — partner API (JWT-protected) for requesting, listing, and downloading reports.

How to find it

Sidebar → Reports. Non-admins see the Access Restricted card instead of the page contents.

Direct URL: https://app.lodgestory.com/crm/reports

📸 [SCREENSHOT: reports-nav.png — sidebar with Reports highlighted]

What is Reports?

The problem it solves

The Analytics dashboard answers "how is the team doing?" at a glance but doesn't export. The module pages (Tickets, Calls, Contacts, and so on) let you filter live but can't hand the filtered slice to Excel. Reports fills that gap with the exact filter vocabulary of each module page, lifted to a background CSV export.

Background generation matters because a large organisation's six months of chats can take minutes to export — nobody wants a browser tab open on a 15-minute request.

What you get

  • Ten report types, each with filters that mirror the live module page:
    • Chat — the richest filter set (about 25 dimensions): archive / resolved & closed / priority / bot handling / unanswered / assignment / workflow / labels / channels / date range / search. Unlike the inbox, the export is a lifecycle record: leave the resolved filter unset and you get every chat, open and closed; set it to isolate one side. CSV has 35+ columns including contact, assignment, created / resolved timestamps and who resolved it, the current stage (with when it was entered and whether it's final), ticket count, goal-event summaries, and one column per custom field from every active contact template.
    • Chat Stage History — one row per workflow stage a chat entered, with entered / left timestamps, time in stage, who moved it and why. Closed chats included. Every Chat filter applies, plus a stage-date range and "moved by" users.
    • Contact — 11 base columns plus one column per unified custom field across your organisation's contact templates. Filters: search, has-chats, channel, creator, date range, plus custom-field predicates.
    • Ticket — 19 columns, led by the per-organisation ticket number ("#42"); includes the linked call number for tickets raised from calls and the customer phone/email captured on standalone tickets. Filters: status, priority, assignee, creator, ticket workflow, date range, search (matches ticket number too — "42" or "#42").
    • Call Log — 27 columns including talk / ring / total durations, hang-up cause, agent / customer / chat linkages, linked ticket numbers ("#42"), and recording availability. Filters: direction, status, agent, account, date, duration range, search.
    • Goal — columns are built per run based on the goals and trackers that fired in the period, so the CSV shape adapts to the data.
    • Booking, Follow-ups, Survey Responses — calendar bookings, agent follow-up reminders, and survey submissions (one column per question).
    • Flow Responses — every WhatsApp Flow submission across the organisation, with the chat and campaign each came from and one column per captured field.
  • Background generation. Request, come back when ready, download. The page auto-polls every few seconds while any report is pending.
  • Rate-limited. One report per type per organisation per 5 minutes — prevents duplicate heavy exports.
  • Streamed generation — no memory blow-up on large exports.
  • Time-limited download URLs — expire after 1 hour.

How it's different

  • Two API surfaces, one module. The in-app UI is available to Admins and Account Owners on the web. The partner API is published on the public OpenAPI spec with example payloads per type, so integrators can drive exports without opening the CRM.
  • Role enforcement is belt-and-braces. The frontend hides the page from non-admins. The API additionally verifies the role on each call and returns an error if it's missing. Non-admins who know the URL can't pull a report.
  • Goal reports discover their shape from the data. Because every journey configures its own goals and trackers, the CSV is built per run — making the export stable regardless of how goals evolved over the period.

Customer scenarios

  • Month-end ops review. Admin exports a Chat report for the previous month filtered to Open + High priority. Opens in Excel. Pivots response-time metrics against agent for the monthly review.
  • Finance reconciliation. Finance admin exports Call Logs for a specific telephony account over the billing cycle. Reconciles against the provider's invoice by duration and direction.
  • Compliance audit. Admin exports Tickets filtered by issue category and date range. Hands the CSV to the compliance team.

How it fits with the rest of Lodgestory

Upstream: filters mirror the live UI of Home, Tickets, Contacts, Calls, and Bot Journey Goals. The CSVs contain the same data the UI surfaces at the same filter grain. Reports is the export of everything below the fold; Analytics is the at-a-glance dashboard.

Core concepts

TermWhat it means
Report jobThe export row. Has a type, a status (Pending → Processing → Completed / Failed), a filter payload, a requester, a generated file, and timestamps.
Report typeChat, Chat Stage History, Contact, Ticket, Call Log, Goal, Booking, Follow-ups, Survey Responses, or Flow Responses.
StatusPending (just requested), Processing (being generated), Completed (ready to download), or Failed (with an error message).
Filter payloadThe filter values you picked when requesting the report. Different per report type.

Quick Start — your first report in 3 minutes

Step 1 — Open Reports

Sidebar → Reports. If you see Access Restricted, you don't have the Admin or Account Owner role.

Step 2 — Pick a report type

Top selector: Chat / Chat Stage History / Contact / Ticket / Call Log / Goal / Booking / Follow-ups / Survey Responses / Flow Responses. A type-specific description appears.

Step 3 — Set filters

Open the filter panel — the filter vocabulary matches the corresponding module's live page (Ticket filters include priority, status, assignee, creator, workflow, date range, and search).

Step 4 — Click Generate Report

A row appears with status PendingProcessing. The list auto-refreshes every few seconds.

Step 5 — Download

When status flips to Completed, click Download. The system generates a download URL (valid for 1 hour) and opens it in a new tab.

Rate-limit note: requesting the same type twice within 5 minutes returns a conflict and points you at the existing record. Wait until the window elapses or reuse the existing CSV.

How it works

When you request an export, Lodgestory:

  1. Checks that no export of the same type is already pending, processing, or completed in the last 5 minutes.
  2. Creates a job record.
  3. Queues a background worker to generate the CSV.
  4. Updates the job's status as it progresses — Pending → Processing → Completed (or Failed with a reason).

When you click Download:

  1. Lodgestory generates a time-limited download URL.
  2. Your browser opens the URL in a new tab.
  3. The file is downloaded; the URL expires after 1 hour.

Large exports are streamed so memory usage stays flat regardless of row count.

Features in depth

Chat export

About 25 filter dimensions mirroring the Home inbox advanced filter panel: archived, resolved & closed, high priority, has contacts, bot handled, unanswered, agent transferred, session closed, assignment, workflow, labels, channels, date range, chat name / contact search, chat type. The resolved & closed filter is tri-state: leave it unset and the export contains every chat, open and closed (an export is a lifecycle record, unlike the inbox list); set it to resolved or open to isolate one side.

CSV output is 35+ columns including:

  • Chat identifiers, channel, timestamps — createdAt, last activity, and resolvedAt.
  • Resolution: isResolved, plus resolvedByName and resolvedByEmail (the admin who closed it, or the agent whose workflow finish closed it).
  • Primary contact fields plus one column per custom field across all active contact templates.
  • Labels (comma-separated), current workflow state (currentState as Workflow: Stage), currentStateEnteredAt (when the chat entered that stage) and currentStateIsFinal.
  • Flags: archived, high priority, autopilot.
  • Primary assignee name and email, all assignees, teams.
  • External-items values.
  • Notes count and summary (first 5, truncated).
  • Tickets count, open tickets, summary.
  • Bot session flag, goals, milestones, tracker values.

For how long a chat spent in each stage, use the Chat Stage History export below — the Chat export only carries the current stage.

Chat Stage History export

One row per workflow stage a chat entered — the append-only stage history behind the History modal in the guest panel, across every chat that matches your filters. Closed chats are included by default, so a finished lifecycle exports whole.

21 columns: Chat ID, Chat WP ID, Chat Phone, Chat Name, Channel, Contact Name, Contact Phone, Workflow, Workflow Version, Stage, Stage Type (starting / in-progress / final), Entered At, Left At, Time In Stage (s), Moved By, Moved By Email, Remarks, Close Reason, Responsible User, Primary assignee (at export), Is Final.

How the timing columns are derived:

  • Entered At is when the chat moved into the stage.
  • Left At is when it moved on: the row's own close time, or — when the row was superseded by a transition — the moment the next stage was entered. A stage the chat is still in has an empty Left At.
  • Time In Stage (s) = Left At − Entered At, measured to the export time for stages the chat is still in. A Final stage is closed on arrival, so its time in stage is 0.
  • Close Reason records why the row closed — Superseded by transition to …, Reached final state: …, Superseded by workflow restart, or the channel-rule auto-close when a stale or reopened chat was moved onto a revived-chat workflow.
  • Revival bookkeeping rows (the auto-close markers written when a chat revives onto a new workflow) are not exported — they aren't stages the chat entered. Their close reason is attached to the real row they closed instead.
  • Stages of workflows that have since been retired or deleted still export; a stage removed from its workflow shows its raw id in Stage.

Filters: every Chat filter (channels, workflow, labels, assignment, resolved & closed, date range, search, …) plus three of its own — stage entered from / to (stateFromDate, stateToDate) and moved by (stateMovedByUserIds), which narrow the stage rows themselves rather than the chats. Rows come out ordered by chat, workflow, and time entered.

Also available through the MCP reports_request tool and the partner API as report type CHAT_STATE_HISTORY.

Contact export

11 standard columns plus one column per unified custom field across active templates. Filters: name / phone / email search, has-chats, channels, creator, date range, and custom-field predicates.

Ticket export

19 columns: ticket number ("#42"), ticket / chat / contact identifiers, linked call number (for tickets raised from calls), customer email, issue, sub-issue, priority, status, remarks, assigned-to, created-by, workflow, media count, timestamps. Contact Phone falls back to the customer phone captured on standalone tickets. Filters: status, priority, assignee, creator, ticket workflow, date range, and free-text search — typing a bare number or "#42" matches the ticket number directly; phone-number searches also match a linked call's numbers.

Call Log export

27 columns. Every call field: direction, status, caller / called numbers, caller-ID, agent, customer, chat linkage, linked ticket numbers (tickets raised from the call, e.g. "#42, #43"), talk / total / ring durations (both formatted and raw seconds), hang-up cause, recording availability, timestamps, account, provider. Filters: direction, statuses, agent, account, date, has-recording, has-chat, duration range, phone / contact search, hang-up cause.

Goal export

Goal exports don't have a fixed CSV shape — they derive it from the data. Lodgestory scans the matched chats' latest bot-journey sessions, finds the maximum goal-event count per chat and the union of tracker names at each event position, and writes a CSV with 11 static columns (chat identifiers, journey, session, total event count) followed by dynamic per-event-position columns: Goal N Name, Goal N Milestone, Goal N Recorded At, and one column per tracker name at that position.

Filters: goal-event date range, goal IDs, channels, and tracker-value predicates.

Flow Responses export

Every WhatsApp Flow submission in the organisation, newest first. Like Goal and Survey exports, the shape is derived from the data: ten fixed context columns followed by one column per field the flows actually captured, sorted alphabetically.

Fixed columns: Response ID, Flow, Flow ID, Chat ID, Channel ID, Source, Campaign ID, Journey Session ID, Sent At, Responded At.

Source records how the flow reached the customer — journey, campaign, chat_template, or test_send — so answers gathered by a bot journey can be separated from a campaign blast in the same file. Only completed submissions are included; sends that were never finished produce no row.

Filters: flows (any subset), source, and a responded-on date range.

Exporting a single flow? The flow's own Responses panel has a Download CSV button that skips the queue. Use this report type when you need several flows, a date range, or a scheduled pull through the API.

Roles and permissions

ActionAccount OwnerAdminUser
Open /crm/reports✗ (Access Restricted)
Request an export (web or API)
List exports
Download a completed export

Cross-module workflows

  • Monthly ops review. Chat export, previous-month filter, High priority — into Excel for agent performance review.
  • Finance reconciliation. Call Log export over the billing cycle, filtered to a specific telephony account — reconciled against the provider invoice.
  • Compliance audit. Ticket export with specific issue categories and date range — handed to compliance.
  • Stage dwell-time review. Chat Stage History export for last month, filtered to one workflow — pivot Time In Stage (s) by Stage and Moved By to find where conversations stall and who unblocks them.

Limits a user will run into

LimitValue
Rate1 export per type per organisation per 5 minutes
Download URL expiry1 hour
Max rows / file sizeNo hard cap — streamed
List auto-refreshEvery few seconds while any export is pending or processing

Errors & FAQ

You seeLikely reasonWhat to do
A report of this type is already being generatedA pending or processing job existsWait for it to finish or reuse
A report was completed recently. Please wait before requesting another.Same type finished in the last 5 minutesReuse the existing CSV, or wait
Report not foundWrong ID or cross-organisation accessVerify the link; switch organisation if needed
Report generation failedBackground job hit an unexpected errorInspect the error message; retry or contact support
Report file not availableFile missing despite a completed statusContact support
Failed to generate download URLTemporary storage issueRetry in a minute
Only Admin or Owner can access reportsMissing roleRequest Admin privileges
Report is still being generated. Please wait.Download before it's readyWait; the list auto-refreshes

Frequently asked

Why is the 5-minute rate limit per type, not per user?
Because the generation cost is the same regardless of who triggered it. Two admins clicking Generate on the same type within the same minute would double the load for identical output.

Can I schedule recurring exports?
Not today. Each export is on demand.

Why can't Users even see the Reports page?
Raw CSV exports can contain cross-chat data that would bypass the per-user inbox visibility. Reports are gated at both the UI and the API to keep that rule intact.

Why is my Goal CSV's column count different from last week's?
Goal exports compute their layout from the data — if new goals fired or new trackers populated in the window, the column count reflects that. Each CSV is self-describing.

Why does my Flow Responses CSV have different columns each run?
Same reason: the answer columns are whatever the matched flows captured. Editing a flow's fields, or filtering to a different set of flows, changes the columns. The ten context columns are always present and always first.

Why does my Chat export contain closed chats now?
Because an export is a lifecycle record. The resolved & closed filter is tri-state: unset means every chat, open or resolved isolates one side. Earlier versions defaulted to open chats only, like the inbox list — set the filter to open to get that behaviour back.

Why are some stage changes missing from Chat Stage History?
Rows are stages the chat actually entered. The bookkeeping rows written when a chat revives onto a new workflow (close reason Auto-closed by channel rule…) are deliberately dropped, and their close reason is shown on the real stage they ended. Every other stage change — including those on retired workflows — is there.

Can I get exports by email?
Not currently. Come back to the Reports page to download.

API

Reports is one of the partner-facing APIs. See the Reports tag on the public API docs for full schemas and example requests. In short:

  • Request an exportPOST /api/wp-crm/reports/{organisationId} with a JWT bearer token and a filter payload.
  • List exportsGET /api/wp-crm/reports/{organisationId}.
  • Download a completed exportGET /api/wp-crm/reports/{organisationId}/{reportId}/download returns a download URL with an expiry.

See Authentication for the JWT flow.

Related modules & next steps


Did this page help you?