---
"@context": https://schema.org
"@type": TechArticle
"@id": https://www.twilio.com/docs/conversation-intelligence-classic/integrations/transcripts-single-page-app#article
headline: Transcripts Integration Guide
description: Learn how to integrate the Conversation Intelligence (classic) Transcripts single-page application into a web application.
url: https://www.twilio.com/docs/conversation-intelligence-classic/integrations/transcripts-single-page-app
inLanguage: en
dateModified: 2026-08-20T18:09:16.000Z
author:
  "@type": Organization
  name: Twilio Developer Education Team
publisher:
  "@type": Organization
  name: Twilio
---

# Transcripts Integration Guide

This guide explains how to integrate and use the Transcripts single-page application in an existing web application. The Transcripts single-page application allows users to filter and view summary details of Conversation Intelligence (classic) [Transcripts](/docs/conversation-intelligence-classic/api/transcript-resource) of recorded conversations created in the past 90 days. Optionally, you can add the ability to view individual Transcripts in detail.

> \[!NOTE]
>
> In past pre-release documentation, the Transcripts single-page application was called Discovery. The old name is still used in some places, such as app retrieval URLs.

![Transcripts table showing date, agent, customer, direction, duration, and language results.](https://docs-resources.prod.twilio.com/d9086d6e3df3bcb53138af13e5b581c1e9f73a21f393658db5d39b6f2fd74620.png)

You can embed the single-page application's UI into an existing web app or render it in a new window. In both cases, the app requests the single-page application's code by calling a specific URL with an authorization token.

Search terms entered in the **Phrases** search box are linked with the OR operator. For example, searching for the phrase `macaroni salad` will match Transcripts that contain `macaroni` OR `salad`.

A [sample implementation of the single-page application](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) is available on GitHub for reference.

## Prerequisites

Before you begin, complete these steps:

* [Create a Twilio Account](https://www.twilio.com/try-twilio).
  * Note the Account SID from the [Console](https://console.twilio.com/).
  * [Create an API key](/docs/iam/api-keys/keys-in-console) and note its SID and secret. The code samples use these as `API_KEY` and `API_SECRET`.

## Instructions

The following steps explain how to integrate the Transcripts single-page application into a web app. The integration can be completed before a [Intelligence Service](/docs/conversation-intelligence-classic/onboarding#services) with associated [Transcriptions](/docs/conversation-intelligence-classic/api/transcript-resource) is created, although the single-page application will render with an error.

To view a specific Transcript, you need to link the single-page application to the Transcription Viewer single-page application. This is an optional step. See [Step 3 (Optional): Link with the Transcription Viewer single-page application](#step-3-optional-link-with-the-transcription-viewer-single-page-application) for more information.

### Step 1: Create a one-time token (OTT)

The Transcripts single-page application requires a short-lived, single-use token called a one-time token (OTT) to start a session. The OTT is used to obtain scoped Conversation Intelligence (classic) API access so the single-page application can fetch Transcripts to populate the table. The scoped API access is limited to one hour in a single user session. Token refresh isn't supported.

> \[!CAUTION]
>
> The request to create an OTT uses global Twilio Account credentials and requires a secure backend server. Don't expose Twilio Account credentials on the frontend.

#### Request an OTT

Make a `POST` request to the following endpoint to request an OTT:

```bash
POST https://ai.twilio.com/v1/Tokens
```

To authenticate requests to the Twilio APIs, Twilio supports [HTTP Basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). Use your *API key SID* as the username and your *API key secret* as the password. You can create an API key [in the Twilio Console](/docs/iam/api-keys/keys-in-console) or [using the API](/docs/iam/api-keys/key-resource-v1).

Learn more about [Twilio API authentication](/docs/usage/requests-to-twilio).

#### OTT request body parameters

The OTT request body supports the following parameters. Note that some parameters are only required if linking with the Transcription Viewer single-page application in [Step 3](#step-3-optional-link-with-the-transcription-viewer-single-page-application).

| Parameter Name                                            | Description                                                                                                                                                                                                                                       | Type      | Required?                                                              |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ---------------------------------------------------------------------- |
| `ott_ttl`                                                 | A field that specifies a custom OTT expiry period in seconds, also known as time-to-live (TTL). If unspecified, the default is `60` seconds.                                                                                                      | `integer` | No                                                                     |
| `grants`                                                  | An array of `grant` objects, containing the properties `product` and `metadata`. Only one `grant` is required for the Transcripts single-page application.                                                                                        | `array`   | Yes                                                                    |
| `grants[].product`                                        | A field that specifies the product functionality. Must be set to `intelligence-discovery` for the Transcripts single-page application.                                                                                                            | `string`  | Yes                                                                    |
| `grants[].metadata`                                       | An object containing metadata.                                                                                                                                                                                                                    | `object`  | No                                                                     |
| `grants[].metadata.defaultServiceSids[]`                  | An array of Service SID strings. If provided, the single-page application only fetches Transcripts associated with the given Service SIDs. If unspecified, the single-page application fetches all Transcripts associated with the given Account. | `array`   | No                                                                     |
| `grants[].metadata.viewLinks`                             | An object containing a `conversationViewLink` object.                                                                                                                                                                                             | `object`  | Yes, if linking with the Transcription Viewer single-page application. |
| `grants[].metadata.viewLinks.conversationViewLink`        | An object containing the `target` and `href` properties for the Transcript view link.                                                                                                                                                             | `object`  | Yes, if linking with the Transcription Viewer single-page application. |
| `grants[].metadata.viewLinks.conversationViewLink.target` | The target of the Transcript view link. Typically set to `_top` to view the Transcript in the same window or `_blank` in a new window.                                                                                                            | `string`  | Yes, if linking with the Transcription Viewer single-page application. |
| `grants[].metadata.viewLinks.conversationViewLink.href`   | A static URL with placeholders used to generate links to view specific Transcripts. See [href parameter](#href-parameter) for more details.                                                                                                       | `string`  | Yes, if linking with the Transcription Viewer single-page application. |

##### href parameter

The value of the `href` parameter depends on if the Account has any Intelligence Services with PII redaction enabled.

* If PII redaction isn't enabled on any of the Account's Intelligence Services, set `href` to:

```bash
http://localhost:8080/annotator/standalone?serviceSid=:serviceSid&transcriptSid=:transcriptSid
```

* If PII redaction is enabled on one or more of the Account's Intelligence Services, set `href` to:

```bash
http://localhost:8080/annotator/standalone?serviceSid=:serviceSid&transcriptSid=:transcriptSid&sensitive=:sensitive
```

The placeholder values for `href` don't need to be replaced in the OTT request. The placeholders are automatically replaced by the single-page application with the actual values for the Service SID, Transcript SID, and sensitive flag.

#### OTT Response properties

If the OTT request is successful, the response includes the following properties:

| Property Name | Description                                                                                              | Type     |
| ------------- | -------------------------------------------------------------------------------------------------------- | -------- |
| `token`       | The value of the OTT.                                                                                    | `string` |
| `expiration`  | The date and time of the OTT's expiration, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. | `string` |

#### Code samples

```js title="Request an OTT with the default 60 second TTL"
fetch("https://ai.twilio.com/v1/Tokens", {
  "headers": {
    "authorization": `Basic ${btoa(API_KEY + ":" + API_SECRET)}`,
    "content-type": "application/json"
  },
  "body": JSON.stringify({
    "grants": [{
        "product": "intelligence-discovery"
    }]
   }),
  "method": "POST"
});
```

```js title="Request an OTT with optional parameters"
fetch("https://ai.twilio.com/v1/Tokens", {
  "headers": {
    "authorization": `Basic ${btoa(API_KEY + ":" + API_SECRET)}`,
    "content-type": "application/json"
  },
  "body": JSON.stringify({
    "ott_ttl": 600,
    "grants": [{
      "product": "intelligence-discovery",
      "metadata": {
        "defaultServiceSids": ["GAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
      }
    }]
   }),
  "method": "POST"
});
```

```js title="Request an OTT if linking to the Transcription Viewer single-page application"
fetch("https://ai.twilio.com/v1/Tokens", {
  "headers": {
    "authorization": `Basic ${btoa(API_KEY + ":" + API_SECRET)}`,
    "content-type": "application/json"
  },
  "body": JSON.stringify({
    "grants": [{
      "product": "intelligence-discovery",
      "metadata": {
        "viewLinks": {
          "conversationViewLink": {
            "target": "_top",
            "href": "http://localhost:8080/annotator/standalone?serviceSid=:serviceSid&transcriptSid=:transcriptSid"
          }
        }
      }
    }]  
  }),
  "method": "POST"
});
```

### Step 2: Initialize and display the Transcripts single-page application

Next, use the OTT as a URL query parameter to create a single-page application initialization URL using the latest Transcripts single-page application build. This sample single-page application initialization URL assumes the OTT is stored in an environment variable named `TRANSCRIPTS_TOKEN`:

```bash
https://assets.twilio.com/public_assets/intelligence-discovery/latest/index.html?token=$TRANSCRIPTS_TOKEN
```

How the single-page application initialization URL is used depends on how the single-page application is displayed. The single-page application can be displayed by either embedding it into an existing web app or rendering it in a new window.

#### Display option 1: Embed the single-page application

The Transcripts single-page application can be embedded into an existing web app using an HTML iframe. Add the single-page application initialization URL to an iframe tag as seen below, noting that the `$TOKEN` variable must be generated from the backend:

```html
<iframe src="https://assets.twilio.com/public_assets/intelligence-discovery/latest/index.html?token=$TOKEN" allow="clipboard-read; clipboard-write;">
```

Review the [demo app](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) for sample implementations of the [frontend](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/views/transcripts-embedded.ejs) and [backend](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/src/server/index.js#L18) of an embedded single-page application.

#### Display option 2: Render the single-page application in a new window

To display the Transcripts single-page application in its own browser window, redirect a window to the single-page application initialization URL:

```js
app.get('/transcripts/standalone', async (req, res) => {
    const token = await client.getTranscriptsToken();
    let url = `${transcriptsAssetUrl}?token=${token}`;
    return res.redirect(url);
});
```

Review the [demo app](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) for a sample implementation of the [backend](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/src/server/index.js#L31) of a single-page application.

### Step 3 (Optional): Link with the Transcription Viewer single-page application

You can add the ability to view an individual Transcript's details by linking the Transcripts single-page application to the [Transcription Viewer single-page application](/docs/conversation-intelligence-classic/integrations/transcription-viewer-single-page-app). When you link the two single-page applications, the option to select **View** for a specific Transcript becomes available under the **Actions** column of the Transcripts single-page application.

To link the Transcripts single-page application to the Transcription Viewer single-page application, a new endpoint must be added to handle the Transcription Viewer single-page application requests.

#### Create a new endpoint

Add a new endpoint to handle the Transcript Viewer single-page application requests with the path `/transcript-viewer/standalone`. This endpoint is called whenever a user selects a **View** link for a Transcript in the Transcripts Viewer single-page application. The endpoint should receive a Service SID and Transcript SID as query parameters, request a Transcription Viewer single-page application OTT, and return a Transcription Viewer single-page application initialization URL.

Review the [demo app](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) for a sample implementation of the [Transcript Viewer endpoint](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/src/server/index.js#L41).

##### Request a Transcription Viewer OTT

The Transcription Viewer OTT is used to obtain scoped Conversation Intelligence (classic) API access so the Transcription Viewer single-page application can fetch an individual Transcript. A new Transcription Viewer OTT must be created for each Transcript that the user wants to view.

The OTT request body supports the following parameters.

| Parameter Name            | Description                                                                                                                                                                       | Type      | Required? |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------- |
| `ott_ttl`                 | A field that specifies a custom OTT expiry period in seconds, also known as time-to-live (TTL). If unspecified, the default is `60` seconds.                                      | `integer` | No        |
| `grants`                  | An array of `grant` objects. Only one `grant` is required for the Transcription Viewer single-page application.                                                                   | `array`   | Yes       |
| `grants[].product`        | A field that specifies the product functionality being requested by the single-page application. Must be set to `annotator` for the Transcription Viewer single-page application. | `string`  | Yes       |
| `grants[].service_sid`    | The SID of the Intelligence Service associated with the Transcription.                                                                                                            | `string`  | Yes       |
| `grants[].transcript_sid` | The SID of the Transcription.                                                                                                                                                     | `string`  | Yes       |

Review the [demo app](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) for a sample implementation of the [Transcription Viewer single-page application OTT request](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/src/server/client.js#L8).

```js title="Request an additional OTT for the Transcription Viewer single-page application"
var serviceSid = "GAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
var transcriptSid = "GTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

fetch(
  'https://ai.twilio.com/v1/Tokens',
  {
    method: 'POST',
    headers: {
      Authorization: `Basic ${twilioEncodedCreds}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      grants: [{
        product: 'annotator',
        service_sid: serviceSid,
        transcript_sid: transcriptSid
      }]
    })
  }
);
```

##### Create a Transcription Viewer single-page application initialization URL

To create the Transcription Viewer single-page application initialization URL, use the latest Transcription Viewer single-page application build and the OTT as a query parameter. The sample initialization URL below assumes the OTT is stored in an environment variable named `TRANSCRIPTION_VIEWER_TOKEN`:

```bash
https://assets.twilio.com/public_assets/annotator/latest/index.html?token=$TRANSCRIPTION_VIEWER_TOKEN
```

To display the Transcription Viewer single-page application, redirect a window to the single-page application initialization URL:

```js
app.get('/transcript-viewer/standalone', async (req, res) => {
    const serviceSid = req.query.serviceSid;
    const transcriptSid = req.query.transcriptSid;
    if (serviceSid && transcriptSid) {
        const token = await client.getTranscriptViewerToken(serviceSid, transcriptSid);
        const url = `${transcriptViewerInitializationUrl}?token=${token}`;
        return res.redirect(url);
    }
```

Review the [demo app](https://github.com/twilio/voice-intelligence-samples/tree/main/transcripts-integration-demo) for a sample implementation of the [Transcription Viewer endpoint](https://github.com/twilio/voice-intelligence-samples/blob/main/transcripts-integration-demo/src/server/index.js#L41).
