---
title: "Team Huddles API reference"
canonical_url: https://zentrik.ai/docs/api/huddles
markdown_url: https://zentrik.ai/docs/api/huddles.md
last_reviewed: 2026-10-21
---

# Team Huddles API reference

Upload transcripts with huddles:write and read daily Team Huddle history with huddles:read or initiatives:read. Read and write grants are separate. Existing initiative-read keys continue to authorize reads. Each grant covers all teams in the workspace; huddles:read lets new keys request only Huddle reads. Initiative Huddle note sessions are a separate workflow. Each daily record retains its latest saved state, up to ten conversation sources, up to 100,000 characters per uploaded source, and up to 120,000 characters of combined transcript text for analysis.

- Human reference: https://zentrik.ai/docs/api/huddles
- Complete Markdown index: https://zentrik.ai/docs/api/index.md
- Base URL: `https://zentrik.ai/api`
- Authentication: `Authorization: Bearer YOUR_API_KEY`
- Shared pagination and rate limits: https://zentrik.ai/docs/api/index.md#shared-conventions

## GET /external/v1/huddles — List Team Huddle history

Operation ID: `list-team-huddles`

List saved daily huddles across the API key’s workspace, newest date first, with ID descending as the tie-breaker. Returns identity, timestamps and version metadata only. The body is an array; X-Total-Count, X-Limit, X-Offset and X-Has-More headers describe pagination. Concurrent creation or deletion can shift offset pages. Reads never create or refresh huddles. Existing keys with initiatives:read also authorize this endpoint; either scope is sufficient.

Required API key scopes: `huddles:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `teamId` | UUID | No | Filter to one team. Omit to include all teams in the API key’s workspace. |
| `from` | string | No | Inclusive huddle date, YYYY-MM-DD. Filters the saved calendar date, not generatedAt. |
| `to` | string | No | Inclusive huddle date, YYYY-MM-DD; must be on or after from. Set from and to to the same date for one day. |
| `limit` | integer | No | Page size, 1–100. Default: 20. |
| `offset` | integer | No | Matching records to skip. Default: 0. |

### Example request

```curl
curl 'https://zentrik.ai/api/external/v1/huddles?from=2026-09-03&to=2026-09-03&limit=20&offset=0' -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | Shallow records and pagination headers. No matches or an exhausted page returns an empty array. | — |
| 400 | Invalid query | Invalid UUID, date, date range, pagination or unsupported parameter. | — |

### Example response

```json
[
  {
    "id": "11111111-1111-4111-8111-111111111111",
    "workspaceId": "22222222-2222-4222-8222-222222222222",
    "teamId": "33333333-3333-4333-8333-333333333333",
    "huddleDate": "2026-09-03",
    "schemaVersion": 4,
    "refreshRevision": 1,
    "generatedAt": "2026-09-03T09:00:00.000Z",
    "generatedByUserId": null,
    "createdAt": "2026-09-03T09:00:00.000Z",
    "updatedAt": "2026-09-03T09:15:00.000Z"
  }
]
```

---

## GET /external/v1/huddles/:id — Get a Team Huddle

Operation ID: `get-team-huddle`

Retrieve metadata and all six stored snapshots: goals, customer changes, execution, pending actions, comparisons and conversations. The conversation snapshot includes retained sources, the summary, outstanding items, action candidates and analysis status/error/time. Snapshot fields follow schemaVersion and can be absent in older records. This is the latest saved state, not an end-of-day snapshot or revision archive. Refresh overwrites the daily record; conversation and action edits can update sections without increasing refreshRevision. Pasted text is in sources[].notes. Connected sources retain references with notes: null; fetch their text through the transcript route. A connected source names its provider in type, the provider’s meeting or transcript ID in externalId, and the provider link saved when the transcript was chosen in url, such as the Fireflies transcript page. If the same call was also imported as a signal, GET /external/v1/signals?externalId={externalId}&integrationId={integrationId} returns it. This detail route makes no provider requests. Existing keys with initiatives:read also authorize this endpoint; either scope is sufficient.

