> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unleeshed.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Topic Status

> Lightweight status check for polling commentary generation progress

## Overview

A lightweight endpoint for checking the workflow status of each persona's commentary generation. Use this for polling without fetching full commentary content.

<Tip>
  This endpoint returns less data than [GET /topics/:id](/api-reference/topics/get), making it ideal for frequent polling.
</Tip>

## Path Parameters

<ParamField path="id" type="string" required>
  The topic ID returned from [POST /topics](/api-reference/topics/create).
</ParamField>

## Response

<ResponseField name="topic_id" type="string">
  The topic identifier.
</ResponseField>

<ResponseField name="content" type="string">
  The topic content.
</ResponseField>

<ResponseField name="overall_status" type="string">
  Aggregated status across all personas:

  * `pending` - Waiting for creators to respond
  * `in_progress` - At least one creator is working on commentary
  * `partial` - Some commentaries ready, others still in progress
  * `completed` - All commentaries ready to fetch
</ResponseField>

<ResponseField name="personas" type="array">
  Per-persona workflow status:

  | Field               | Type     | Description                        |
  | ------------------- | -------- | ---------------------------------- |
  | `persona_id`        | string   | Persona UUID                       |
  | `persona_name`      | string   | Display name                       |
  | `status`            | string   | Current workflow stage (see below) |
  | `status_updated_at` | datetime | When status last changed           |
  | `has_commentary`    | boolean  | True if ready to fetch             |
</ResponseField>

<ResponseField name="summary" type="object">
  Count of personas at each stage:

  * `total` - Total personas
  * `topic_sent` - Waiting for creator
  * `opinion_injected` - Creator added perspective, AI generating
  * `commentary_generated` - Awaiting creator approval
  * `creator_approved` - Ready to fetch
  * `declined` - Creator declined
  * `expired` - Creator didn't respond in time
</ResponseField>

## Workflow Status Values

The `status` field for each persona follows this progression:

```mermaid theme={null}
stateDiagram-v2
    [*] --> topic_sent: Topic Created
    topic_sent --> opinion_injected: Creator Responds
    opinion_injected --> commentary_generated: AI Generates
    commentary_generated --> creator_approved: Creator Approves
    creator_approved --> [*]: Ready to Fetch
    
    topic_sent --> declined: Creator Declines
    topic_sent --> expired: No Response
    declined --> [*]
    expired --> [*]
```

| Status                 | Description                              | Has Commentary |
| ---------------------- | ---------------------------------------- | -------------- |
| `topic_sent`           | Waiting for creator to respond           | No             |
| `opinion_injected`     | Creator added perspective, AI generating | No             |
| `commentary_generated` | AI finished, awaiting creator approval   | No             |
| `creator_approved`     | Ready to fetch                           | **Yes**        |
| `declined`             | Creator declined this topic              | No             |
| `expired`              | Creator didn't respond in time window    | No             |

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://prod.api.unleeshed.ai/partner/v1/topics/abc123/status" \
    -H "X-Api-Key: pk_live_your_api_key"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://prod.api.unleeshed.ai/partner/v1/topics/${topicId}/status`,
    { headers: { 'X-Api-Key': process.env.UNLEESHED_API_KEY } }
  );

  const { data } = await response.json();

  console.log(`Overall: ${data.overall_status}`);
  console.log(`Ready: ${data.summary.creator_approved}/${data.summary.total}`);

  data.personas.forEach(p => {
    console.log(`${p.persona_name}: ${p.status}`);
  });
  ```

  ```python Python theme={null}
  import requests
  import os

  response = requests.get(
      f"https://prod.api.unleeshed.ai/partner/v1/topics/{topic_id}/status",
      headers={"X-Api-Key": os.environ["UNLEESHED_API_KEY"]}
  )

  data = response.json()["data"]

  print(f"Overall: {data['overall_status']}")
  print(f"Ready: {data['summary']['creator_approved']}/{data['summary']['total']}")

  for p in data["personas"]:
      print(f"{p['persona_name']}: {p['status']}")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "success": true,
    "data": {
      "topic_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "content": "Should the Lakers trade Anthony Davis?",
      "overall_status": "partial",
      "created_at": "2026-01-30T12:00:00Z",
      "personas": [
        {
          "persona_id": "pers_abc123",
          "persona_name": "Coach Mike",
          "status": "creator_approved",
          "status_updated_at": "2026-01-30T14:30:00Z",
          "has_commentary": true
        },
        {
          "persona_id": "pers_xyz789",
          "persona_name": "Analytics Amy",
          "status": "commentary_generated",
          "status_updated_at": "2026-01-30T14:15:00Z",
          "has_commentary": false
        },
        {
          "persona_id": "pers_def456",
          "persona_name": "Hot Take Harry",
          "status": "topic_sent",
          "status_updated_at": "2026-01-30T12:00:00Z",
          "has_commentary": false
        }
      ],
      "summary": {
        "total": 3,
        "topic_sent": 1,
        "opinion_injected": 0,
        "commentary_generated": 1,
        "creator_approved": 1,
        "declined": 0,
        "expired": 0
      }
    }
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "success": false,
    "error": {
      "code": "not_found",
      "message": "Topic not found"
    }
  }
  ```
</ResponseExample>

## Polling Best Practices

<AccordionGroup>
  <Accordion title="Recommended polling interval">
    Poll every **30-60 seconds**. Commentary generation involves human creators, so changes happen on a minutes-to-hours timescale, not seconds.
  </Accordion>

  <Accordion title="Handle partial results">
    When `overall_status` is `partial`, some commentaries are ready. You can fetch and display these while waiting for others.

    ```javascript theme={null}
    if (data.overall_status === 'partial' || data.overall_status === 'completed') {
      const commentaries = await fetchCommentaries(topicId);
      displayCommentaries(commentaries);
    }
    ```
  </Accordion>

  <Accordion title="Set realistic timeouts">
    Unlike instant AI APIs, this workflow involves human review. Set your timeout to **24-48 hours** rather than minutes.

    ```javascript theme={null}
    const MAX_WAIT_HOURS = 24;
    const created = new Date(data.created_at);
    const elapsed = Date.now() - created.getTime();

    if (elapsed > MAX_WAIT_HOURS * 60 * 60 * 1000) {
      // Handle timeout - some creators may not respond
    }
    ```
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Get Commentaries" icon="comments" href="/api-reference/commentary/get">
    Fetch ready commentaries when status is `creator_approved`.
  </Card>

  <Card title="Generate Commentary Guide" icon="waveform" href="/guides/generate-commentary">
    Complete integration guide.
  </Card>
</CardGroup>
