# Tool reference

> The 25 tools a connected AI assistant can call in Korala, with inputs and the permission each one needs.

Source: https://docs.korala.ai/ai-agents/tools

---

A connected assistant calls these tools. Each call goes through Korala's public HTTP API, so quota, billing, validation and the audit trail apply as they do for any integration.

The **Permission** column names the choice on the [consent page](https://docs.korala.ai/ai-agents/permissions). **View** stands for "View documents and templates".

A permission covers more than the tools listed under it. The connection's token works against the REST API directly. **Create and edit templates** also allows deleting, duplicating and replacing the file of any template in your organization. **Prepare documents** also allows renaming a draft and removing its recipients and fields.

## Drafts

| Tool | What it does | Inputs | Permission |
| --- | --- | --- | --- |
| `create_draft_link` | Turns a Markdown agreement into an "Open in Korala" link. You open the link, review the rendered draft and choose **Save in Korala**. The tool saves and sends nothing. Anyone with the link can read the draft, so use example data. | `name`, `source`, `sampleData`?, `pageSize`? (`A4` or `Letter`) | None. Works with no account through the local [`@korala/mcp`](https://docs.korala.ai/ai-agents/api-key#draft-only-mode) package. |

The draft travels in the URL fragment, which your browser does not send to a server. The encoded draft can hold up to 65,536 characters.

## Templates

| Tool | What it does | Inputs | Permission |
| --- | --- | --- | --- |
| `list_templates` | Lists the reusable templates in your organization. | `search`?, `page`?, `limit`? (1 to 100) | View |
| `get_template` | Returns one template with its signer roles and fields. Markdown templates include source and revision. | `templateId` | View |
| `preview_markdown_template` | Renders a Markdown agreement without saving it. Returns the page count, the variables it expects and the signature roles it declares. | `source`, `sampleData`?, `pageSize`? | View |
| `create_markdown_template` | Saves a Markdown agreement as a reusable template. Each `::signature` role becomes a signer role. Saving sends nothing. | `name`, `description`?, `source`, `sampleData`?, `pageSize`? | Create and edit templates |
| `create_document_from_template` | Creates a draft document from a template. You assign one person to each signer role and supply the data that fills the template. Nothing goes out until `send_document`. This counts against your plan on plans that charge per document created from a template. | `templateId`, `name`, `signers` (`role`, `name`, `email` each), `templateData`? for Markdown templates, `variables`? for PDF and DOCX templates | Prepare documents |
| `add_template_field` | Adds a field to a template, so every document made from it carries that field. Places it by coordinates, against text found in each generated document, or at a Word bookmark. A Markdown template keeps its signature fields in its source and refuses fields added from outside. | `templateId`, `fieldType`, `width`, `height`, `signerRoleId`?, `placement`?, `pageNumber`?, `xPosition`?, `yPosition`?, `anchorText`?, `anchorPosition`?, `anchorOffsetX`?, `anchorOffsetY`?, `hideAnchor`?, `anchorMatchWholeWord`?, `bookmarkName`?, `mergeFieldName`?, `defaultValue`?, and the [field properties](#field-properties) | Create and edit templates |
| `update_template_field` | Changes a field on a template: moves it, resizes it, relabels it, reassigns it, or fixes a dropdown's choices. Documents already created from the template keep the fields they were made with. | `templateId`, `fieldId`, and any input `add_template_field` takes except `fieldType`, with `width` and `height` optional here | Create and edit templates |
| `remove_template_field` | Removes one field from a template. | `templateId`, `fieldId` | Create and edit templates |

`source` accepts up to 131,072 bytes, so text with non-ASCII characters reaches the limit sooner. See [Markdown templates](https://docs.korala.ai/guides/markdown-templates) for the syntax. `create_document_from_template` matches roles by name, ignores case, and fails when a role has no person or two people.

## Documents

| Tool | What it does | Inputs | Permission |
| --- | --- | --- | --- |
| `list_documents` | Lists documents, newest first. Filters by status or a name search. | `status`? (`draft`, `pending`, `completing`, `completed`, `failed`, `voided`, `expired`), `search`?, `page`?, `limit`? (1 to 100) | View |
| `get_document` | Returns one document with its status, its signers and who has signed, and its fields. A completed document includes a time-limited download URL for the signed PDF. | `documentId` | View |
| `get_audit_trail` | Returns the audit trail: created, sent, viewed, signed, declined and completed events with timestamps. | `documentId` | View |
| `request_pdf_upload` | For an assistant that cannot send a file. Creates an empty draft and returns a Korala page where the user uploads the PDF, signed in as themselves. When the user says the file is there, the assistant calls `confirm_upload`, which fails until it is and then describes the PDF. Chat apps that support MCP Apps show the link as a card. | `name`? | Prepare documents |
| `upload_attached_pdf` | Turns a PDF the user attached to the chat into a draft. ChatGPT passes an attachment to the tool as a temporary download link; Korala downloads it, refuses anything that is not a PDF or is over 25 MB, and never follows the link to a private address. Other assistants do not pass attachments to tools. | `file`, `name`? | Prepare documents, View documents |
| `create_upload_url` | Step 1 of a PDF upload. Returns a `documentId` and a presigned `uploadUrl`. The agent sends the file bytes to `uploadUrl` with `PUT`, then calls `confirm_upload`. | `filename`, `contentType` (`application/pdf`) | Prepare documents |
| `confirm_upload` | Step 2 of a PDF upload. Creates the draft document and tells the assistant what Korala found in the file: page count, whether it is a fillable form and how many fields it declares, and whether it has a text layer. `fieldOptions` lists the ways to place fields on that file. With `autoImportFormFields`, Korala places a fillable form's fields itself when the first signer is added. | `documentId`, `name`?, `autoImportFormFields`? | Prepare documents. The brief also needs View documents and templates |
| `get_form_fields` | Lists the fillable form fields inside an uploaded PDF, with page, position and size. An assistant cannot see the PDF, so it uses this to put a signature on the form's own signature line. Returns an empty list for a flat PDF; the assistant then uses `find_text`. | `documentId` | View documents and templates |
| `add_signer` | Adds a recipient to a draft. Sends nothing. The result says how many fields the signer already has, because a fillable PDF uploaded in the dashboard gets its form fields when the first signer is added. | `documentId`, `name`, `email`, `signingOrder`? | Prepare documents. The field count also needs View documents and templates |
| `import_form_fields` | Places the fields a fillable PDF declares, for one signer, exactly where the form draws them; read-only boxes are left out. Repeating it skips what an earlier import placed. It does not know about fields the assistant placed by hand, so it goes first. A large file is imported in the background, and the result says so. Returns an error for a flat PDF. Korala does the same by itself for a PDF uploaded in the dashboard, when the first signer is added. | `documentId`, `signerId`, `replaceExisting`? | Prepare documents |
| `update_field` | Moves, resizes, relabels or reassigns a field on a draft. For correcting a placement the assistant can see is wrong. Same coordinates as `add_field`. | `documentId`, `fieldId`, `signerId`?, `xPosition`?, `yPosition`?, `width`?, `height`?, and the [field properties](#field-properties) | Prepare documents |
| `remove_field` | Removes one field from a draft: a duplicate, or one placed by mistake. | `documentId`, `fieldId` | Prepare documents |
| `view_page` | Shows one page of an uploaded PDF as an image. Rulers are drawn on it in the units `add_field` takes (points from the top-left corner), so the assistant reads positions off the page instead of converting pixels. Fields already placed are outlined and captioned with a number and their type, so it can check where its field landed. The result lists each numbered field with its signer's name, as text, so a name in any script arrives intact. Refuses a rotated page. | `documentId`, `pageNumber`, `showFields`? | View documents and templates |
| `read_text` | Reads what an uploaded PDF says, a run of pages at a time, with columns kept side by side as printed. Only for an assistant that cannot read the file itself: one handed a document it has never seen (you uploaded it in Korala, or through the upload link) uses this to learn who the parties are and what the label beside each blank is called, in any language, before it searches for it. An assistant that has the file reads it there and does not call Korala. One answer holds about 20,000 characters and says which page to continue from, so the number of pages is no limit; the file may be up to 25 MB. Scanned pages have no text; the assistant looks at those with `view_page`. | `documentId`, `fromPage`?, `toPage`? | View documents and templates |
| `find_text` | Finds a phrase in an uploaded PDF, or up to ten phrases in one call (`texts`), which costs Korala one read of the file instead of one per phrase. Each match comes with its page, its box and the whole line it sits on, so two "Signature" labels for different people can be told apart. Also returns page sizes and marks rotated pages. It reads files up to 25 MB and their first 150 pages. An assistant cannot see the PDF; this is how it finds the signature line on a flat one. | `documentId`, `text`?, `texts`? | View documents and templates |
| `add_field_at_text` | Places a field against a phrase in the PDF: to the right of it, above it, below it, to the left, or over it. Korala works out the coordinates, and above or below a label makes the field no taller than the blank there. It refuses a place with no room, a rotated page, and a signer who is not on the document. When the phrase appears more than once the assistant has to say which. | `documentId`, `signerId`, `fieldType`, `anchorText`, `occurrence`?, `position`?, `offsetX`?, `offsetY`?, `width`?, `height`?, and the [field properties](#field-properties) | Prepare documents |
| `add_field` | Places a field at exact coordinates, for a fillable PDF whose positions came from `get_form_fields`. The origin is the top-left corner of the page, `x` grows right and `y` grows down, as in an image; it is not the PDF-native bottom-left system. Units are PDF points (72 per inch), and `xPosition`/`yPosition` are the field's own top-left corner. An agent working from a rendered page multiplies pixel values by page points ÷ image pixels; see [Coordinates](#coordinates). Documents from a template carry their fields already, so this tool serves uploaded PDFs. Like `add_field_at_text` and `update_field`, it warns when the field lies on top of another field on the same page. | `documentId`, `signerId`, `fieldType`, `pageNumber`, `xPosition`, `yPosition`, `width`, `height`, and the [field properties](#field-properties) | Prepare documents |
| `find_blanks` | Where an uploaded PDF looks like it is waiting to be filled in: every ruled line and labelled blank, with the words printed against it, the whole line it sits on, and a box a field would fit. It does not say what any blank is for; the assistant has the label and decides. A line drawn as a graphic is not text and is not found this way, so `find_text` still covers those. For a fillable PDF, `import_form_fields` is better. | `documentId` | View documents and templates |
| `add_fields` | Places many fields in one call, each at coordinates or against text. Every entry is judged on its own: the answer says which were placed and why each of the others was not, so one bad entry does not cost the rest. The file is read once however many entries are anchored. | `documentId`, `fields` (each: `signerId`, `fieldType`, then either `pageNumber`/`xPosition`/`yPosition`/`width`/`height` or `anchorText`/`occurrence`?/`position`?, plus the [field properties](#field-properties)) | Prepare documents |
| `prepare_for_signature` | The one-call form for the simple case: one signer, one free place to sign, no signature field yet. It places that one. For anything else it places nothing and hands back the places it found and the signers still waiting, for the assistant to pair with `add_fields`. It will not pair them itself: the order blanks appear on a page has nothing to do with the order signers were added, and nothing printed on the page says whose a line is. | `documentId` | Prepare documents. Also needs View documents and templates |
| `send_document` | Sends a draft to its signers. This emails real people and counts against your plan. The one exception is a document made with a test-mode [API key](https://docs.korala.ai/ai-agents/api-key#setup). Without the permission, the tool returns a `reviewUrl` where you review and send the document yourself. | `documentId` | Send and void documents |
| `void_document` | Cancels a document so that nobody can sign it. You cannot undo a void. Without the permission, the tool returns a `reviewUrl`. | `documentId` | Send and void documents |

A trailing `?` marks an optional input.

## Field properties

Six field types: `signature`, `initials`, `date`, `text`, `checkbox` and
`dropdown`. A dropdown needs its `options`; without them the API refuses it,
because it would be a text box that only looks like a list.

`add_field`, `add_field_at_text`, `update_field` and the template field tools
all take the same properties, so a field built by an assistant is the same
field a person builds in Korala.

| Property | What it does |
| --- | --- |
| `label` | What the signer sees on the field. |
| `required` | Whether signing is blocked until it is filled. |
| `options` | The choices a dropdown offers, in order. |
| `editable` | For a field you prefill: whether the signer may change the value. |
| `sharedFill` | One signer owns the field; until they sign, any signer able to act may fill or correct it. Refused on signature and initials fields. |
| `maxLength` | Longest value a text field accepts. |
| `multiline` | A text field that takes more than one line. |
| `inputMask` | A fill pattern such as `###-##-####`. Each `#` takes one digit; Korala types the rest in. |
| `validationPattern`, `validationMessage` | A regular expression the value must match, and what the signer is told when it does not. |
| `dateFormat` | How a date renders, e.g. `MM/DD/YYYY`. |
| `fontSize`, `fontFamily`, `textAlign`, `textColor` | How the value is drawn. Omit `fontSize` to fit the size to the box. |
| `groupKey`, `groupRequired` | Ties checkboxes into one choice among several, and requires one of them. |
| `requiredWhenFieldId`, `requiredWhenValue` | Makes this field required only while another field holds a given value. |
| `acroFieldName`, `acroOptionValue` | Links the field to a fillable PDF's own form field, from `get_form_fields`, so the value is written through the form rather than drawn over it. |

On `update_field` and `update_template_field`, `acroFieldName`,
`acroOptionValue`, `inputMask`, `requiredWhenFieldId` and `requiredWhenValue`
also take `null`, which clears them.

Template fields add `mergeFieldName`, the name of the value that fills the
field when a document is created from the template, and `defaultValue`.

## Coordinates

Most placements need none: `import_form_fields` and `add_field_at_text` work from the PDF's own form and text. `add_field` is for the rest, and an agent that can render the PDF may place by eye. It needs three facts.

- **Origin and direction.** The origin is the top-left corner of the page. `x` grows to the right and `y` grows down, exactly like pixels in an image. PDF's own coordinate system starts at the bottom-left with `y` growing up; Korala does not use it, so an agent must never flip `y`.
- **Units.** PDF points, 72 to the inch. US Letter is 612 × 792 and A4 is 595 × 842. `find_text` returns the real size of every page.
- **What a position means.** `xPosition` and `yPosition` are the top-left corner of the field; `width` and `height` extend right and down from it.

An agent that holds the file should render it itself: that needs nothing from Korala but the rules above and the page size. Render the page by itself, for example `pdftoppm -r 72 -png`, where one pixel is one point. At another resolution multiply every pixel value by page points ÷ image pixels. A 1275-pixel-wide render of a 612-point page scales by 0.48, so a box at pixel (250, 1500) sized 375 × 83 becomes `xPosition` 120, `yPosition` 720, `width` 180, `height` 40.

An agent that cannot render the file, such as a chat assistant, calls `view_page`: it returns the page with rulers already in these units and outlines the placed fields, so it also serves to check a placement. Korala renders a page once and keeps the picture until the fields on that page change.

Do not measure a screenshot of a PDF viewer: its margins, toolbar and zoom make pixel positions meaningless. Do not place from an image on a rotated page, which `find_text` marks.

`create_upload_url` serves coding agents that hold the file and can make HTTP requests. A chat assistant uses `upload_attached_pdf` when the chat app hands it the attachment, and `request_pdf_upload` otherwise. See [Working with a PDF you already have](https://docs.korala.ai/ai-agents#working-with-a-pdf-you-already-have).

Korala marks `send_document` and `void_document` as destructive. Assistants that honor the mark, such as ChatGPT, ask you to confirm before they call either tool.

## Worked example

You are connected with **Send and void documents** off.

> **You:** I need an NDA for Anna Miller, anna@example.com. My company is Acme Inc.

The assistant calls `list_templates` with `search: "NDA"` and finds nothing. It writes a one-page mutual NDA in Markdown with two signature roles, `company` and `recipient`, and calls `preview_markdown_template`.

> **Assistant:** The draft is one page. It expects `company.name`, `recipient.name` and `effective_date`, and it has two signature roles: company and recipient. Who signs for Acme, and what is the effective date?

> **You:** I sign, james@acme.example, James Carter. Effective today.

The assistant calls `create_markdown_template`, then `create_document_from_template` with both signers and the data.

> **Assistant:** I saved the template "Mutual NDA" and created the document "NDA - Anna Miller". Its ID is `7d0c1f5e-2a4b-4c8d-9e1f-3b6a5c7d8e9f` and its status is draft. I have sent nothing.

> **You:** Send it.

The assistant calls `send_document`. The connection lacks the permission, so the tool returns a review link.

> **Assistant:** This connection cannot send. Review and send the document here: `https://korala.ai/documents/7d0c1f5e-2a4b-4c8d-9e1f-3b6a5c7d8e9f`

With **Send and void documents** on, the same call sends the document, and the assistant reports the status `pending`. Ask "Has Anna signed?" later, and the assistant answers from `get_document`.
