> For the complete documentation index, see [llms.txt](https://boundaryai.gitbook.io/boundaryai-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://boundaryai.gitbook.io/boundaryai-docs/api-and-webhooks/analysis.md).

# Analysis

Read back what the platform found: sentiment distribution, themes, and Custom Monitoring matches for a source. Pair with the `analysis.completed` webhook instead of polling.

## Read processed analysis for a source

> Partner-vocabulary variant of \`/surveys/{survey\_id}/analysis\`: sentiment distribution, themes and monitored flags for one source. Flags are monitored at the feedback-group level. Analysis launches automatically after content lands and takes minutes to tens of minutes depending on volume and queue depth; \`analysis\_status: "none"\` means no completed run has been persisted yet (it does not distinguish queued from in-progress). Pair with the \`analysis.completed\` webhook — registered in the dashboard's Integrations Hub — instead of polling.\
> \
> \*\*Response envelope migration:\*\* during the current migration window, 2xx responses carry the bare payload shown in the example (the value of the schema's \`data\` property, without the \`{"data": ...}\` wrapper). The \`Deprecation\` and \`Sunset\` headers on every 2xx announce this envelope migration — they do \*\*not\*\* deprecate the endpoint itself. After the \`Sunset\` date, responses will be wrapped as \`{"data": ...}\` exactly as the schema declares.

```json
{"openapi":"3.1.0","info":{"title":"BAI Analytics API","version":"1.3.0"},"tags":[{"name":"Analysis","description":"Read back what the platform found: sentiment distribution, themes, and Custom Monitoring matches for a source. Pair with the `analysis.completed` webhook instead of polling."}],"servers":[{"url":"https://app.boundary-ai.com","description":"Production"}],"security":[{"apiKeyAuth":[]}],"components":{"securitySchemes":{"apiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"BAI Analytics API key","description":"API key authentication: pass your key in the Authorization header as `Bearer inpk_live_...` (or `inpk_test_...` for a test-environment key). Create and manage keys in the dashboard under Integrations Hub -> API Keys. Each key carries a permission scope (push, create, send, mcp_read, or all) and a per-minute rate limit."}},"schemas":{"SourceAnalysisReadResponse":{"description":"Partner-vocabulary variant of SurveyAnalysisReadResponse.","properties":{"source_id":{"title":"Source Id","type":"integer"},"feedback_group_id":{"title":"Feedback Group Id","type":"integer"},"feedback_type":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Feedback Type"},"analysis_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Analysis Id"},"analysis_status":{"enum":["available","none"],"title":"Analysis Status","type":"string"},"sentiment_distribution":{"$ref":"#/components/schemas/SentimentDistribution"},"themes":{"items":{"$ref":"#/components/schemas/AnalysisTheme"},"title":"Themes","type":"array"},"flags":{"items":{"$ref":"#/components/schemas/AnalysisFlag"},"title":"Flags","type":"array"}},"required":["source_id","feedback_group_id","analysis_status","sentiment_distribution"],"title":"SourceAnalysisReadResponse","type":"object"},"SentimentDistribution":{"description":"5-tier mention-weighted sentiment distribution.","properties":{"veryPositive":{"default":0,"title":"Verypositive","type":"integer"},"positive":{"default":0,"title":"Positive","type":"integer"},"neutral":{"default":0,"title":"Neutral","type":"integer"},"negative":{"default":0,"title":"Negative","type":"integer"},"veryNegative":{"default":0,"title":"Verynegative","type":"integer"}},"title":"SentimentDistribution","type":"object"},"AnalysisTheme":{"properties":{"name":{"title":"Name","type":"string"},"mentions":{"minimum":0,"title":"Mentions","type":"integer"},"avg_sentiment":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"-1..1 average sentiment across mentions","title":"Avg Sentiment"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Description"}},"required":["name","mentions"],"title":"AnalysisTheme","type":"object"},"AnalysisFlag":{"properties":{"name":{"title":"Name","type":"string"},"mentions":{"minimum":0,"title":"Mentions","type":"integer"},"avg_sentiment":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"title":"Avg Sentiment"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Summary"},"scope":{"const":"survey_series","default":"survey_series","description":"Flags are monitored at feedback-group level; the list covers the whole group this survey belongs to.","title":"Scope","type":"string"}},"required":["name","mentions"],"title":"AnalysisFlag","type":"object"},"ErrorEnvelope":{"description":"Top-level error response.\n\nSchema name in the OpenAPI document: ``ErrorEnvelope``.","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"},"details":{"anyOf":[{},{"type":"null"}],"default":null,"description":"Optional structured details (e.g. validation field map)","title":"Details"}},"required":["error"],"title":"ErrorEnvelope","type":"object"},"ErrorObject":{"description":"The inner ``error`` field of an error envelope.\n\nSchema name in the OpenAPI document: ``ErrorObject``.","properties":{"code":{"description":"Machine-readable error code drawn from ErrorCode enum","title":"Code","type":"string"},"message":{"description":"Human-readable error message, safe to display","title":"Message","type":"string"}},"required":["code","message"],"title":"ErrorObject","type":"object"}},"responses":{"RateLimited":{"description":"Rate limit exceeded — see Retry-After header.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"headers":{"RetryAfter":{"description":"Seconds to wait before retrying. Emitted on 429 responses and on 503 responses from the global rate limiter. Rate-limit windows are fixed (anchored at the first request in the window): requests rejected with 429 do not extend the window, so waiting until ``X-RateLimit-Reset`` always recovers.","schema":{"type":"integer","minimum":1}},"XRateLimitLimit":{"description":"Total requests allowed in the current rate-limit window.","schema":{"type":"integer","minimum":1}},"XRateLimitRemaining":{"description":"Requests remaining in the current rate-limit window.","schema":{"type":"integer","minimum":0}},"XRateLimitReset":{"description":"Unix timestamp when the rate-limit window resets. The window is fixed from its first request — 429-rejected requests do not push this forward.","schema":{"type":"integer","minimum":0}}}},"paths":{"/api/input/sources/{survey_id}/analysis":{"get":{"summary":"Read processed analysis for a source","description":"Partner-vocabulary variant of `/surveys/{survey_id}/analysis`: sentiment distribution, themes and monitored flags for one source. Flags are monitored at the feedback-group level. Analysis launches automatically after content lands and takes minutes to tens of minutes depending on volume and queue depth; `analysis_status: \"none\"` means no completed run has been persisted yet (it does not distinguish queued from in-progress). Pair with the `analysis.completed` webhook — registered in the dashboard's Integrations Hub — instead of polling.\n\n**Response envelope migration:** during the current migration window, 2xx responses carry the bare payload shown in the example (the value of the schema's `data` property, without the `{\"data\": ...}` wrapper). The `Deprecation` and `Sunset` headers on every 2xx announce this envelope migration — they do **not** deprecate the endpoint itself. After the `Sunset` date, responses will be wrapped as `{\"data\": ...}` exactly as the schema declares.","tags":["Analysis"],"operationId":"inputapi_get_source_analysis","parameters":[{"name":"survey_id","in":"path","required":true,"schema":{"type":"integer","format":"int64"},"description":"The source id"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SourceAnalysisReadResponse"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — insufficient permission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}}}}
```
