Post analysis

A Siftsy analysis is the relationship between what the post is and how commenters responded. GET /posts/{postId}/analysis returns both sides without comment bodies. Comments for that analysis live underneath it:

GET /posts/{postId}/analysis
GET /posts/{postId}/analysis/comments

Analyses of a selection of posts (a collection, tag, filter set, or explicit ids) use the same pattern, with POST /analyses in front to define the selection and any comment filters or search:

POST /analyses
GET /analyses/{analysisId}
GET /analyses/{analysisId}/comments

Post analysis is the per-post dashboard view, always materialized. Analyses covers selections of up to 1,000 posts and the job model for searches. Both nest comments under the analysis — they are not a standalone post resource.

GET /posts/{postId}/analysis

Requires posts:read. Materialized only — it never rescores or runs live LLM.

curl -sS -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.siftsy.app/analyst/v1/posts/YOUR_POST_ID/analysis"

comments.path is the subresource for comment bodies.

Full payload

{
"data": {
"postId": "p_301",
"content": {
"brief": "Launch video for the new running line; creator demos the shoe and announces same-day shipping.",
"title": "The new line is here",
"description": "Same-day shipping on every order this week. #launch",
"platform": "tiktok",
"link": "https://www.tiktok.com/@acme/video/7311",
"creator": { "username": "acme", "name": "Acme Running", "avatar": null },
"postedAt": "2026-09-02T17:00:00.000Z",
"engagement": { "views": 812000, "likes": 40400, "comments": 4820, "shares": 1210, "saves": 3300, "engagementRate": 0.0605 },
"isDemo": false,
"topics": [{ "title": "Product launch", "description": "New running shoe line" }],
"messages": [{ "topic": "Product launch", "stance": "The new line ships faster" }],
"scores": { "content": 7.1, "topic": 6.4 },
"mix": {
"content": { "positivePercent": 41, "leanPositivePercent": 22, "neutralPercent": 18, "leanNegativePercent": 11, "negativePercent": 8 },
"topic": { "positivePercent": 35, "leanPositivePercent": 27, "neutralPercent": 20, "leanNegativePercent": 10, "negativePercent": 8 }
}
},
"commentAnalysis": {
"briefSummary": "Fans are excited about the colorways; a vocal minority reports late deliveries.",
"scores": { "scoreVersion": 2, "siftsyScore": 7.1, "sentiment": 6.8, "relevance": 7.9, "consensus": 7.2, "content": 6.9, "topic": 7.0 },
"mix": {
"sentiment": { "positivePercent": 44, "leanPositivePercent": 21, "neutralPercent": 14, "leanNegativePercent": 12, "negativePercent": 9 },
"relevance": { "positivePercent": 61, "leanPositivePercent": 22, "neutralPercent": 0, "leanNegativePercent": 12, "negativePercent": 5 },
"consensus": { "positivePercent": 48, "leanPositivePercent": 30, "neutralPercent": 0, "leanNegativePercent": 16, "negativePercent": 6 },
"content": { "positivePercent": 41, "leanPositivePercent": 22, "neutralPercent": 18, "leanNegativePercent": 11, "negativePercent": 8 },
"topic": { "positivePercent": 35, "leanPositivePercent": 27, "neutralPercent": 20, "leanNegativePercent": 10, "negativePercent": 8 }
},
"topics": [
{
"label": "Shipping delays",
"shareOfComments": 0.13,
"shareOfContent": 1,
"commentCount": 611,
"postCount": 1,
"scores": { "siftsyScore": 3.1, "sentiment": 2.3, "relevance": 7.8, "consensus": 6.9, "content": 2.1, "topic": 2.6 },
"brief": { "heading": "Orders arriving late", "description": "Commenters report deliveries missing the same-day promise." },
"sampleCommentIds": ["c_77f1", "c_1a09"]
}
],
"notableCommentIds": [],
"outliers": [],
"wordCloud": null,
"emojiCloud": null,
"totalComments": 4820,
"completeness": "full"
},
"comments": { "path": "/posts/p_301/analysis/comments" },
"computedAt": "2026-09-03T04:12:44.000Z"
},
"meta": {}
}

