Reports API
An AI report reads a set of completed conversations and writes up the sentiment, common themes and issues. The API returns the reports your team created in the dashboard. It can't create new ones. For authentication, pagination and errors, see the API overview.
List reports#
HTTP
GET /api/v1/projects/{project_id}/reportsReturns a project's reports, newest first, without their content. Deleted reports are left out.
Query parameters#
| Parameter | Description |
|---|---|
status | One or more of generating, completed, failed, separated by commas |
limit | 1 to 100. Default 25. |
cursor | The next_cursor of the previous page |
Example#
curl -G "https://diaform.io/api/v1/projects/b8acb3ab-1f3d-4a7e-a846-b7f493f86b6d/reports" \
-H "Authorization: Bearer $DIAFORM_API_KEY" \
--data-urlencode "status=completed"Response#
JSON
{
"data": [
{
"id": "882f2ed7-07d9-4344-aced-9e523275b196",
"project_id": "b8acb3ab-1f3d-4a7e-a846-b7f493f86b6d",
"status": "completed",
"title": "Support problems overshadow a well-liked product",
"focus": null,
"selection": {
"mode": "date_range",
"range_start": "2026-05-01T00:00:00+00:00",
"range_end": "2026-05-31T23:59:59+00:00"
},
"conversation_count": 48,
"first_conversation_at": "2026-05-01T08:12:09.692998+00:00",
"last_conversation_at": "2026-05-30T13:11:09.628765+00:00",
"sentiment_counts": {
"positive": 14,
"negative": 11,
"neutral": 8,
"mixed": 15,
"unknown": 0
},
"error_message": null,
"created_at": "2026-06-01T09:33:49.465144+00:00",
"completed_at": "2026-06-01T09:34:07.2+00:00"
}
],
"has_more": false,
"next_cursor": null
}Report fields#
| Field | Type | Description |
|---|---|---|
id | string | Report ID |
project_id | string | The project it belongs to |
status | string | generating, completed or failed |
title | string or null | The headline the AI gave the report. null until it's completed. |
focus | string or null | The question your team asked the report to focus on, if any |
selection.mode | string | date_range (all completed conversations in a period) or manual (hand-picked conversations) |
selection.range_start, selection.range_end | string or null | The period for date_range. null means no limit on that side. |
conversation_count | number | How many conversations the report covers |
first_conversation_at, last_conversation_at | string or null | When the oldest and newest covered conversations were created |
sentiment_counts | object or null | Covered conversations by overall sentiment. null until the report is completed. |
error_message | string or null | Why a failed report failed |
created_at | string | When the report was requested |
completed_at | string or null | When it finished or failed |
Get a report#
HTTP
GET /api/v1/reports/{report_id}Returns one report with every field of the list, plus conversation_ids and the written content.
Example#
curl "https://diaform.io/api/v1/reports/882f2ed7-07d9-4344-aced-9e523275b196" \
-H "Authorization: Bearer $DIAFORM_API_KEY"Response#
The fields shared with the list are left out here.
JSON
{
"id": "882f2ed7-07d9-4344-aced-9e523275b196",
"status": "completed",
"title": "Support problems overshadow a well-liked product",
"conversation_ids": [
"0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee",
"912b8ced-f69d-4f50-b497-9a712fe59359"
],
"content": {
"summary": "Most respondents like the product and would recommend it, but support wait times came up in a quarter of the interviews.",
"focus_answer": null,
"sentiment_explanation": "Praise for the product is offset by frustration with support.",
"themes": [
{
"title": "Customer support is the top complaint",
"detail": "Twelve respondents described long waits before reaching support.",
"tone": "negative",
"mention_count": 12,
"conversation_ids": ["912b8ced-f69d-4f50-b497-9a712fe59359"],
"quotes": [
{
"conversation_id": "912b8ced-f69d-4f50-b497-9a712fe59359",
"text": "it took me 25 min to connect last time, which is too long",
"translation": null,
"respondent_label": "alex@acme.com",
"created_at": "2026-05-10T17:52:10.539708+00:00"
}
]
}
],
"issues": [
{
"title": "Invite emails land in spam",
"detail": "Three respondents never received their teammate invite.",
"severity": "high",
"mention_count": 3,
"conversation_ids": ["0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee"],
"quotes": []
}
],
"outliers": [
{
"title": "Request for an on-premise version",
"detail": "One enterprise respondent can't use cloud tools.",
"mention_count": 1,
"conversation_ids": ["0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee"]
}
]
}
}Content fields#
content is null while the report is generating and when it failed.
| Field | Type | Description |
|---|---|---|
conversation_ids | array | Every conversation the report covers |
content.summary | string | The report's overall summary |
content.focus_answer | string or null | The answer to the report's focus, when one was set |
content.sentiment_explanation | string | What drives the sentiment split |
content.themes | array | Recurring topics, most mentioned first |
content.themes[].tone | string | positive, negative, mixed or neutral |
content.issues | array | Concrete problems to fix |
content.issues[].severity | string | high, medium or low |
content.outliers | array | Notable points raised by only a few respondents. They have no quotes. |
title, detail | string | On every theme, issue and outlier: a headline and a short explanation |
mention_count | number | How many conversations raised it |
conversation_ids | array | Those conversations. Fetch any of them with the Conversations API. |
quotes[].text | string | The respondent's own words |
quotes[].translation | string or null | An English translation when the quote is in another language |
quotes[].conversation_id | string | The conversation the quote comes from |
quotes[].respondent_label | string or null | Who said it, when known |
quotes[].created_at | string | When that conversation was created |
A report is a snapshot of the conversations at the time it was written. If a conversation is deleted later, its quotes are removed from the report.