draw_user_growth
ChatGPTRender an interactive line chart of unique visitors and page views over time for a host you own. Use when asked to chart, graph, draw, or visualize growth or traffic for a subdomain. The host must be a verified origin of your project.
get_acquisition
ChatGPTAnswer 'what's my biggest signup source?'. Returns new customers grouped by their TRUE first-touch source — the referrer/utm on their earliest anonymous visit (e.g. chatgpt.com, google), carried forward to the customer at signup, NOT the signup-moment referrer. Counts only, highest-first. Forward-only: coverage.state='not_instrumented' means no signups attributed since first-touch tracking shipped, NOT zero signups historically.
get_customer
ChatGPTCross-match one customer across every layer Crossdeck joins by identity. Returns what they pay (monthly cents), their active entitlement count, and their database read-cost — in one view. Use for 'how much does this user pay and what do they cost us?'. Returns a no-match result (not an error) if no customer resolves.
get_customers
ChatGPTGet an app's customer census: the PAYING-customer count (measured from the maintained revenue ledger), plus total customers / active people where instrumented. This is the canonical 'how many customers/users does this app have?' answer — never estimate it from other tools' counts. Fields that aren't instrumented come back not_instrumented with an explanation (a blind spot), never a misleading 0 — check data.coverage per field.
get_error_affected_users
ChatGPTFor one error, get the PAYING customers it actually hit — the row-level moat answer: which paying customer broke, and how much are they worth. Returns a list sorted by revenue at risk, each row with the customer's HUMAN identity (email/name, resolved best-first), their minted monthly revenue (USD cents, reconciles to Revenue — never re-summed from subscriptions), and when they last hit it. The owner's OWN customers, surfaced by name/email. Use when you need the actual customers, not just counts.
get_error_impact
ChatGPTGet one error's blast radius joined to identity. Returns distinct users affected, how many of those are PAYING customers, and the error's type, status, occurrence count, and first/last-seen — counts only. Use to size an error's impact. For the NAMED paying users behind the counts, call get_error_affected_users.
get_host_analytics
ChatGPTGet headless web analytics for one host/subdomain the app owns (e.g. a tenant's subdomain). Returns page views and unique visitors with totals, from the maintained rollup ledger. The host MUST be a verified origin of the project, or the request is rejected (403). Use for per-tenant traffic questions.
get_host_top_pages
ChatGPTGet the top pages for one host the app owns, ranked highest-first. Returns rows of { page, views } from the rollup ledger. The host must belong to the selected app. Use for 'most-viewed pages on this subdomain'.
get_portfolio
ChatGPTGet a coverage map of the whole workspace: for each app, which surfaces are instrumented (revenue, read-cost, analytics, customer census) vs a blind spot. Load this FIRST in a portfolio conversation — every later number is then interpreted against a known map, so a not-instrumented surface is never mistaken for a zero. Read-only; takes no arguments.
get_read_cost
ChatGPTGet an app's database read-cost, split into per-user reads vs un-attributed overhead, with a breakdown by operation. Per-user attribution works because Crossdeck joins read-cost to the SDK's identity. Returns the per-user-vs-overhead totals and the by-operation breakdown. Use for 'what's driving our database reads' or 'which operation costs the most'.
get_revenue
ChatGPTGet an app's revenue from its maintained ledgers (point-reads, never a scan). Returns TWO distinct revenue truths, each self-describing: current.mrrCents = recurring SUBSCRIPTION MRR (Stripe/Apple/Google), plus current.recognisedCashThisMonthCents = ALL money collected this calendar month INCLUDING one-off / consumable / cash charges (with a recurring-vs-oneOff split). This matters: a one-off or consumable business has $0 recurring MRR but real monthly revenue — read recognisedCashThisMonthCents and lead with it, NEVER report '$0 revenue' when it is positive. Also returns the paying-customer count and per-rail split. With granularity='day' adds a daily MRR series (data.series) for 'is my MRR up/down over time' / trend questions. A null field is a blind spot for THAT metric (read its semantics), not $0.
get_revenue_averages
ChatGPTGet an app's revenue AVERAGES from maintained ledgers (point-reads, no scan): ARPU (avg MRR per paying customer) and average lifetime value per paying customer. Lifetime value = combinedLifetimeValueCents (active-subscription annualized run-rate + banked one-offs) — RECONCILES to the dashboard's per-customer LTV, and is NOT recognisedCashToDateCents (actual cash banked, returned separately). Answers 'average lifetime value per user' / 'what's my ARPU'. Averages ACROSS THE PAYING BASE — NOT one customer's pay (use get_customer for one). 'user'=paying customer; a per-all-users average is not_instrumented. not_instrumented when no rail connected — not $0.
list_customers_ranked
ChatGPTPivot the whole customer book by an axis Crossdeck owns and rank it — the leaderboard. by='read_cost' (metered reads), by='mrr' (monthly revenue), by='ltv' (lifetime value — net recognised cash actually paid, succeeded charges minus refunds; the SAME charge ledger the dashboard shows as 'Lifetime'), by='total_spend' (the SAME banked-cash figure as ltv — recognised cash to date, succeeded charges net of refunds), by='errors' (how many DISTINCT issues the customer has hit — breadth, not occurrences), by='activity' (lifetime event volume — total engagement; use 'recency' for 'hot right now'), by='tenure' (when they became a customer), by='recency' (when last active — use order='asc' for the CHURN-RISK queue of dormant customers), by='cost_ratio' (reads ÷ revenue: a RAW-NUMBER efficiency ratio, 'reads generated per $1 of MRR' — who costs most relative to what they pay; paying customers only; Crossdeck never invents a $/read cost). order='desc' (default, highest-first) or 'asc' (lowest-first — churn risk, longest-standing, best efficiency). THE RICH ROW: every row carries EVERY metric at once (the customer's HUMAN identity — email/name, resolved best-first — plus mrrCents, ltvCents, netCashCents, readCost, createdAtMs, lastSeenMs, readsPerRevenue, currency, paying) regardless of the ranking axis — the cross is pre-done, so you read the row instead of re-joining across tools. Identity is the owner's OWN customers, surfaced by email/name (the same the dashboard shows), never a bare UID. mrrCents is the ONE minted MRR that reconciles to the Revenue page — never re-summed from subscriptions. Use for 'most valuable' (by='ltv'), 'paid me the most' (by='total_spend'), 'top by revenue' (by='mrr'), 'most expensive in reads' (by='read_cost'), 'about to churn' (by='recency', order='asc'), 'oldest' (by='tenure', order='asc'), 'worst read-efficiency' (by='cost_ratio').
list_projects
ChatGPTList every app (project) in your Crossdeck portfolio that this connector can read — the same set your Pulse dashboard shows. Returns an array of { id, name } per app. Call this FIRST: every other tool needs a project id. Read-only; takes no arguments.
open_moat_dashboard
ChatGPTRender ONE customer's cross-layer dashboard — what they pay, their active entitlements, and their database read-cost, joined by identity. Requires project and customerId (any single id you have for the customer — a Crossdeck customer id, your own user id, an anonymous id, or a rail id; Crossdeck resolves it through the identity graph). This is the moat, rendered.