Every field is always present; values that were never materialized for the post are null or []. scores.scoreVersion tells you which scoring model produced the numbers (see Scores).

Content (creator-side)

FieldWhat it is
briefPost summary
title, description, platform, link, creator, postedAt, engagementThe post
topics[]Topics this post was scored against (title, description)
messages[]Creator messages / stances (topic, stance)
scores.contentAlignment with the post / creator (1–10)
scores.topicReception of the subject (1–10)
mix.content / mix.topicFive-bucket mix for those scores

Content mix labels: Supportive / Receptive / Split / Skeptical / Opposed. Topic mix labels: Enthusiastic / Favorable / Mixed / Critical / Hostile. JSON keys are the same positivePercentnegativePercent as sentiment. See Scores.

Comment analysis (audience-side)

FieldWhat it is
scoresSiftsy score plus sentiment, content, topic, relevance, consensus
mix.sentimentOverall sentiment bars
mix.content / mix.topicSame bars, split by dimension
mix.relevanceOn-topic → off-topic
mix.consensusHow commenters react to each other, not the post
topics[]Emergent comment themes when stored on the post: label, shareOfComments / shareOfContent (0–1), commentCount, postCount, scores, brief.heading / brief.description, sampleCommentIds
briefSummaryAudience brief when materialized
notableCommentIds[], outliers[]Reserved; empty unless stored on the post
wordCloud, emojiCloudnull on the per-post route (request them via include on POST /analyses)
totalCommentsComment count
completenessHow much of the panel is filled
comments.pathSample of comments behind this analysis. Relative to the base URL: https://api.siftsy.app/analyst/v1 + path
computedAtWhen the post was last processed

completeness is full, scores_and_content, scores_only, content_only, or unavailable. Themes, notables, and clouds stay empty unless they were stored on the post. They do not trigger a live analysis job.

Consensus is not agreement with the post. A thread can be uniformly negative toward the post and still have high consensus.

GET /posts/{postId}/analysis/comments

Requires comments:read and posts:read. This is a sample of comments behind that analysis — the same mix bars and creator topics/messages — not a dump of the thread. Hidden comments are excluded.

Siftsy is an analysis platform, not a comment exporter. Use source=notables (or content / all) for evidence. Do not treat this route as a way to export a full comment section.

curl -sS -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.siftsy.app/analyst/v1/posts/YOUR_POST_ID/analysis/comments?source=notables"

On-topic comments that are fighting, still as a sample:

curl -sS -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.siftsy.app/analyst/v1/posts/YOUR_POST_ID/analysis/comments?source=notables&relevance=on_topic&consensus=fighting"

source=notables is engagement + relevance, content groups onto creator topics/messages, all is the union. Sampled rows include sampleReasons. meta.groups lists creator topics and messages with commentCount and sampleCommentIds. Mix-bar filters narrow the sample. See Retrieving comments.

This route is the comments rate class (120 requests / minute, 1,000 / day, per key) — enough to sample source=notables for every post in a 500-post workspace once a day, and deliberately not enough to page full threads.

GET /analyses/{analysisId}/comments

Requires comments:read and analyses:read. Same sampled evidence as the post analysis comments route — across every post on that analysis (up to 1,000 posts), not a full-thread export. For analyses created with POST /analyses, the analysis’s own filters and search matches are applied first, so the sample is drawn from the set the analysis numbers describe.

curl -sS -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.siftsy.app/analyst/v1/analyses/YOUR_ANALYSIS_ID/comments?source=notables&relevance=on_topic&consensus=fighting"

GET /analyses/{analysisId} includes comments.path. Comment bodies are not on the analysis itself.

Analyses with more than 1000 posts return 400. meta.groups includes postId when more than one post is in the result. Analyses that are still queued / running return 409 analysis_not_ready.

This route is the analysis_comments rate class (20 requests / minute, 300 / day, per key): every page re-reads the comments of every post on the analysis, so use it for the comments behind a filter or search rather than for bulk export. POST /analyses is analysis_create or analysis_search; GET /analyses/{analysisId} is analysis_read. See Rate limits. See Analyses for the full selection → analysis → comments flow and the analysis payload.