Send Existing PDFs for E-Signature from Claude Desktop (send_document_pdf Guide)
Not every contract starts as AI-generated Markdown. When your wealth management firm, legal department, or enterprise sales team already has a bespoke PDF agreement, here are the three architectural methods for dispatching it directly from Claude Desktop, Claude Projects, and custom API pipelines with zero layout mutation.
Quick Answer (TL;DR)
Direct Binary PDF Ingestion • Zero Markdown Rewriting
To send a pre-existing PDF contract from Claude without converting it to Markdown, use one of Signbee's three binary ingestion pathways: (1) Local File Path via MCP: In Claude Desktop, invoke send_document_pdf from signbee-mcp with file_path (e.g., ~/Downloads/Asset-Management-Agreement.pdf) so the local MCP server encodes the binary outside the LLM context window; (2) Presigned Cloud URL: Pass pdf_url to POST https://signb.ee/api/v1/send; or (3) Direct Base64 Buffer: Pass pdf_base64 from a Python or TypeScript tool runner. Upload the PDF completely unsigned—Signbee automatically stamps Party A via your API key, emails Party B a mobile signing link, and appends a two-pass SHA-256 cryptographic certificate.
1. Why Pre-Existing PDFs Cannot Be Rewritten into Markdown
Signbee's CommonMark Markdown compiler (markdown parameter) is ideal when an AI agent drafts an NDA, consulting agreement, or statement of work from scratch. However, regulated industries—including private wealth management, commercial real estate, cross-border M&A, and enterprise procurement—frequently operate on strict, pre-engineered PDF documents.
Consider an institutional Asset Management Agreement or a statutory regulatory filing exported from Adobe InDesign or LaTeX. These documents contain vector company crests, complex multi-column fee schedules, watermarked backgrounds, exact pagination footers, and externally audited clause numbering. Asking an LLM like Claude 3.7 Sonnet or Claude 4 Opus to extract the text from that PDF and re-emit it as Markdown introduces three unacceptable risks:
- Visual & Brand Destruction: Re-rendering through Markdown strips custom corporate typography, dual-column layouts, embedded vector diagrams, and regulatory form boxes.
- Pagination & Cross-Reference Drift: Legal exhibits that reference “the fee table on Page 4, Section 3.2(b)” break if text reflow changes the page count.
- Token Exhaustion & Hallucination Risk: Re-emitting a 15-page legal PDF word-for-word consumes thousands of output tokens, adding 25–40 seconds of latency and risking subtle transcription omissions.
That is why Signbee ranks among the best e-signature APIs for developers in 2026: it treats binary PDF ingestion as a first-class citizen alongside Markdown compilation, without the complex envelope XML coordinates or high per-seat fees analyzed in our DocuSign API pricing guide.
2. The Golden Rule of Binary PDF Signing: Upload Unsigned Documents
When preparing pre-existing PDF agreements for dispatch through Claude and Signbee, one operational rule governs every workflow: the PDF file must be completely unsigned by both parties before sending. Do not paste a JPEG image of your signature into the PDF in Preview or Acrobat before calling Signbee, and do not pre-sign the PDF with a local X.509 certificate that locks the PDF object tree against page appends.
Party A (Sender / You)
When Claude calls Signbee with your secret key (Authorization: Bearer signbee_...), Signbee immediately records Party A as digitally authorized and executed—capturing your legal name, verified email, caller IP, and UTC timestamp.
Party B (Recipient / Client)
Signbee immediately emails the counterparty a secure, single-use signing URL (https://signb.ee/sign/[token]). The client reviews the exact original PDF in their browser and draws or types their signature.
Two-Party SHA-256 Certificate
Upon Party B's execution, Signbee appends an audit-grade A4 Signing Certificate page showing both Party A and Party B with timestamps, IPs, and SHA-256 verification links, and emails the final sealed PDF to both parties.
3. Comparing the 3 Direct PDF Ingestion Pathways in Claude
Why does Signbee offer three distinct ways to submit a binary PDF? Because an LLM agent cannot efficiently emit a 500KB Base64 string through its conversational token stream (a 500KB binary PDF expands to ~683,000 Base64 characters, which equates to roughly 175,000 LLM tokens—exceeding output token caps and costing dollars per call). Instead, you should always route the binary bytes around the LLM token generator using one of these three architectures:
| Ingestion Pathway | Method 1: send_document_pdf (MCP) | Method 2: pdf_url (Cloud Fetch) | Method 3: pdf_base64 (Code / API) |
|---|---|---|---|
| Best Host Environment | Claude Desktop, Cursor, Windsurf | Claude Web Projects, Cloud Agents, Zapier/n8n | Python / TypeScript Backends, Claude Code CLI |
| Parameter Passed by Claude | file_path: "/Users/.../doc.pdf" | pdf_url: "https://s3.../doc.pdf" | pdf_base64: "JVBERi0xLjQK..." |
| LLM Output Tokens Used | ~45 tokens (file path only) | ~55 tokens (URL string only) | 0 LLM tokens (encoded by script) |
| Where Binary Read Occurs | Local signbee-mcp child process | Signbee Edge Server (fetch(pdf_url)) | Your Python / Node.js runtime (fs.readFileSync) |
| End-to-End Dispatch Latency | 750ms – 950ms | 600ms – 880ms | 520ms – 790ms |
4. Method 1: Local File Path via send_document_pdf in Claude Desktop
If you use Claude Desktop on macOS or Windows, configuring the official signbee-mcp server gives Claude direct access to the send_document_pdf tool. Add the following configuration to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
// 1. ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"signbee": {
"command": "npx",
"args": ["-y", "signbee-mcp"],
"env": {
"SIGNBEE_API_KEY": "signbee_live_your_secret_key_here"
}
}
}
}
// 2. Tool Call Payload Generated by Claude Desktop when you prompt:
// "Send ~/Documents/Altezza-Asset-Management-Agreement.pdf to Jane Smith (jane.smith@example.com)"
{
"tool": "send_document_pdf",
"arguments": {
"file_path": "/Users/andrei/Documents/Altezza-Asset-Management-Agreement.pdf",
"title": "Asset Management Agreement — Altezza & Jane Smith",
"sender_name": "Andrei Ptitsyn",
"sender_email": "ap@altezza.org",
"recipient_name": "Jane Smith",
"recipient_email": "jane.smith@example.com",
"expires_in_days": 7
}
}Crucial UX Detail: Drag-and-Drop Attachments vs. Local File Paths
Many power users initially drag a PDF into the Claude Desktop chat box and say, “Send this attached PDF via Signbee.” When you attach a file to the chat window, Claude Desktop uploads the file into Anthropic's cloud vision/text buffer so Claude can read its contents, but it does not tell local MCP servers where that file lives on your hard drive.
To ensure Claude Desktop both reviews the clauses and sends the exact binary PDF via send_document_pdf, include the local path in your prompt (or right-click the file in Finder and press Option + Command + C to copy its POSIX path):
send_document_pdf to dispatch /Users/andrei/Desktop/Asset-Management-Agreement.pdf to Jane Smith at jane.smith@example.com with title 'Asset Management Agreement' and 7-day expiry.”5. Method 2 & Method 3: Cloud URLs (pdf_url) and Base64 (pdf_base64) in Python & TypeScript
When you add our claude-direct-pdf-signing-guide.md instructions to a Claude Project (under Project Knowledge or Custom Instructions) or run an agent inside Claude Code, Python, or a TypeScript backend, your code or agent calls POST https://signb.ee/api/v1/send directly.
Below are production-ready Python and TypeScript implementations covering both local Base64 encoding (pdf_base64) and presigned S3 / Cloudflare R2 URL ingestion (pdf_url), complete with strict %PDF magic-byte validation and plan size checks:
import base64
import os
from pathlib import Path
import requests
SIGNBEE_ENDPOINT = "https://signb.ee/api/v1/send"
def send_local_pdf_agreement(
pdf_file_path: str,
recipient_name: str,
recipient_email: str,
title: str = "Asset Management Agreement",
sender_name: str = "Andrei Ptitsyn",
sender_email: str = "ap@altezza.org",
expires_in_days: int = 7,
api_key: str | None = None,
) -> dict:
resolved_key = api_key or os.environ["SIGNBEE_API_KEY"]
raw_bytes = Path(pdf_file_path).expanduser().read_bytes()
# Verify PDF magic header (%PDF-) before network transmission
if not raw_bytes.startswith(b"%PDF"):
raise ValueError(f"File {pdf_file_path} is not a valid binary PDF document.")
payload = {
"title": title,
"pdf_base64": base64.b64encode(raw_bytes).decode("utf-8"),
"sender_name": sender_name,
"sender_email": sender_email,
"recipient_name": recipient_name,
"recipient_email": recipient_email,
"expires_in_days": expires_in_days,
}
response = requests.post(
SIGNBEE_ENDPOINT,
headers={
"Authorization": f"Bearer {resolved_key}",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
response.raise_for_status()
return response.json()
# Expected 200 OK JSON Response:
# {
# "document_id": "cmu6xyz123000...",
# "status": "pending_recipient",
# "sender": "Andrei Ptitsyn",
# "recipient": "Jane Smith",
# "expires_at": "2026-09-30T10:00:00.000Z"
# }And here is the corresponding Node.js / TypeScript implementation supporting both pdf_base64 and pdf_url, plus HMAC webhook registration for downstream CRM updates:
import fs from "node:fs";
export interface SendPdfOptions {
title: string;
filePath?: string;
pdfUrl?: string;
senderName?: string;
senderEmail?: string;
recipientName: string;
recipientEmail: string;
expiresInDays?: number;
webhookUrl?: string;
apiKey: string;
}
export async function sendExistingPdfViaSignbee(opts: SendPdfOptions) {
if (!opts.filePath && !opts.pdfUrl) {
throw new Error("Provide either filePath (for pdf_base64) or pdfUrl (for pdf_url)");
}
const bodyPayload: Record<string, unknown> = {
title: opts.title,
sender_name: opts.senderName ?? "Andrei Ptitsyn",
sender_email: opts.senderEmail ?? "ap@altezza.org",
recipient_name: opts.recipientName,
recipient_email: opts.recipientEmail,
expires_in_days: opts.expiresInDays ?? 7,
webhook_url: opts.webhookUrl,
};
if (opts.filePath) {
const pdfBuffer = fs.readFileSync(opts.filePath);
if (!pdfBuffer.subarray(0, 5).toString("ascii").startsWith("%PDF")) {
throw new Error("Invalid PDF binary: missing %PDF header");
}
bodyPayload.pdf_base64 = pdfBuffer.toString("base64");
} else {
bodyPayload.pdf_url = opts.pdfUrl;
}
const res = await fetch("https://signb.ee/api/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${opts.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(bodyPayload),
});
if (!res.ok) {
const errText = await res.text();
throw new Error(`Signbee send failed (${res.status}): ${errText}`);
}
return await res.json();
}6. Deep Dive: How Signbee Computes the Two-Pass SHA-256 Certificate on Binary PDFs
When you upload a pre-existing PDF via pdf_base64 or pdf_url, how does Signbee seal the document without corrupting internal PDF cross-reference tables (`xref`) or modifying your original pages?
Signbee's cryptographic engine uses pdf-lib to parse the Abstract Syntax Tree (AST) of your uploaded PDF buffer directly in memory:
- Header & Data-URI Sanitization: On
POST /api/v1/send, Signbee strips any optionaldata:application/pdf;base64,prefix, decodes the buffer into raw bytes, and verifiespdfBuffer.subarray(0, 5).toString().startsWith("%PDF"). - Immutable Source Persistence: The untouched binary PDF is uploaded to encrypted blob storage and linked to the document record alongside Party A's execution metadata (
senderSignedAt,senderIp, and verified account identity). - Two-Pass Certificate Sealing on Party B Completion: When Party B completes the signing ceremony at
https://signb.ee/sign/[token], Signbee loads the original PDF intoPDFDocument.load(originalBytes). In Pass 1, it constructs a dedicated A4 Certificate of Completion page containing Party A and Party B's names, verified emails, IP addresses, ISO-8601 UTC timestamps, Party B's drawn or typed signature graphic, and the public verification URL (https://signb.ee/verify/[id]). In Pass 2, it computes thecrypto.createHash("sha256")digest across the finalized PDF byte stream, stamps the digest onto the certificate, and stores the immutable hash in PostgreSQL for permanent public verification.
7. Plan Payload Limits, HTTP Error Handling & Pricing Tiers
Before deploying automated PDF pipelines into production, review Signbee's binary size limits and deterministic HTTP status codes. Unlike self-hosted stacks analyzed in our open-source e-signature API comparison—where large PDFs often crash Sidekiq workers or exceed SMTP attachment caps—Signbee validates payload sizes upfront before incrementing your monthly document counter. You can also explore our affordable e-signature API integration guide, 2026 e-signature API pricing comparison, white-label e-signature API documentation, and free e-signature API tier details.
| Signbee Plan Tier | Max Binary PDF Size | Included Docs / Pricing | HMAC Webhooks | Typical Contract Profile |
|---|---|---|---|---|
| Free Developer Tier | 250 KB | 5 docs/mo ($0.00) | Upgrade to Pro | 1–5 page text PDFs, NDAs, contractor agreements |
| Pay-As-You-Go / Pro | 500 KB | $0.50/doc or $19/mo (50 docs) | Included (SHA-256 HMAC) | 5–20 page MSAs, Asset Management Agreements, SOWs |
| Business Tier | 2,048 KB (2 MB) | $49/mo (250 docs) | Included + Custom Branding | 20–60 page enterprise agreements, graphic pitch decks, leases |
8. Frequently Asked Questions: Direct PDF Signing in Claude
Can Claude Desktop send an existing PDF file for signature without re-typing it into Markdown?
Yes. Using Signbee's send_document_pdf Model Context Protocol (MCP) tool or the pdf_base64 and pdf_url fields on POST https://signb.ee/api/v1/send, Claude dispatches your exact binary PDF file without converting or re-formatting its layout into Markdown. Every original vector graphic, corporate letterhead, multi-column financial schedule, embedded font, and page break remains 100% intact. Signbee simply validates the %PDF magic byte header, stores the immutable binary, and appends a cryptographic A4 Signing Certificate page upon completion.
Why doesn't Claude Desktop pass uploaded chat attachments directly to local MCP servers as file paths?
When you drag and drop a PDF into the Claude Desktop chat window, Anthropic reads that attachment into Claude's cloud context window rather than exposing a local filesystem path to stdio MCP servers. Furthermore, Base64-encoding a 400KB PDF inside an LLM's output token stream would consume over 140,000 tokens and hit output truncation limits. Instead, passing a local disk path (such as ~/Desktop/Asset-Management-Agreement.pdf) to Signbee's send_document_pdf MCP tool lets the local Node.js process read and Base64-encode the binary file directly on your machine with zero LLM token overhead.
Should the PDF document be pre-signed by Party A before sending it through Signbee?
No. Documents uploaded to Signbee via send_document_pdf, pdf_base64, or pdf_url should be completely unsigned by both parties prior to dispatch. When Claude calls the Signbee API authenticated with your Bearer API key (Authorization: Bearer signbee_...), Signbee automatically binds and certifies Party A (the sender) with your registered legal name, verified email, caller IP address, and UTC timestamp. Once Party B completes the interactive signing ceremony, Signbee's final SHA-256 certificate records both Party A and Party B on the appended certificate page.
What are the maximum PDF file size limits across Signbee plans?
Signbee enforces deterministic binary payload limits based on your account tier to guarantee sub-second ingestion and email delivery. The Free plan supports PDF documents up to 250KB, the Pro plan ($19/month) supports PDF documents up to 500KB, and the Business plan ($49/month) supports multi-page graphic PDFs up to 2MB (2,048KB). If a payload exceeds your plan limit, POST /api/v1/send returns an explicit HTTP 413 Payload Too Large response containing size_kb, limit_kb, and your current plan tier.
How does Signbee compute the two-pass SHA-256 cryptographic hash on an existing PDF?
When Party B signs an uploaded PDF, Signbee loads the original binary PDF buffer into pdf-lib without rasterizing or altering the original pages. In Pass 1, Signbee records the exact byte length and SHA-256 digest of the source document, along with Party A and Party B's execution metadata (timestamps, IP addresses, user agents, and drawn or typed signature artifacts). In Pass 2, Signbee appends the A4 Signing Certificate page to the PDF document tree, serializes the combined document bytes, and computes the final master SHA-256 hash stored at https://signb.ee/verify/[id].
When should I use pdf_url instead of pdf_base64 or send_document_pdf?
Use pdf_url when your PDF contract is already hosted in cloud object storage—such as an AWS S3 presigned URL, Cloudflare R2 bucket, Vercel Blob store, or Google Cloud Storage bucket—and your Claude agent is running inside a cloud workbench, Claude Project, or serverless webhook where local disk access is unavailable. Signbee's backend fetches the binary directly from pdf_url over TLS, validates the %PDF header and byte size limit, and initiates the signing ceremony without requiring your agent to buffer Base64 strings in memory.
Send Your First Existing PDF from Claude Today
Preserve 100% of your original PDF design and typography while automating two-party SHA-256 execution via MCP or REST API.