API Reference
Analytics and Usage
💬Get free consultation

Analytics and usage

ⓘ

Who can use this feature?

  • An admin on Pro or Plus can create the calling API key. Every route needs analytics:read, except GET /intents, which needs conversations:read. Legacy unscoped keys are refused.
  • Chat-to-sale reports follow the store's plan: some fields are removed on lower plans. See Plan limits on chat-to-sale.

All routes are GET on the Public API base URL and take no body. Send X-Api-Key on every request. These are reads only; the API cannot change the plan or billing.

PathReturns
/analytics/overviewConversation totals, AI answer rate, AI reply ratings, FAQ views
/analytics/aiAI answer rate, involvement and answer topics
/analytics/conversationsConversation totals, response time, team performance, totals by channel
/analytics/salesOrders attributed to Chatty, chat-to-sale rate, total store sales
/analytics/customer-intentsWhat customers asked about, by intent and phase
/analytics/satisfactionSatisfaction survey results
/analytics/handlingAgent handling and resolution time
/analytics/campaigns/{id}Triggers, interactions and add-to-cart events for one campaign
/analytics/chat-to-sale and 8 sub-viewsChat-to-sale funnel, sales, agents and resolution
/intentsThe store's active intent labels
/subscriptionCurrent plan and AI reply quota
/subscription/usageCurrent cycle usage and billing history

Choose a date window