Required API key scopes: `huddles:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | UUID | Yes | Huddle ID returned by the list endpoint (path parameter). |

### Example request

```curl
curl 'https://zentrik.ai/api/external/v1/huddles/11111111-1111-4111-8111-111111111111' -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | Metadata and complete saved snapshots. Snapshot objects in this example are abbreviated; the response returns complete stored JSON. | — |
| 400 | Invalid ID | The huddle ID must be a UUID. | — |
| 404 | Not found | The huddle does not exist in the API key’s workspace. | — |

### Example response

```json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "workspaceId": "22222222-2222-4222-8222-222222222222",
  "teamId": "33333333-3333-4333-8333-333333333333",
  "huddleDate": "2026-09-03",
  "schemaVersion": 4,
  "refreshRevision": 1,
  "generatedAt": "2026-09-03T09:00:00.000Z",
  "generatedByUserId": null,
  "createdAt": "2026-09-03T09:00:00.000Z",
  "updatedAt": "2026-09-03T09:15:00.000Z",
  "goalSnapshot": {
    "globalProgress": 0,
    "progressMethod": "equal_average",
    "goalCount": 0,
    "goals": []
  },
  "customerSnapshot": {},
  "executionSnapshot": {},
  "pendingActionSnapshot": [],
  "comparisonSnapshot": {
    "hasBaseline": false,
    "comparedWithDate": null,
    "requestedPreviousDay": "2026-09-02",
    "usedPreviousDay": false
  },
  "conversationSnapshot": {
    "sources": [
      {
        "id": "55555555-5555-4555-8555-555555555555",
        "provider": "Fireflies",
        "title": "Customer interview",
        "type": "fireflies",
        "externalId": "fireflies-transcript-id",
        "url": "https://app.fireflies.ai/view/fireflies-transcript-id",
        "occurredAt": "2026-09-02T16:00:00.000Z",
        "integrationId": "66666666-6666-4666-8666-666666666666",
        "metadata": {},
        "retention": "reference",
        "notes": null,
        "addedByUserId": "77777777-7777-4777-8777-777777777777",
        "createdAt": "2026-09-03T09:10:00.000Z"
      },
      {
        "id": "44444444-4444-4444-8444-444444444444",
        "provider": "Pasted notes",
        "title": "Daily huddle",
        "type": "transcript",
        "externalId": null,
        "url": null,
        "occurredAt": null,
        "integrationId": null,
        "metadata": {},
        "retention": "stored",
        "notes": "Review the scheduling feedback tomorrow.",
        "addedByUserId": null,
        "createdAt": "2026-09-03T09:15:00.000Z"
      }
    ],
    "analysisStatus": "queued",
    "aggregate": null,
    "analysisError": null,
    "analyzedAt": null
  }
}
```

---

## GET /external/v1/huddles/:huddleId/conversations/:conversationId — Get a huddle transcript

Operation ID: `get-team-huddle-transcript`

Retrieve one attached conversation’s transcript text. Pasted notes come from the saved huddle. Connected transcripts are fetched on demand using the stored provider reference and connected account, without persisting the text. Retrieval depends on source availability and provider permissions. All huddle reads use Cache-Control: private, no-store. Existing keys with initiatives:read also authorize this endpoint; either scope is sufficient.

Required API key scopes: `huddles:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `huddleId` | UUID | Yes | Huddle ID (path parameter). |
| `conversationId` | UUID | Yes | Zentrik conversation entry ID from conversationSnapshot.sources[].id (path parameter), not the provider’s meeting ID. |

### Example request

```curl
curl 'https://zentrik.ai/api/external/v1/huddles/11111111-1111-4111-8111-111111111111/conversations/55555555-5555-4555-8555-555555555555' -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | Source identity, provider, title, occurrence date, saved provider link and transcript text. Pasted notes return url: null. | — |
| 400 | Unavailable content | Invalid UUID, empty transcript, incomplete reference or integration requiring reconnection. Provider errors may also be returned. | — |
| 404 | Not found | Huddle, source or connected integration was not found. | — |

