> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cloudraker.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cloudraker.com/_mcp/server.

# File tools

The capabilities read documents. **File tools** operate on the bytes. The tools are deterministic and cost no inference. Each tool works on a file that already exists in your corpus.

Every tool exists twice, from one implementation:

| Scope                                   | Path                           |
| --------------------------------------- | ------------------------------ |
| The hidden org workspace                | `/v1/files/…`                  |
| An explicit [space](/developers/spaces) | `/v1/spaces/{spaceId}/files/…` |

## Refer to a file by id or by name

`{ref}` in every path below is the file id **or** the file name. `GET /v1/files/{id}` accepts the same values:

```bash
curl -X POST https://api.cloudraker.com/v1/files/msa.docx/convert/pdf \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY"
```

The API resolves a name inside one scope only, over the newest files there. Two files with the same name return `409 ambiguous_file_name`. A scope too crowded to search safely returns `409 file_listing_truncated`. In both cases, pass the id.

## The six tools

| Tool                | Path                                    | Produces                                     |
| ------------------- | --------------------------------------- | -------------------------------------------- |
| Convert to Markdown | `POST /v1/files/{ref}/convert/markdown` | **Text in the response.** Nothing is stored. |
| Convert to PDF      | `POST /v1/files/{ref}/convert/pdf`      | A new PDF file                               |
| Render a page       | `POST /v1/files/{ref}/convert/image`    | A new PNG file                               |
| Split pages         | `POST /v1/files/{ref}/split/pages`      | One new PDF per page                         |
| Stitch              | `POST /v1/files/stitch`                 | One joined file                              |
| Redline             | `POST /v1/files/{ref}/redline`          | A [redlining session](#redlining)            |

Every tool except the Markdown conversion writes a **new file beside the source**. The new file has the same space and a `parentFileId` that points to the original. The new file is never indexed for search. The original is the indexed file.

### Convert to Markdown

Returns the file as Markdown text. If the file was already parsed, this returns the Markdown from that parse at no extra cost. Otherwise, the tool converts the bytes on the spot. The answer is the same in both cases.

### Convert to PDF

Converts a Word document, spreadsheet, presentation, image, or plain-text file into a PDF. A file that is already a PDF returns `400`. A type that cannot be converted returns `422 unsupported_file_type`.

### Render a page

```json
{ "page": 1, "scale": 2 }
```

`page` is 1-based and defaults to the first page. `scale` runs from `0.1` to `6` and defaults to `2`. The long edge is capped at 4000 pixels in all cases. The tool renders PDFs only. Convert other types first.

### Split pages

Splits a PDF into single-page PDFs named `<original>.p<n>.pdf`. Each carries `parentFileId`.

**Caps:** more than 100 pages returns `413 too_many_pages`. Larger than 15 MB returns `413 too_large`.

### Stitch

```json
{ "files": ["call-part1.mp3", "call-part2.mp3"] }
```

Joins 2 to 20 files in the order you list them. Each entry is an id or a name. Every file must be the same kind:

* **Audio** — concatenated. `format` (`mp3`, `m4a`, `wav`) forces the output container. Without it, the output keeps the inputs' container. Named `<first>.joined.<ext>`.
* **PDF** — merged into one file, named `<first>.merged.pdf`.

Mixed kinds return `400`. **Cap:** 40 MB across all inputs. More returns `413 too_large`.

## Redlining

Redlining is the one tool with a session. It opens an editing session on a `.docx` so you can rewrite it with tracked changes.

```bash
curl -X POST https://api.cloudraker.com/v1/files/msa.docx/redline \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ttl": 86400 }'
```

```json
{
  "object": "redline_session",
  "id": "rdl_01K9Z6P2R4",
  "fileId": "a04d6597-4e34-4a99-94ea-964c289a4c68",
  "expiresAt": "2026-08-16T09:12:00.114Z",
  "revision": 0
}
```

`ttl` is 60 to 604800 seconds. A file that is not a Word document returns `422`. Nothing goes back into your corpus until you flush.

Then work on the session at `/v1/redline/{sessionId}`:

| Route                                                                | What it does                                                                                                                            |
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/redline/{sessionId}`                                        | Returns the session: filename, revision, and counts.                                                                                    |
| `GET /v1/redline/{sessionId}/content`                                | Returns the document's text, block by block.                                                                                            |
| `POST /v1/redline/{sessionId}/edits`                                 | Applies one edit: `replace`, `deleteText`, `fill`, or `insertMarkdown`. Edits are tracked by default. `tracked: false` writes silently. |
| `GET /v1/redline/{sessionId}/suggestions`                            | Lists every tracked change, with author and a snippet.                                                                                  |
| `POST /v1/redline/{sessionId}/suggestions/apply`                     | Accepts or rejects in bulk (`accept`, `reject`).                                                                                        |
| `POST /v1/redline/{sessionId}/suggestions/{tcId}/accept` / `/reject` | Accepts or rejects one tracked change.                                                                                                  |
| `GET /v1/redline/{sessionId}/revisions`                              | Returns the session's revision history.                                                                                                 |
| `POST /v1/redline/{sessionId}/flush`                                 | Exports `<original>.redlined.docx` and stores it beside the source.                                                                     |

```json
{ "op": "replace", "anchorText": "thirty (30) days", "replacement": "sixty (60) days" }
```

**Tracked-change ids are positional.** They are valid only at the revision that produced them. Any edit renumbers them. List the suggestions immediately before you accept or reject.

Flush takes the file the session was opened on, by id or by name:

```json
{ "fileId": "msa.docx" }
```

A different file returns `409 redline_file_mismatch`. Names resolve in the org workspace only. Flush a file in a space by id. The session stays open after a flush. You can flush many times.

## Next steps

#### [Files](/developers/files)

Register documents and use presigned uploads.

#### [Spaces](/developers/spaces)

Run the same tools inside a named container.

#### [Parse](/capabilities/parse)

Use a model-quality reading instead of a byte conversion.

#### [Errors](/developers/errors)

Read the full `409` and `413` codes shown above.