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

# Transcripts API: Upload and retrieve transcripts

> Upload conversation transcripts into a Bigspin project via the public API, list transcripts in a project, and retrieve a single transcript with turns and annotations.

A **transcript** is a single conversation — a sequence of `user` / `assistant` (and optionally `tool` / `system` / `human_agent`) turns — that you upload into a [project](/api-reference/projects). The Transcripts API lets you push conversations from your AI system into Bigspin programmatically, list the transcripts in a project, and fetch a single transcript with its turns and AI-generated annotations.

## Prerequisites

* An **API key** from your workspace with the `projects-write` permission (for `POST`) or `projects-read` permission (for `GET`). See [Authentication](/api-reference/authentication).
* A **project ID** (`hp-{uuid}` format). Create one with `POST /projects` if you don't have one yet.
* The base URL: `https://app.bigspin.ai/public/api/v1`

## Endpoints

| Method | Path                                | Permission       | Purpose                                               |
| ------ | ----------------------------------- | ---------------- | ----------------------------------------------------- |
| `POST` | `/projects/{projectId}/transcripts` | `projects-write` | Upload a transcript into a project                    |
| `GET`  | `/projects/{projectId}/transcripts` | `projects-read`  | List transcripts in a project (paginated, filterable) |
| `GET`  | `/transcripts/{transcriptId}`       | `projects-read`  | Get a single transcript with turns and annotations    |

## Upload a transcript — `POST /projects/{projectId}/transcripts`

### Request

```bash theme={null}
curl -X POST "https://app.bigspin.ai/public/api/v1/projects/hp-550e8400-e29b-41d4-a716-446655440000/transcripts" \
  -H "Authorization: Bearer sk-bigspin-api03-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support ticket #4821",
    "modelName": "gpt-4o",
    "externalId": "ticket-4821",
    "turns": [
      { "role": "user", "content": "My order never arrived." },
      { "role": "assistant", "content": "I am sorry to hear that. Let me check your order status." }
    ]
  }'
```

### Path parameter

<ParamField path="projectId" type="string" required>
  The ID of the project to upload into. Must match the `hp-{uuid}` format. The project must belong to the same workspace as your API key.
</ParamField>

### Request body

<ParamField body="name" type="string" required>
  A human-readable name for the transcript. 1–500 characters.
</ParamField>

<ParamField body="turns" type="array" required>
  Array of conversation turns. At least 1 turn, at most 1000.

  Each turn has:

  * `role` — one of `user`, `assistant`, `system`, `tool`, `human_agent`
  * `content` — string, up to 1 MB per turn
  * `toolCalls` — (optional) array of `{ name, args }` objects for assistant tool calls
  * `toolResults` — (optional) array of `{ name, result }` objects for tool responses
  * `metadata` — (optional) arbitrary object
  * `createdAt` — (optional) ISO 8601 timestamp for the turn
</ParamField>

<ParamField body="modelName" type="string">
  The name of the model that produced the assistant turns. Max 100 characters.
</ParamField>

<ParamField body="language" type="string">
  Optional language code. Max 10 characters.
</ParamField>

<ParamField body="sourceSystem" type="string">
  Optional source system identifier. Max 100 characters.
</ParamField>

<ParamField body="externalId" type="string">
  Your system's identifier for this conversation. Max 500 characters. Useful for cross-referencing.
</ParamField>

<ParamField body="externalUserId" type="string">
  Optional end-user identifier from your system. Max 500 characters.
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary metadata object stored alongside the transcript.
</ParamField>

<ParamField body="sourceTimestamp" type="string">
  ISO 8601 timestamp of when the conversation took place.
</ParamField>

<ParamField body="process" type="boolean" default="true">
  Whether to run Bigspin's annotation pipeline (structural + LLM annotation + pattern detection) after upload. Set to `false` to upload without analysis — useful for backfills.
</ParamField>

<Note>
  Total request body size is capped at approximately 5 MB. For larger datasets, split into multiple requests or use the dashboard's file upload (which supports up to 500 MB per file).
</Note>

### Response — `201 Created`

```json theme={null}
{
  "data": {
    "id": "tr_01HXYZ...",
    "name": "Support ticket #4821",
    "model_name": "gpt-4o",
    "language": null,
    "source_system": null,
    "external_id": "ticket-4821",
    "external_user_id": null,
    "metadata": {},
    "turn_count": 2,
    "user_turn_count": 1,
    "assistant_turn_count": 1,
    "total_token_count": 18,
    "source_timestamp": null,
    "created_at": "2026-05-21T14:35:08.000Z",
    "processing_status": "queued"
  },
  "processing_time_ms": 187
}
```

<ResponseField name="data.id" type="string">
  The transcript ID. Use this in subsequent calls to fetch detail.
</ResponseField>

<ResponseField name="data.processing_status" type="string">
  One of:

  * `queued` — the annotation job was submitted to the pipeline
  * `skipped` — `process: false` was set; no analysis will run
  * `error` — the annotation job could not be submitted (the transcript was still created successfully)
</ResponseField>

### Error responses

| Status | Type                    | When                                                                                                                        |
| ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `invalid_request_error` | The `projectId` path parameter is not in `hp-{uuid}` format, the request body is malformed, or a required field is missing. |
| `401`  | `authentication_error`  | The API key is missing or invalid.                                                                                          |
| `403`  | `authorization_error`   | The key does not have the `projects-write` permission, or the project belongs to a different workspace.                     |
| `404`  | `not_found_error`       | The project does not exist.                                                                                                 |
| `413`  | `invalid_request_error` | The request body is too large (a single turn exceeds 1 MB, or the total payload exceeds the platform body limit).           |

## List transcripts in a project — `GET /projects/{projectId}/transcripts`

```bash theme={null}
curl -X GET "https://app.bigspin.ai/public/api/v1/projects/hp-550e8400.../transcripts?page=1&limit=50" \
  -H "Authorization: Bearer sk-bigspin-api03-your-api-key"
```

### Query parameters

<ParamField query="page" type="number" default="1">Page number (1-indexed).</ParamField>
<ParamField query="limit" type="number" default="20">Results per page. Max 100.</ParamField>
<ParamField query="q" type="string">Full-text search across transcript content.</ParamField>
<ParamField query="model_name" type="string">Filter by model name.</ParamField>
<ParamField query="language" type="string">Filter by language code.</ParamField>
<ParamField query="source_system" type="string">Filter by source system.</ParamField>
<ParamField query="annotation" type="string">Filter by annotation, formatted as `key:value`.</ParamField>
<ParamField query="date_from" type="string">ISO 8601 lower bound (inclusive) on `source_timestamp`.</ParamField>
<ParamField query="date_to" type="string">ISO 8601 upper bound (inclusive) on `source_timestamp`.</ParamField>

## Get a single transcript — `GET /transcripts/{transcriptId}`

```bash theme={null}
curl -X GET "https://app.bigspin.ai/public/api/v1/transcripts/tr_01HXYZ..." \
  -H "Authorization: Bearer sk-bigspin-api03-your-api-key"
```

Returns the transcript plus all turns and annotations. Returns `404 not_found_error` if the transcript ID is unknown or belongs to a different workspace.

## Next steps

* [Authentication](/api-reference/authentication) — set up your API key.
* [Projects API](/api-reference/projects) — create the project you'll upload into.
* [Upload transcripts via the dashboard](/projects/upload-transcripts) — for CSV/JSONL bulk loads up to 500 MB.
