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

# Presentation

> Let your PAL walk participants through a slide deck from your Knowledge Base.

The `presentation` skill lets the PAL present one or more slide decks (pdf) and images from your [Knowledge Base](/sections/conversational-video-interface/knowledge-base). The documents are injected into the PAL's conversation context so the PAL can speak to their content during the call.

<Note>
  **Which documents can be presented**

  Uploaded documents are prepared for presentation automatically - there is nothing to enable at upload time:

  * **PDFs up to 50 pages** and **images** are presentable.
  * **PDFs over 50 pages** are not presentable.
  * **Websites and other file types** (e.g. Word documents) are not presentable.
</Note>

## Adding a presentation skill to your PAL

Before you attach the presentation skill to your PAL, the documents must already exist in your Knowledge Base. See [Create Document](/api-reference/documents/create-document).

```bash theme={null}
curl --request PUT \
  --url https://tavusapi.com/v2/pals/{pal_id}/skills/presentation \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "config": {
      "document_ids": ["d1234567890", "d2468101214"],
      "slides_trigger": "walk_the_deck",
      "prompt": "Walk the participant through the Q4 roadmap deck, one slide at a time."
    }
  }'
```

## Configuration

| Field            | Type             | Required | Description                                                                                                                                                                                                                                                                                              |
| ---------------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `document_ids`   | array of strings | Yes      | The documents you want the PAL to present. For many use cases this will be just one pdf slide deck. At least one is required. Document IDs are returned by the [Create Document](/api-reference/documents/create-document) API endpoint. Each document must be owned by you and presentable (see above). |
| `slides_trigger` | string           | No       | How the PAL decides to present a slide: show a relevant slide based on the conversation (`on_demand`) or let the walk-through of the slide deck drive the conversation flow (`walk_the_deck`).                                                                                                           |
| `prompt`         | string           | No       | Custom instructions for how the PAL should present the material.                                                                                                                                                                                                                                         |

## Update the configuration

`PATCH` merges changes into the existing config - fields you omit are preserved:

```bash theme={null}
curl --request PATCH \
  --url https://tavusapi.com/v2/pals/{pal_id}/skills/presentation \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "config": {
      "slides_trigger": "on_demand"
    }
  }'
```

See [Skills Overview](/sections/conversational-video-interface/skills/overview) for how attachments work and the full [API reference](/api-reference/pal-skills/attach-skill-to-pal).

## Displaying the presentation video track in your app

<Note>
  If you embed with the [`@tavus/cvi-ui`](/sections/conversational-video-interface/component-library/blocks) [`Conversation`](/sections/conversational-video-interface/component-library/blocks#conversation-block) block, face video and screen share switching is built in - skip this section unless you are building a custom Daily React layout.
</Note>

When the PAL presents, the slide is **not** a separate participant in the call. It is published as a `screenVideo` track on the **same participant as the PAL's video** (its face video). Your frontend shows it by watching that participant's `screenVideo` track and rendering it when it becomes playable.

The examples below use [`@daily-co/daily-react`](https://docs.daily.co/reference/daily-react). All Daily components are client-side, so wrap your call UI in a `<DailyProvider>` and mark the components as client components. Import hooks and components from that package - for example `useParticipantIds`, `useParticipantProperty`, `DailyVideo`, and `DailyAudioTrack`.

<Steps>
  <Step title="Find the PAL's participant">
    The PAL is the remote participant with a playable video track. (A Tavus room can also contain a helper participant that has no video and only sends app-messages, so filter on a playable video track rather than taking the first remote participant.)

    ```tsx theme={null}
    const videoIds = useParticipantIds({
      filter: (p) => !p.local && p.tracks?.video?.state === "playable",
    });
    const remoteIds = useParticipantIds({ filter: "remote" });
    const replicaId = videoIds[0] ?? remoteIds[0] ?? null;
    ```
  </Step>

  <Step title="Watch the screen-share track">
    The slide is published as a `screenVideo` track on that same participant. Subscribe to its state so you know when the PAL starts sharing:

    ```tsx theme={null}
    const screenState = useParticipantProperty(replicaId ?? "", "tracks.screenVideo.state");
    const screenSharing = screenState === "playable" || screenState === "loading";
    ```

    `screenState` stays `off` until the PAL starts sharing, then transitions to `loading` and `playable`. Including `loading` lets your layout switch the moment the slide starts coming in instead of waiting for the first frame.
  </Step>

  <Step title="Render the right track">
    Show the slide when the PAL is sharing, and fall back to the face video otherwise. Both use the same `sessionId` - only the `type` differs (`screenVideo` for the slide, `video` for the face video):

    ```tsx theme={null}
    {replicaId && screenSharing ? (
      // The PAL is sharing - show the slide
      <DailyVideo
        sessionId={replicaId}
        type="screenVideo"
        autoPlay
        style={{ width: "100%", height: "100%", objectFit: "contain" }}
      />
    ) : replicaId ? (
      // Not sharing - show the face video
      <DailyVideo
        sessionId={replicaId}
        type="video"
        autoPlay
        style={{ width: "100%", height: "100%", objectFit: "cover" }}
      />
    ) : (
      <p>Waiting for the PAL...</p>
    )}

    {/* Render the PAL's audio independently so it plays in either layout */}
    {replicaId && <DailyAudioTrack sessionId={replicaId} type="audio" autoPlay />}
    ```

    Use `objectFit: "contain"` for the slide so documents are never cropped, and `"cover"` for the face video. When the slide is the main view, a common pattern is to keep the face visible as a small picture-in-picture by rendering a second `<DailyVideo sessionId={replicaId} type="video" />` in a corner.
  </Step>
</Steps>

<Note>
  The `screenVideo` track is lazy: it does not exist until the PAL starts sharing. Don't block or error on a missing screen track when the call connects - just render the face video and switch to the slide once `screenVideo.state` becomes `playable`. If a slide isn't appearing, logging `screenState` makes it clear whether the track is never publishing or your frontend simply isn't rendering it.
</Note>

## Troubleshooting

Documents must be fully processed for presentation before they can be attached. The API rejects the configuration with a `400` if any document is still processing or not presentable (too long, a website, or an unsupported file type). Wait for the document's processing to finish before attaching it.
