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

# Files

> Turn a file on the Lua CDN into text from a tool

`Files.toText()` turns a file on the Lua CDN into text: Word, Excel, PowerPoint, email, PDF and other documents, scanned images (OCR), and audio or video (speech-to-text). It's the same converter the platform uses for attachments in chat. Only files on the Lua CDN are read, so upload a file with [`CDN.upload`](https://docs.heylua.ai/reference/sdk/cdn) first and pass the id it returns.

*Verified against lua-cli 3.62.0.*

```ts theme={null}
import { Files } from "lua-cli";
```

## Quick example

```ts theme={null}
import { CDN, Files } from "lua-cli";

const fileId = await CDN.upload(
  new File([bytes], "minutes.doc", { type: "application/msword" }),
);
const { text, truncated, error } = await Files.toText(fileId, {
  maxChars: 50_000,
});

if (error) {
  return `I couldn't read that file: ${error.message}`;
}
```

## Methods

### toText()

```ts theme={null}
Files.toText(url: string, options?: { maxChars?: number }): Promise<FilesToTextResult>
```

The parameter is named `url`, as in the SDK typings, but it takes either form: a file id or a full Lua CDN URL.

| Parameter | Type | Description |
| - | - | - |
| `url` | `string` | The file id `CDN.upload` returns, or the file's Lua CDN URL |
| `options.maxChars` | `number` | Cap on the returned text. Default 300,000, at most 1,000,000 |

Set the file's type when you upload it (`new File([bytes], name, { type })`). The type is how the converter is picked, and a file stored without one comes back as `mime_unknown`.

### FilesToTextResult

| Field | Type | Description |
| - | - | - |
| `text` | `string` | The file's text. Empty only when `error` is set |
| `mime` | `string` | The file's type, when known |
| `truncated` | `boolean` | `true` when `text` was cut to `maxChars` |
| `chars` | `number` | Length of `text` |
| `error` | `{ code, message }` | Set when the file gave no text |

## Errors

A file that gives no text resolves with an empty `text` and an `error`, never an empty string on its own:

| `error.code` | Meaning |
| - | - |
| `not_cdn_url` | Not a Lua CDN file id or URL. Upload it with `CDN.upload` first |
| `private_artefact_unsupported` | A private room file. Upload a copy with `CDN.upload` |
| `mime_unknown` | The file was stored without a type. Upload it again with `type` set |
| `unsupported_type` | This type can't be turned into text (a zip, for example) |
| `too_large` | Over 100 MB |
| `fetch_failed` | The file couldn't be read from the CDN |
| `conversion_failed` | The conversion failed. `message` says why |
| `timeout` | The conversion took longer than its time limit (40 seconds) |
| `empty_text` | The file had no text in it |

The call throws an error named `FilesToTextError` only when the call itself is refused: `billing_refused` when the workspace is out of credits or billing can't be reached, and `files_unavailable` when the runtime doesn't support it. Inside a test session it throws `test_session_tier_unsupported`. Under `lua test` the call goes through the Lua API, so a platform outage throws `UPSTREAM_UNAVAILABLE` instead.

## Usage and limits

* A call from a deployed tool uses one credit once the file passes its checks (it's on the CDN, has a known, supported type, and is under 100 MB). A conversion that then fails still uses that credit. Calls from `lua test` are free.
* Files up to 100 MB. A conversion gets 40 seconds.
* Supported documents include doc, docx, xls, xlsx, ppt, pptx, odt, rtf, eml, msg, epub, pdf, csv, html and markdown; images (jpeg, png, tiff, bmp, heic) are read with OCR; audio and video go through speech-to-text.
* Plain-text files (txt, csv, tsv, markdown, json) come back exactly as stored, line breaks and commas included. `maxChars` cuts them at a character count, so a cut CSV or JSON can end mid-row or mid-object (check `truncated`).


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