Every /analytics/* route accepts the same window:

ParameterMeaning
from, toInclusive days as YYYY-MM-DD. Send both, or neither. They take precedence over range.
rangetoday, yesterday, last-3-days, last-7-days, last-30-days (default), last-3-months, this-month or last-month
  • A window is 1–90 days. Longer windows, or to before from, return 400 VALIDATION_FAILED.
  • Days are counted in the store's time zone, or UTC if none is set.
  • Each report also compares with the window just before it: the same number of days, or the previous month for this-month and last-month.
  • Money is in the store's currency. Analytics responses do not include a currency code.
curl 'https://app.chatty.net/v1/analytics/overview?from=2026-10-01&to=2026-10-21' \
  -H 'X-Api-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

Response shape

Analytics routes return {"success":true,"data":{...}}. data.updatedAt is when the report was computed. Reports are cached for up to an hour, so a new conversation can take that long to appear.

!

Check success as well as the status. An unexpected failure while building a report returns HTTP 200 with {"success":false,"error":"..."}. Validation and lookup errors use the usual error.code.

/subscription, /subscription/usage and /intents return {"data":...} without success or updatedAt, and are not cached.

Overview, AI, conversations and sales

These four reports wrap each figure as {current, previous, unit, description}, where previous is the comparison window. They also return a window object:

{
  "success": true,
  "data": {
    "window": {
      "from": "2026-09-24T14:22:00.000Z",
      "to": "2026-10-22T14:22:00.000Z",
      "timeZone": "America/New_York",
      "unit": "UTC instants for calendar dates in the shop time zone",
      "description": "The time window applied to every analytics value in this response."
    },
    "conversations": {
      "current": {"resolutionRate": 0.82, "totalConversations": 410, "totalHumanConversations": 150, "totalHumanResolvedConversations": 120},
      "previous": {"resolutionRate": 0.8, "totalConversations": 380},
      "unit": "conversations and percent",
      "description": "Conversation totals and resolution rate for the requested time window."
    },
    "aiAnswerRate": {
      "current": {"totalCount": 900, "successCount": 760, "successRate": 0.8444},
      "previous": {"totalCount": 850, "successCount": 700, "successRate": 0.8235},
      "unit": "answers and proportion from 0 to 1",
      "description": "AI knowledge-answer attempts, successful answers, and answer rate for the requested time window."
    },
    "updatedAt": "2026-10-22T14:22:05.123Z"
  }
}

The example is an excerpt of /analytics/overview, which also returns satisfaction and faqViews. Chart arrays are left out.

RouteFigures
/analytics/overviewconversations, aiAnswerRate, satisfaction, faqViews
/analytics/aianswerRate, involvement, topics
/analytics/conversationsoverview, responseTime, teamPerformance, byChannel
/analytics/salesattributedOrders, chatToSale, storeSales
  • resolutionRate and successRate are proportions from 0 to 1. teamPerformance.value[].resolvedRate is a whole percent from 0 to 100.
  • satisfaction in the overview counts AI reply ratings (great, good, bad), not survey answers. Survey results are on /analytics/satisfaction.
  • topics.value lists AI answer topics, most frequent first, with total and rate.
  • byChannel keys are online store, email, facebook, instagram and whatsapp.
  • attributedOrders counts orders assisted by Chatty. storeSales covers every order in the store.

Customer intents

/analytics/customer-intents reports which intents Chatty detected in customer messages. Optional filters, each a comma-separated list:

ParameterValues
phasespre, purchase, post, cross, junk, customer_type, none
intentsIntent slugs from GET /intents. Unknown slugs are ignored.
{
  "success": true,
  "data": {
    "rows": [{"slug": "product_info", "name": "Product information", "phase": "pre", "total": 120, "compareTotal": 100, "percentage": 24.5}],
    "junkRows": [{"slug": "marketing_spam", "name": "Marketing spam", "total": 8, "compareTotal": 5, "percentage": 1.6}],
    "phases": [{"phase": "pre", "total": 300, "compareTotal": 280, "messages": 250, "compareMessages": 240}],
    "labelledMessages": 490,
    "compareLabelledMessages": 450,
    "noneMessages": 60,
    "compareNoneMessages": 55,
    "requestMessages": 480,
    "compareRequestMessages": 440,
    "updatedAt": "2026-10-22T14:22:05.123Z"
  }
}

rows lists intents most frequent first; junk intents go to junkRows. percentage is the share of labelled messages, with one decimal. Fields starting with compare are for the comparison window.

GET /intents returns the store's active intent labels, so you can show names for the slugs:

{"data":[{"slug":"product_info","name":"Product information","phase":"pre"},{"slug":"order_status","name":"Order status","phase":"post"}]}

Satisfaction, handling and campaigns

These reports return sourceData for the requested window and compareData for the comparison window.

RouteFields
/analytics/satisfactionsatisfiedCount (rating 4 or 5), submittedCount, surveyCount, ratedSurveyCount, totalPoints, ratingCounts (counts for ratings 1 to 5)
/analytics/handlingavgAgentHandlingTime, avgResolutionTime, and chart data for the requested window
/analytics/campaigns/{id}triggered, interacted, add_to_cart, always present
{"success":true,"data":{"sourceData":{"triggered":120,"interacted":30,"add_to_cart":7},"compareData":{"triggered":100,"interacted":25,"add_to_cart":4},"updatedAt":"2026-10-22T14:22:05.123Z"}}

A campaign ID from another store returns 404 NOT_FOUND with Campaign not found. Reading satisfaction through the API does not mark survey results as seen in the admin.

Chat-to-sale

PathReturns
/analytics/chat-to-saleHeadline figures; same data as /kpi
/analytics/chat-to-sale/kpiConversations, converted conversations, orders, revenue, resolution, satisfaction, store totals
/analytics/chat-to-sale/salesFunnel by stage and topic, a chart, top products
/analytics/chat-to-sale/sales/sparkThe funnel for the last 4 windows of the same length, oldest first
/analytics/chat-to-sale/agentsChats and revenue per team member
/analytics/chat-to-sale/resolutionConversations by how they were resolved
/analytics/chat-to-sale/agent-tablePer-member orders, resolution rate and first response time
/analytics/chat-to-sale/phase-mixPer-member split of conversations into pre-sale, purchase and post-sale
/analytics/chat-to-sale/topicsEach member's top two topics

Most figures are split into ai, human and both. ai means only the AI answered; human means a team member replied. both is the distinct total, so ai plus human can be less than both. Deleted and spam conversations are excluded.

{
  "success": true,
  "data": {
    "current": {
      "extensives": {
        "conversations": {"ai": 200, "human": 150, "both": 410},
        "converted": {"ai": 12, "human": 8, "both": 20},
        "orders": {"ai": 13, "human": 9, "both": 22},
        "revenue": {"ai": 900.0, "human": 640.5, "both": 1540.5}
      },
      "resolution": {"auto": 180, "manual": 120},
      "csat": {"satisfied": {"ai": 30, "human": 20, "both": 50}, "submitted": {"ai": 40, "human": 30, "both": 70}},
      "storeRevenue": 15400.0,
      "storeOrders": 220
    },
    "compare": {},
    "updatedAt": "2026-10-22T14:22:05.123Z"
  }
}

The example is an excerpt of /kpi; compare has the same keys for the comparison window. storeRevenue and storeOrders cover every store order.

  • /sales funnel stages are cumulative: Pre is every conversation, Purchase has an assisted order, Post has a fulfilled order. Refunds are taken out of revenue. The chart is hourly for a one-day window, daily otherwise.
  • /resolution returns five states in this order: aiResolved, agentResolved, mixResolved, notReplyResolved and open, each with count and a share from 0 to 1.
  • /agents credits revenue to the last assigned member. Members no longer in the store are left out.
  • /agent-table sorts members by chats. frt is the median first response time; null means the member never replied.

Plan limits on chat-to-sale

Chatty removes fields the store's plan does not include. There is no error: the field is missing or empty. /kpi, /agents, /resolution and /phase-mix are never limited.

PlanRemoved
FreeEverything listed for Basic, plus orders and revenue in the Purchase and Post stages of /sales and /sales/spark
BasicTopic detail (topics keep only volume), topicProducts, product prices and revenue in topProducts, operations figures in /agent-table, and all of /topics ({"agents":[]})
Pro, PlusNothing

An upgrade applies on the next request, even to cached reports.

Subscription and usage

{
  "data": {
    "plan": {"id": "pro", "name": "Pro", "interval": "monthly", "isOnTrial": false, "trialEndsAt": null},
    "aiQuota": {"used": 420, "limit": 1000, "remaining": 580, "unit": "AI replies in the current billing cycle"}
  }
}

GET /subscription returns the plan and the AI reply quota for the current billing cycle. remaining never goes below 0. GET /subscription/usage returns currentCycle (startsAt, used, limit, bonusUsed, bonusLimit) and history.value, one row per billing period with periodStart, periodEnd, plan, used, limit, amount and currency. Missing values are null. Both examples are excerpts.

Errors

HTTPCodeMeaning
200success: falseA report failed to build. Retry later.
400VALIDATION_FAILEDOnly one of from/to, an unknown range, a window outside 1–90 days, or an invalid date.
400INVALID_API_VERSIONInvalid X-Api-Version date.
401UNAUTHENTICATED / INVALID_API_KEYMissing, unknown or revoked key.
403FORBIDDENMissing scope, or a legacy key.
404NOT_FOUNDStore or campaign not found.
429RATE_LIMITEDShared Public API limit reached.

On MCP, get_shop_analytics reads the intent, satisfaction, campaign, handling and chat-to-sale reports with an API key or OAuth, with the same plan limits. list_intents reads intent labels with an API key. The older tools, such as get_analytics_overview and get_subscription, read the other routes. See the MCP tool reference.