API & MCP

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}/reports

Returns a project's reports, newest first, without their content. Deleted reports are left out.

Query parameters#

ParameterDescription
statusOne or more of generating, completed, failed, separated by commas
limit1 to 100. Default 25.
cursorThe 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#

FieldTypeDescription
idstringReport ID
project_idstringThe project it belongs to
statusstringgenerating, completed or failed
titlestring or nullThe headline the AI gave the report. null until it's completed.
focusstring or nullThe question your team asked the report to focus on, if any
selection.modestringdate_range (all completed conversations in a period) or manual (hand-picked conversations)
selection.range_start, selection.range_endstring or nullThe period for date_range. null means no limit on that side.
conversation_countnumberHow many conversations the report covers
first_conversation_at, last_conversation_atstring or nullWhen the oldest and newest covered conversations were created
sentiment_countsobject or nullCovered conversations by overall sentiment. null until the report is completed.
error_messagestring or nullWhy a failed report failed
created_atstringWhen the report was requested
completed_atstring or nullWhen 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.

FieldTypeDescription
conversation_idsarrayEvery conversation the report covers
content.summarystringThe report's overall summary
content.focus_answerstring or nullThe answer to the report's focus, when one was set
content.sentiment_explanationstringWhat drives the sentiment split
content.themesarrayRecurring topics, most mentioned first
content.themes[].tonestringpositive, negative, mixed or neutral
content.issuesarrayConcrete problems to fix
content.issues[].severitystringhigh, medium or low
content.outliersarrayNotable points raised by only a few respondents. They have no quotes.
title, detailstringOn every theme, issue and outlier: a headline and a short explanation
mention_countnumberHow many conversations raised it
conversation_idsarrayThose conversations. Fetch any of them with the Conversations API.
quotes[].textstringThe respondent's own words
quotes[].translationstring or nullAn English translation when the quote is in another language
quotes[].conversation_idstringThe conversation the quote comes from
quotes[].respondent_labelstring or nullWho said it, when known
quotes[].created_atstringWhen 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.