pdf_documents
Convert a Microsoft Office document (.docx, .xlsx, .pptx) or inline markdown into a PDF, then deliver it as an email attachment or save it to OneDrive.
What it does
pdf_documents is a single agent tool, with one action (create), that dispatches to two pure converters:
- Office formats (
.docx,.xlsx,.pptx,.mdalready in OneDrive) are converted via Microsoft Graph's built-in?format=pdfendpoint. - Inline markdown is rendered with the
md-to-pdfheadless-Chromium pipeline using one of the bundled themes (default,business-case).
The tool can store the PDF as a generated asset (the default), return it inline as base64, write it to OneDrive, or do both of the last two. Cross-tenant isolation is enforced by construction: the tool always uses the caller's delegated Graph token and the caller's tenant for OneDrive writes, and generated assets are stored under the caller's tenant; no tenantId parameter is accepted.
When to pick it
Use pdf_documents.create when an agent needs to:
- Produce a PDF from an Office document already stored in OneDrive or SharePoint.
- Render an agent-authored markdown report (status update, business case, daily brief) into a polished, themed PDF that can be attached to email, posted to a project, or saved to OneDrive.
- Convert a small batch of files in-place without exposing the conversion mechanics to the caller.
It is not the right tool for:
- OpenDocument or legacy Office formats (
.odt,.doc,.rtf). - Excel sheet-selection or fit-to-page rendering controls.
- PDF post-processing (watermarks, page numbers, merging documents).
- Inline non-markdown bytes - pass
.docx/.xlsx/.pptxthrough OneDrive (document) instead.
Input examples
Provide exactly one of content (inline markdown) or document (an existing drive item to convert).
document (Office format already in OneDrive)
{
"document": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
},
"deliverTo": "onedrive",
"destination": {
"folderPath": "/Reports/2026-Q1"
}
}
When deliverTo is "onedrive" and destination.folderPath / destination.filename are omitted, the PDF is written next to the source item with the same base filename plus .pdf.
content (inline markdown)
{
"content": "# Q1 Status\n\nProgress against goals...",
"filename": "q1-status.md",
"theme": "business-case",
"deliverTo": "onedrive",
"destination": {
"folderPath": "/Outermind Artifacts/PDFs"
}
}
theme is honored for inline markdown only; it is ignored on the document path. Themes are CSS files keyed by name (currently default and business-case). style (house or plain) selects whether the organization's letterhead, fonts and colors are applied; it defaults to house.
deliverTo: asset (default, deliverable as an email attachment)
{
"content": "# Website Redesign Proposal\n\nPrepared for ...",
"filename": "proposal"
}
deliverTo defaults to "asset". The PDF is stored as a private, tenant-scoped generated asset and the response carries asset_id, url, content_type, and filename, with no onedrive block. The PDF bytes themselves are never returned in the response.
This is the mode that lets an agent actually send someone a PDF. The agent passes the returned asset_id to the attachments parameter of messages.reply or messages.send:person, and the bytes travel with the outgoing email as a real file attachment. Two things to know:
- The
urlis an authenticated in-app link. It requires a signed-in Outermind session, so it must not be pasted into email body text - an external recipient gets a 401. - The delivered attachment is named from the asset id, not from
filename. Thefilenamefield is an echo for the agent's own reference.
deliverTo: inline (alias for asset, no OneDrive write)
{
"content": "# Daily Brief\n\n...",
"filename": "daily-brief.md",
"deliverTo": "inline"
}
"inline" behaves exactly like "asset": the response carries asset_id, url, content_type, and filename, and no onedrive block. It used to return the encoded PDF as pdfBase64, which put a multi-megabyte string into the agent's own conversation and could exhaust its context window; the bytes now travel on the asset rail instead.
deliverTo: both (save an asset AND save to OneDrive)
{
"document": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
},
"deliverTo": "both",
"destination": {
"folderPath": "/Reports/2026-Q1",
"filename": "summary.pdf"
}
}
The response carries both the asset fields (asset_id, url, content_type, filename) and an onedrive block (driveId, itemId, webUrl).
deliverTo: onedrive (save only)
{
"document": {
"driveId": "b!abc...",
"itemId": "01XYZ..."
},
"deliverTo": "onedrive"
}
The response carries an onedrive block and no asset fields. "onedrive" needs a target drive: with a document source it defaults to the source item's own drive, but an inline markdown source has no drive to fall back on, so destination.driveId is required there.
Error codes the agent can react to
The tool returns a structured error envelope on failure. Each error declares retryable so the agent can decide between immediate retry, escalation, or a different approach.
| Code | Meaning | Retryable |
|---|---|---|
unsupported_format | The document source is not a format Graph can convert (e.g., .txt, .zip). | No |
graph_conversion_failed | Microsoft Graph returned a server error during conversion. One automatic retry has already been attempted. | Yes |
render_failed | The markdown render pipeline failed or timed out. | Yes (re-render may succeed; reduce input size if persistent) |
source_not_found | The document driveId/itemId does not exist or the caller cannot access it (404 or 403). Often a permissions problem rather than a missing file. | No |
input_too_large | Inline markdown exceeded 5 MB, or the source document exceeded 50 MB. | No |
destination_unavailable | The output target could not be reached: on "onedrive"/"both" no target drive was resolvable, or the drive is offline / over quota / permission-denied; on "asset" the generated-asset store rejected the write. | Yes (No when the OneDrive target simply was not supplied) |
Agent guidance for common cases:
source_not_found: surface the failure to the user with a request to verify the file path or share permissions; do not retry blindly.input_too_large: shrink the markdown (trim verbose sections, drop large embedded images) or split the source document; retry once with the smaller input.destination_unavailable: fall back todeliverTo: "asset"to get anasset_idthat can be attached to a reply, or todeliverTo: "inline"to return the base64 PDF, then ask the user where to save it.
Limits
| Limit | Value | Where enforced |
|---|---|---|
| Inline markdown input size | 5 MB | markdown-pdf converter |
Source file size (document) | 50 MB (pre-checked via Graph metadata) | graph-format-pdf converter |
| Markdown render timeout | 30 seconds | markdown-pdf converter |
| Graph 429 retry | One automatic retry honoring Retry-After | graph-format-pdf converter |
Telemetry: every call emits one structured tool-call log entry with { tool, durationMs, sourceKind, sourceFormat, outputMode, byteSize, ok, errorCode? }.
Default availability
pdf_documents.create is available to every agent, with no per-agent assignment. It is one of the platform's built-in tools, alongside spreadsheets.create, word_documents.create and presentations.create: the platform supplies it directly to each agent rather than an administrator assigning it, so there is no per-agent switch to flip and nothing for an agent to request. (One organization-wide permission does still apply to pdf_documents; see below.) This applies to your AI Chief of Staff, every Personal Assistant, every specialist agent and every subject matter expert alike.
Because it is built in rather than assigned, it does not appear in an agent's tool assignment panel and cannot be withheld from an individual agent.
pdf_documents also still appears in the Media & Document Generation tool group (which absorbed the former Document Conversion group). That listing is what lets an agent discover the tool by searching its capabilities; it is not a permission.
One thing an administrator does still control: pdf_documents.create can read source documents from, and write finished PDFs back to, SharePoint and OneDrive, so it is covered by your organization's SharePoint and OneDrive document permission. That permission is checked once per tool rather than per request, so until it is granted agents are not offered pdf_documents at all - including for Markdown-only requests that would never touch SharePoint. The other three built-in document tools (spreadsheets, word_documents, presentations) are not covered by it and are available either way.
Related tools
spreadsheets(createaction) - author a new.xlsxworkbook, delivered through the same generated-asset rail.word_documents(createaction) - author a new.docxWord document from Markdown, on the same rail.presentations(createaction) - author a new.pptxslide deck from structured slide data, on the same rail.onedrive_files(createaction) - generic OneDrive write for non-PDF artifacts.projects(linkaction) - record the resulting PDF on a CAIOO project page.