Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: HellouOne AI Classifications API
version: 1.0.0
description: 'The HellouOne REST API: everything the dashboard does, available to your
own systems — CRMs, bots, BI tools and back-office automation.'
termsOfService: https://hellou.ai/en/legal/terms/
contact:
name: HellouOne support
email: support@hellou.ai
servers:
- url: https://one.hellou.ai
description: HellouOne cloud
security:
- userApiKey: []
tags:
- name: AI Classifications
paths:
/api/v2/accounts/{account_id}/reports/sentiment:
parameters:
- $ref: '#/components/parameters/account_id'
get:
tags:
- AI Classifications
operationId: getSentimentReport
summary: Get the sentiment report
description: 'Customer sentiment over a date range, one conversation at a time: how many
closed negative, net sentiment, how many that opened negative were recovered
(and by whom), the opening-to-closing matrix, frustration by inbox, risk
flags with the time to a person, sentiment against CSAT and speed, and the
open conversations that need attention now. A conversation counts in the
range when its latest reading falls in it. Sentiment is recorded only while
it runs in `enforce`, so an account in shadow reports zeros. Counts and codes
only: never message text.
**Administrators only.**
**Requires feature:** `ai_decisions`'
x-required-feature: ai_decisions
parameters:
- in: query
name: channel
schema:
type: string
enum:
- chat
- voice
description: '`voice` keeps only phone calls to AI lines, `chat` everything else. Omit for both.'
- in: query
name: since
schema:
type: string
description: Unix timestamp where the range starts.
- in: query
name: until
schema:
type: string
description: Unix timestamp where the range ends.
- in: query
name: group_by
schema:
type: string
enum:
- day
- week
- month
- year
description: Period of each `timeseries` point. Defaults to `day`.
- in: query
name: timezone_offset
schema:
type: number
description: Viewer's offset from UTC in hours, so periods start at local midnight.
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/sentiment_report'
'401':
$ref: '#/components/responses/unauthorized'
'403':
$ref: '#/components/responses/forbidden'
/api/v2/accounts/{account_id}/reports/sentiment_conversations:
parameters:
- $ref: '#/components/parameters/account_id'
get:
tags:
- AI Classifications
operationId: listSentimentConversations
summary: List conversations by sentiment
description: 'The conversations behind a cell of the sentiment report: filter by opening
and closing sentiment, a risk flag, worst frustration, who handled it, an
agent, an inbox or a team. Same range rules as the report; at most 50,
latest first.
**Administrators only.**
**Requires feature:** `ai_decisions`'
x-required-feature: ai_decisions
parameters:
- in: query
name: channel
schema:
type: string
enum:
- chat
- voice
description: '`voice` keeps only phone calls to AI lines, `chat` everything else. Omit for both.'
- in: query
name: since
schema:
type: string
description: Unix timestamp where the range starts.
- in: query
name: until
schema:
type: string
description: Unix timestamp where the range ends.
- in: query
name: opening
schema:
type: string
enum:
- negative
- neutral
- positive
description: Opening sentiment. With `closing`, only conversations read at least twice.
- in: query
name: closing
schema:
type: string
enum:
- negative
- neutral
- positive
- unknown
description: Closing (latest) sentiment.
- in: query
name: flag
schema:
type: string
enum:
- wants_human
- churn_risk
- abuse
description: Only conversations with this flag raised.
- in: query
name: frustration
schema:
type: string
enum:
- calm
- annoyed
- frustrated
- hostile
description: Worst frustration reached.
- in: query
name: handler
schema:
type: string
enum:
- agent
- bot
- unassigned
description: Who handled it at the last burst.
- in: query
name: assignee_id
schema:
type: integer
description: The agent handling it at the last burst.
- in: query
name: inbox_id
schema:
type: integer
- in: query
name: team_id
schema:
type: integer
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/sentiment_conversations'
'401':
$ref: '#/components/responses/unauthorized'
'403':
$ref: '#/components/responses/forbidden'
/api/v1/accounts/{account_id}/ai_decisions/summary:
parameters:
- $ref: '#/components/parameters/account_id'
get:
tags:
- AI Classifications
operationId: getAiDecisionsSummary
summary: Get the AI classifications summary
description: 'AI classifications are short automatic checks of a customer message or a lead
(smart routing in AI agents, Lead Ads qualification). This returns which use
cases are on and at which mode, how many classifications ran within a date
range by use case and outcome, and the billing-period meter. It returns counts
and codes only: never message text, answers or cost.
**Administrators only.**
**Requires feature:** `ai_decisions`'
x-required-feature: ai_decisions
parameters:
- name: since
in: query
description: First day (`YYYY-MM-DD`, inclusive). Defaults to 30 days before `until`; an unparseable date also falls back to the default.
schema:
type: string
format: date
- name: until
in: query
description: Last day (`YYYY-MM-DD`, inclusive). Defaults to today; an unparseable date also falls back to the default.
schema:
type: string
format: date
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/ai_decisions_summary'
'401':
$ref: '#/components/responses/unauthorized'
'403':
$ref: '#/components/responses/forbidden'
components:
schemas:
sentiment_report_flag:
type: object
properties:
count:
type: integer
rate:
type:
- integer
- 'null'
description: Percentage of all conversations read.
sentiment_report_rows:
type: array
items:
type: object
properties:
id:
type:
- integer
- 'null'
name:
type:
- string
- 'null'
handler:
type: string
enum:
- agent
- bot
- unassigned
description: Agents only. `bot` is the AI agent, `unassigned` nobody, credited at the conversation's last burst.
conversations:
type: integer
description: Conversations with a known closing sentiment.
unread:
type: integer
description: Conversations whose sentiment could not be read; left out of every rate.
ending_positive:
type: integer
ending_neutral:
type: integer
ending_negative:
type: integer
ending_negative_rate:
type:
- integer
- 'null'
description: Conversations closing negative, as a percentage of `conversations`.
net_sentiment:
type:
- integer
- 'null'
description: Percentage closing positive minus percentage closing negative, from -100 to 100.
opened_negative:
type: integer
description: Conversations that opened negative (inherited), among those read at least twice.
recovered:
type: integer
description: Of those, conversations that closed neutral or positive.
recovery_rate:
type:
- integer
- 'null'
description: Recovered as a percentage of opened negative.
opened_other:
type: integer
description: Conversations that opened neutral or positive, among those read at least twice.
worsened:
type: integer
description: Of those, conversations that closed negative.
worsened_rate:
type:
- integer
- 'null'
description: Worsened as a percentage of opened neutral or positive.
low_sample:
type: boolean
description: True under `min_sample` conversations; do not rank on it.
sentiment_conversations:
type: object
properties:
total:
type: integer
description: Conversations matching the filters (the list shows at most 50).
conversations:
type: array
items:
type: object
properties:
id:
type: integer
description: The conversation's display ID.
contact_name:
type:
- string
- 'null'
inbox_name:
type:
- string
- 'null'
assignee_name:
type:
- string
- 'null'
status:
type: string
handler:
type: string
enum:
- agent
- bot
- unassigned
opening_sentiment:
type: string
latest_sentiment:
type: string
worst_frustration:
type:
- string
- 'null'
bursts:
type: integer
description: Times the customer's sentiment was read.
wants_human:
type: boolean
churn_risk:
type: boolean
abuse:
type: boolean
latest_at:
type: integer
sentiment_report:
type: object
properties:
summary:
description: The same counts and rates as a breakdown row, for the whole account, plus `attention_now`.
allOf:
- $ref: '#/components/schemas/sentiment_report_rows/items'
- type: object
properties:
attention_now:
type: integer
description: Open or pending conversations that need attention right now.
timeseries:
type: array
description: Closing sentiment per period (by the time of the conversation's latest reading).
items:
type: object
properties:
timestamp:
type: integer
description: Start of the period (Unix timestamp), at midnight in the viewer's time zone.
positive:
type: integer
neutral:
type: integer
negative:
type: integer
matrix:
type: object
description: Opening sentiment to closing sentiment, as counts, for conversations read at least twice with both ends known.
additionalProperties:
type: object
additionalProperties:
type: integer
breakdown:
type: object
properties:
agents:
$ref: '#/components/schemas/sentiment_report_rows'
inboxes:
$ref: '#/components/schemas/sentiment_report_rows'
teams:
$ref: '#/components/schemas/sentiment_report_rows'
frustration:
type: array
description: Worst frustration reached per conversation, by inbox.
items:
type: object
properties:
id:
type: integer
name:
type:
- string
- 'null'
total:
type: integer
calm:
type: integer
annoyed:
type: integer
frustrated:
type: integer
hostile:
type: integer
flags:
type: object
description: Conversations where the customer asked for a person, was at risk of leaving or used abusive language, over all conversations read.
properties:
total:
type: integer
wants_human:
$ref: '#/components/schemas/sentiment_report_flag'
churn_risk:
$ref: '#/components/schemas/sentiment_report_flag'
abuse:
$ref: '#/components/schemas/sentiment_report_flag'
wants_human_response:
type: object
description: From the first message asking for a person to the next public reply by an agent.
properties:
median_minutes:
type:
- integer
- 'null'
answered:
type: integer
waiting:
type: integer
description: Still without a reply from an agent.
quality:
type: object
description: Average CSAT by closing sentiment, and median first response and resolution time (seconds) by opening sentiment.
properties:
csat_by_closing:
$ref: '#/components/schemas/sentiment_report_by_sentiment'
first_response_by_opening:
$ref: '#/components/schemas/sentiment_report_by_sentiment'
resolution_by_opening:
$ref: '#/components/schemas/sentiment_report_by_sentiment'
attention:
type: array
description: Open or pending conversations whose sentiment needs attention, most recent first (at most 50).
items:
type: object
properties:
id:
type: integer
description: The conversation's display ID.
contact_name:
type:
- string
- 'null'
inbox_name:
type:
- string
- 'null'
assignee_name:
type:
- string
- 'null'
team_name:
type:
- string
- 'null'
priority:
type:
- string
- 'null'
sentiment:
type:
- string
- 'null'
description: negative, neutral, positive or unknown.
frustration:
type:
- string
- 'null'
description: calm, annoyed, frustrated or hostile.
urgency:
type:
- string
- 'null'
description: low, medium or high.
trend:
type:
- string
- 'null'
description: improving, flat, worsening or unknown.
last_activity_at:
type:
- integer
- 'null'
min_sample:
type: integer
description: Below this many conversations a row is flagged `low_sample`.
ai_decisions_summary:
type: object
description: 'The account''s AI classifications. A use case runs at `effective`, the lower of
its own mode and the platform mode: `off` sends nothing, `shadow` classifies
and records without acting, `review` labels for a person to check, `enforce`
acts.
'
properties:
since:
type: string
format: date
description: First day of the range.
until:
type: string
format: date
description: Last day of the range.
available:
type: boolean
description: Whether classifications can run for this account at all (feature on and the platform configured).
platform_mode:
type: string
enum:
- 'off'
- shadow
- enforce
description: The platform-wide ceiling every use case is capped at.
use_cases:
type: object
description: Account-level use cases by key (`fb_lead`, `campaign_reply`, `sentiment`, `consent_intent`, `inbox_routing`).
additionalProperties:
$ref: '#/components/schemas/ai_decisions_mode'
bots:
type: array
description: AI agents with smart routing set to anything but `off`.
items:
type: object
properties:
id:
type: integer
description: The agent bot id.
name:
type: string
description: The agent bot name.
mode:
type: string
enum:
- 'off'
- shadow
- review
- enforce
description: The mode set on the bot.
effective:
type: string
enum:
- 'off'
- shadow
- review
- enforce
description: The mode it runs at.
by_purpose:
type: object
description: Classifications in the range by use case (`bot_gate`, `fb_lead_intake`, …). Use cases with none are omitted.
additionalProperties:
type: object
properties:
ok:
type: integer
description: Answered.
failed:
type: integer
description: Not answered (the service was unavailable or refused); nothing was decided.
skipped:
type: integer
description: Not asked (no text, a daily cap, or the service paused).
acted:
type: integer
description: Answered and acted on (only possible in `review` or `enforce`).
reasons:
type: object
description: Count of failed and skipped classifications per reason code.
additionalProperties:
type: integer
bands:
type: object
description: For each question with thresholds, how many answered classifications crossed the bar to act (`act`) or to ask a person (`ask`). The rest of `ok` crossed neither.
additionalProperties:
type: object
properties:
act:
type: integer
ask:
type: integer
usage:
type: object
description: The plan meter for the current billing period. Classifications are never refused at the limit.
properties:
consumed:
type:
- integer
- 'null'
description: Answered classifications this period, editor previews excluded. `null` without a billing period.
allowed:
type:
- integer
- 'null'
description: The plan's allowance, or `null` when it is not metered.
error_message:
type: object
description: An error with a human-readable message.
properties:
error:
type: string
description: What went wrong.
reason:
type: string
description: Machine-readable cause, when there is one (for example `feature_disabled`).
required:
- error
ai_decisions_mode:
type: object
properties:
mode:
type: string
enum:
- 'off'
- shadow
- review
- enforce
description: The mode set for the account.
effective:
type: string
enum:
- 'off'
- shadow
- review
- enforce
description: The mode it runs at, capped by `platform_mode`.
sentiment_report_by_sentiment:
type: object
description: One value per sentiment, with how many conversations it is over.
additionalProperties:
type: object
properties:
value:
type:
- number
- 'null'
n:
type: integer
responses:
unauthorized:
description: Missing or invalid `api_access_token`, or a bot token on an endpoint bots cannot use.
content:
application/json:
schema:
$ref: '#/components/schemas/error_message'
forbidden:
description: 'Not allowed: the user''s role does not permit it, the feature is not enabled
for the account (`reason: feature_disabled`), or the account is read-only.
'
content:
application/json:
schema:
$ref: '#/components/schemas/error_message'
parameters:
account_id:
in: path
name: account_id
required: true
description: The numeric ID of the account
schema:
type: integer
securitySchemes:
userApiKey:
type: apiKey
in: header
name: api_access_token
description: 'A user''s access token, from **Profile settings → Access token** in the dashboard.
Requests act with that user''s role: administrators reach everything in their
account, agents only what their role and visibility settings allow.
'
agentBotApiKey:
type: apiKey
in: header
name: api_access_token
description: 'An agent bot''s access token, shown to administrators on the bot''s settings page.
Bot tokens reach a limited set of conversation and message endpoints.
'
platformAppApiKey:
type: apiKey
in: header
name: api_access_token
description: 'A platform app token, issued by the installation operator. Used to provision
accounts, users, account memberships and agent bots.
'
connectorInvokeToken:
type: http
scheme: bearer
description: 'A connector''s invoke token (`hci_…`), sent as `Authorization: Bearer <token>`.
Each connector install has its own; it is rotated whenever the connector is
reconnected or disconnected, so a stale copy stops working.
'
x-tagGroups:
- name: Guides
tags:
- Introduction
- Authentication
- Errors
- Pagination
- Rate limits
- Webhook events
- name: Webhook payloads
tags:
- Event payloads
- name: Platform
tags:
- Accounts
- Account Users
- AgentBots
- Users
- name: Application
tags:
- Account AgentBots
- Agents
- Automation Rule
- Campaigns
- Canned Responses
- Contacts
- Contact Labels
- Conversation Assignment
- Conversation Labels
- Conversations
- Custom Attributes
- Custom Filters
- Help Center
- Inboxes
- Integrations
- Macros
- Messages
- Profile
- Reports
- Security Settings
- Teams
- Webhooks
- name: Business tools
tags:
- AI Classifications
- Assignment Settings
- Calls
- AI Phone Lines
- Connectors
- ElevenLabs Integration
- Facebook Marketing
- HellouAI Integration
- Knowledge Base
- Marketing Consent
- Plan Upgrades
- Voice Campaigns
- WhatsApp Campaigns
- WhatsApp Flows
- WhatsApp Templates
- name: Client
tags:
- Inbox API
- Contacts API
- Conversations API
- Messages API
- name: Others
tags:
- CSAT Survey Page