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

# Attachments, surveys, and email verification

> Upload files, collect satisfaction ratings, and verify a visitor's email with the Chat SDK

Add the interactive parts of a conversation to your own UI: file attachments,
satisfaction surveys, and email verification. Each one is optional.

## Attachments

Show an attach button only when file uploads are enabled for your chat, that is
when `state.config.features` includes `"file-upload"`.

### Send files

**1. Upload the files**

Pass `File` or `Blob` objects, such as the files from an
`<input type="file">`, or `{ name, type, data }`:

```javascript theme={null}
const results = await chat.uploadFiles(files, {
  onProgress: ({ name, loaded, total }) => showProgress(name, loaded / total),
});
```

`onProgress` reports bytes as they're sent in browsers and React Native. In
other runtimes it fires only when each file completes.

**2. Handle failed files**

You get one result per file, so one failed file doesn't fail the others:

```javascript theme={null}
const failed = results.filter((result) => !result.ok);
if (failed.length) showUploadErrors(failed.map((f) => `${f.name}: ${f.error}`));
```

**3. Send the message**

Pass the uploaded attachments with the message. The text can be empty:

```javascript theme={null}
const attachments = results.filter((result) => result.ok).map((result) => result.attachment);
if (text.trim() || attachments.length) {
  await chat.sendMessage({ text, attachments });
}
```

### Show received files

Each message has an `attachments` array of `{ name, path, type, size }`. Get a
short-lived download URL when the visitor opens one:

```javascript theme={null}
const url = await chat.getAttachmentUrl(message, attachment);
window.open(url, "_blank");
```

Request the URL on demand rather than in advance, because it expires. Messages
still sending have no URL yet.

## Satisfaction surveys

When a message has `kind: "csat_request"`, show a rating prompt. Load its text,
then submit a rating from 1 to 5 and an optional comment:

```javascript theme={null}
const { csatMessage, lastRating } = await chat.csat.getConfig();
showRatingPrompt(csatMessage, lastRating);

await chat.csat.submit({ rating: 5, comment: "Quick and helpful" });
```

`lastRating` and `lastComment` hold a previous answer, so you can show it
instead of asking again.

## Email verification

When the AI Agent needs to confirm who the visitor is, it sends a message with
`kind: "email_verification_requested"`. Show a form that asks for an email, then
for the code sent to it:

**1. Send the code**

```javascript theme={null}
await chat.verification.sendCode(email);
```

**2. Check the code**

```javascript theme={null}
const { success, reason } = await chat.verification.verifyCode(code);
```

If `success` is `false`, `reason` is `invalid_code`, `max_attempts`, or
`expired`.

**3. Confirm**

A message with `kind: "email_verification_verified"` arrives, and the
conversation continues.

To restore the form after a reload, call `chat.verification.getStatus()`:

**state** `string`

`none`, `awaiting_email`, `awaiting_code`, or `verified`. Show the email field
for `awaiting_email` and the code field for `awaiting_code`.

**email** `string`

The email the code was sent to.

**attemptsRemaining** `number`

How many more codes the visitor can try.

> [!TIP]
>
> If your visitors are signed in, pass their email as a [signed
> variable](https://docs.typewise.app/guides/channels/chat-sdk/page-context.md#identify-signed-in-users)
> instead. Verified values skip this step.

## Voice input

When `state.config.features` includes `"transcription"`, you can offer
speech-to-text. `chat.getTranscriptionKey()` returns a short-lived ElevenLabs
key to use with the ElevenLabs speech-to-text client. If you use a CSP, allow
`wss://api.elevenlabs.io` in `connect-src`.

## Related

* [Render messages and activity](https://docs.typewise.app/guides/channels/chat-sdk/render-messages.md)
* [API reference](https://docs.typewise.app/guides/channels/chat-sdk/api-reference.md)
* [Insights Hub](https://docs.typewise.app/documentation/insights-hub/overview.md): where satisfaction
  ratings show up


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.