### Example response

```json
{
  "id": "55555555-5555-4555-8555-555555555555",
  "provider": "Fireflies",
  "title": "Customer interview",
  "occurredAt": "2026-09-02T16:00:00.000Z",
  "url": "https://app.fireflies.ai/view/fireflies-transcript-id",
  "text": "Scheduling takes our team two hours every Monday."
}
```

---

## POST /external/v1/huddles/conversations — Add a Huddle transcript

Operation ID: `create-team-huddle-transcript`

Upload meeting text to a team’s daily Huddle. Requires huddles:write; read scopes do not allow uploads. Supply teamId and an explicit date to select the destination; Zentrik creates the daily Huddle if needed. Text is stored as an API-uploaded transcript, and analysis is queued. Suggested actions and decisions remain subject to review in Huddle. The latest ten conversation sources are retained. Their combined transcript text is limited to 120,000 characters, excluding source labels; each upload is also limited to 100,000 characters. A request exceeding the known retained-text budget returns 400 without adding the upload or changing the existing analysis. Shorten notes before retrying; splitting the same text across uploads does not avoid the combined limit. Connected source lengths are checked again when fetched. Each successful POST appends a new source: sourceExternalId is descriptive metadata, not a deduplication key. After a timeout, inspect the Huddle sources before retrying; serialize uploads to the same team/date. Connected-provider references and audio files are not accepted by this endpoint.

Required API key scopes: `huddles:write`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `teamId` | UUID | Yes | Destination team in the API key workspace (query parameter). Find IDs with GET /external/v1/teams using initiatives:read. |
| `date` | string | Yes | Huddle calendar date as YYYY-MM-DD (body). |
| `notes` | string | Yes | Nonblank transcript text, at most 100,000 characters (body). |
| `sourceTitle` | string | No | Meeting title, at most 200 characters (body). |
| `sourceExternalId` | string | No | Source-system meeting ID, at most 500 characters; does not deduplicate uploads (body). |
| `sourceUrl` | string | No | HTTP(S) source link, at most 2,000 characters; not fetched (body). |
| `sourceOccurredAt` | string | No | ISO 8601 occurrence time including Z or an offset (body). |

### Example request

```curl
curl -X POST 'https://zentrik.ai/api/external/v1/huddles/conversations?teamId=33333333-3333-4333-8333-333333333333'   -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json'   -d '{"date":"2026-10-21","notes":"We agreed to follow up with the customer on Friday.","sourceTitle":"Weekly team sync","sourceExternalId":"meeting-2026-10-21"}'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 201 | Saved | Returns the Huddle and conversation IDs. Poll GET /external/v1/huddles/:id with huddles:read or initiatives:read; conversationSnapshot reports analysisStatus, analysisError and the resulting aggregate; decisionStatus and decisionError separately report decision extraction. Wait for both to finish. A saved upload does not mean analysis has finished. If existing or fetched provider text exceeds the combined limit, both statuses become failed with an explicit size error; no partial analysis runs. Existing sources remain retrievable. Contact support to reduce oversized retained sources, then retry analysis in Huddle. | — |
| 400 | Invalid input | Missing team/date/text, invalid date or URL, oversized text, or an unsupported field. Combined-size errors include code: HUDDLE_TRANSCRIPT_LIMIT_EXCEEDED, maxCharacters: 120000 and totalCharacters. The rejected upload is not saved; shorten notes and retry. Send JSON text, not a file or provider credentials. | — |
| 401 | Unauthorized | Missing, invalid, expired or disabled API key. | — |
| 403 | Missing scope | Grant huddles:write to the API key. | — |
| 404 | Team not found | The destination team does not belong to the key’s workspace. | — |
| 429 | Rate limited | Wait for Retry-After before another request. | — |

### Example response

```json
{
  "huddleId": "11111111-1111-4111-8111-111111111111",
  "teamId": "33333333-3333-4333-8333-333333333333",
  "date": "2026-10-21",
  "conversationId": "44444444-4444-4444-8444-444444444444",
  "analysisStatus": "queued"
}
```
