How the V2 fields are designed, and how legacy statements/search fields map to Listen API V2.
This page explains how the Listen API V2 fields are designed, and maps every field of the legacy statements/search endpoint to V2. For the migration steps, see Migrating from Legacy API to Listen API V2.
How the V2 fields are designed
V2 does not copy the legacy field list one to one. It follows four design principles; once you know them, most of the mappings below are predictable.
| Principle | Legacy API (V1) | Listen API V2 |
|---|---|---|
| Structured objects instead of flat fields | 62 top-level fields, plus 24 counters in metadata | Related data grouped into objects: author, source, content, engagementMetrics, location, discussion, context |
| Human-readable dates | Milliseconds since 1970 (1761125400000) or local-time strings (2025-12-01 00:00:00.000 CET) | ISO 8601 in UTC (2026-10-20T09:12:15Z), in requests and responses |
| Enumeration values that mirror the Listen app | Internal codes: POSITIVE, st / ar, microblog, m / f / u | The labels you see in the app: Positive, Post / Article, X, Male / Female |
| Consistent naming | Mixed names: likes, retweets, createdAt | Counters end with Count (likeCount), timestamps end with At (publishedAt, collectedAt) |
Structured objects instead of flat fields
The legacy Statement put everything on one level, so author, source, content and metrics fields were mixed together. V2 groups them by what they describe:
author: who wrote the mention (ID, name, avatar, gender, follower and fan counts)source: where it was published (platform type, social channel such as a Facebook page, and the mention URL)content: what it says (title, text, language, sentiment, review rating)engagementMetrics: how people reacted (influence score, engagement rate, counters)location: where it comes from (country, region, city, coordinates)discussionandcontext: the thread it belongs to and its parent
Platform-specific values have their own sub-objects, such as engagementMetrics.sourceMetrics.facebook for reactions. A sub-object that does not apply to a mention is null, instead of adding fields that are empty for most mentions.
The same Facebook post in both APIs (fields shortened):
Legacy API (V1)
{
"author": "Sarah Johnson",
"authorId": "1234567890",
"sex": "f",
"createdAt": 1761125400000,
"sentiment": "POSITIVE",
"group": "facebook",
"sourceName": "Tech Reviews Hub",
"metadata": { "likes": 28, "followers": 245 }
}Listen API V2
{
"author": {
"id": "1234567890",
"name": "Sarah Johnson",
"gender": "Female",
"influenceMetrics": { "followerCount": 245 }
},
"publishedAt": "2025-10-22T09:30:00Z",
"content": { "sentiment": "Positive" },
"source": { "type": "Facebook", "socialChannel": { "name": "Tech Reviews Hub" } },
"engagementMetrics": { "sourceMetrics": { "common": { "likeCount": 28 } } }
}Human-readable dates
Every date in V2, in requests and in responses, is an ISO 8601 string in UTC, such as 2026-10-20T09:12:15Z. You can read it in logs and pass it to any date library without knowing a time zone or a timestamp unit.
Enumeration values that mirror the Listen app
Enumeration values use the same names as the Listen app UI: sentiment is Positive, Negative, Neutral or Unspecified; sources are Facebook, X, Reddit and so on. What you see in the app is what you send in filters and get back in responses.
Enumerations can growNew values may be added to enumerations such as
SourceTypeandMentionTypewithout a major version change. Make sure your integration tolerates values it does not recognize.
Request fields: legacy → V2
V2 groups filters under filters and uses ISO 8601 UTC dates and capitalized enum values.
| Legacy field | V2 equivalent | Notes |
|---|---|---|
topicId | projectId in the path | Topics are now called projects. List them with GET /projects. |
threadId | discussionId in the path of /discussions/{discussionId}/… | Thread IDs changed format; take discussion.id from a V2 mention. |
from, to | filters.publishedAt.from, .to | ISO 8601 UTC only (no ms timestamps, no time zone names). to is exclusive. |
indexedFrom, indexedTo | filters.collectedAt.from, .to | Not available on live streams. |
sentiment (POSITIVE, …) | filters.content.sentiment (Positive, Negative, Neutral, Unspecified) | |
language (["en"]) | filters.content.language ([{"code": "en"}]) | Each code is an object. Dialects (e.g. de-at) are included automatically. |
country (["pl"]) | filters.location.country ([{"code": "pl"}]) | Each code is an object. |
group | filters.source.type | blog→Blogs, forum→Forums, portal→Websites, facebook→Facebook, instagram→Instagram, microblog→X, video→Video, review→Reviews, tiktok→TikTok, reddit→Reddit. google has no equivalent. |
type: ar | filters.type: ["Article"] | |
type: st | filters.type: ["Post", "Comment", "Share", "PrivateMessage"] | V2 distinguishes posts from comments. Omit type for everything (legacy all). |
textFilter | filters.content.query | Listen Query Language: keywords, "phrases", AND/OR/NOT, suffix *. Matches text and title. Max 500 characters. |
sort + order | sortType | createdAt → PublishedAtAscending/Descending. New: CollectedAt*, InfluenceScoreDescending, EngagementRateDescending, LikeCountDescending, ShareCountDescending, FollowerCountDescending. Sorting by sentiment is gone. |
page, rows | Streams: none, use limit to cap the count. Search: cursor query parameter, 25 per page. | |
withMetadata | Always on | Engagement metrics are always in engagementMetrics. |
author, domain, sex, continent, region, city, includeIgnored | No equivalent | Narrow the project query instead, or filter on the response fields. |
Response fields: legacy Statement → V2 Mention
Statement → V2 MentionV2 returns a nested Mention object. Timestamps are ISO 8601 UTC strings instead of milliseconds, and empty values are null or absent.
| Legacy field | V2 field |
|---|---|
id | id (new format). Old ID: deprecatedV1Fields.id |
threadId | discussion.id (new format) |
initialAuthor | discussion.author.name |
type, isComment, private, isRetweet | type: Post, Comment, Article, PrivateMessage, Share (retweets are Share) |
createdAt (ms) | publishedAt |
| — | collectedAt (when SentiOne found the mention) |
title | content.title |
text | content.text |
language | content.language.code (dialects such as de-at become de) |
sentiment (POSITIVE, …, UNKNOWN) | content.sentiment (Positive, …, Unspecified) |
url | source.mentionUrl |
group | source.type (mapping as in the request table) |
sourceName, sourceId | source.socialChannel.name, .id |
author, authorId | author.name, author.id |
sex (m, f, u) | author.gender (Male, Female, Unspecified) |
media.avatar | author.avatar.url |
metadata.followers, metadata.fans | author.influenceMetrics.followerCount, .fanCount |
media.images, media.video | attachments[] with type Image / Video / Other |
country | location.country.code |
latitude, longitude | location.coordinates.latitude, .longitude |
| — | location.region, location.city |
influenceScore | engagementMetrics.influenceScore (1–10) |
engagementRate | engagementMetrics.engagementRate |
metadata.likes, shares, comments, views | engagementMetrics.sourceMetrics.common.likeCount, shareCount, commentCount, viewCount |
metadata.reactions.* | engagementMetrics.sourceMetrics.facebook.*Count (Facebook only) |
metadata.retweets, favourites | engagementMetrics.sourceMetrics.twitter.retweetsCount, favouritesCount (X only) |
metadata.digs, burrows | engagementMetrics.sourceMetrics.newsAggregators.digsCount, burrowsCount |
parentText | context.parent.content.text |
parentId | Call GET /mentions/{mentionId}/parent |
tags | tags |
| — | content.review.rating (review sources) |
Fields removed in V2
These legacy fields have no direct V2 field. Where the information is still available, the last column says where to find it.
| Legacy field | What it contained | In V2 |
|---|---|---|
keywords | A search helper: a merged copy of several other fields | Not needed. Search with filters.content.query and read the original fields |
host | Domain where the mention was published | Derive it from source.mentionUrl |
sourceURL | Link to the source | source.mentionUrl |
image | Author's avatar, or the attached image if there was no avatar | author.avatar and attachments |
authorURL | Link to the author's profile | No equivalent |
hasImageOrVideo | Whether the mention has an image or video | Check attachments for Image or Video items |
facebookPageId, youtubeChannelId | ID of the Facebook page or YouTube channel | source.socialChannel.id |
facebookIds, facebookMessengerThreadId | Facebook IDs in the context; Messenger thread ID | No equivalent. For threads, use discussion.id |
socialType, isInstagramStory | Platform-specific subtype, such as twitterTweet or facebookPhoto; Instagram story flag | type together with source.type |
link, description, caption, context, contextTitle, metaTitle | Details of shared or attached content: link, description, caption, page title | No equivalent. The mention's own title is in content.title |
places | Places tagged in the post (Foursquare, Instagram, Twitter) | No equivalent. Geolocation is in location |
recipients | Recipients of the post (Facebook, Wykop) | No equivalent |
parentCreatedAt and the parent* counters (parentLikes, parentComments, parentFans, parentFollowers, …) | Date and metrics of the parent post | GET /mentions/{mentionId}/parent returns the full parent mention, including publishedAt and engagementMetrics. Its text is also in context.parent.content.text |
metadata.friends, hearts, pluses, uniqueUsers | Counters of legacy platforms (Facebook friends, Foursquare and Instagram hearts, Google+ pluses, Instagram unique users) | No equivalent. Common counters are in engagementMetrics.sourceMetrics.common |
sourceData, sourceLimitations | Raw source-specific data; limits on replying or other actions in the app | No equivalent |
isRead, isReplied, isRepliedPriv, isTrashed, ignored, userId, status | Workflow state from the Listen app: read, replied, trashed, ignored, assigned user, status | Not exposed: V2 returns collected data, not app workflow state. Your own labels are available as tags |
isBot | Whether the author was detected as a bot | No equivalent |
isDeleted, isHidden | Whether the mention was deleted or hidden on the source platform | No equivalent |
Matching data you already stored
V2 mention IDs differ from legacy statement IDs. To avoid duplicates when you switch, each V2 mention carries deprecatedV1Fields.id, the legacy id of the same mention. Use it once to match V2 records to what you already stored, then key everything on the V2 id.
