Agent generates
The model emits semantic PTDF blocks: headings, paragraphs, lists, tables and more.
schemaVersion: ptp.document/1
Your agent creates the content. PasteToPrint turns it into a structured, human-reviewable document — ready to edit, draw on, print or export.
/.well-known/ai.json
POST /api/v2/documents
2{
3 "schemaVersion": "ptp.document/1"
,
4 "title": "Service report"
,
5 "template": "work_report"
,
6 "blocks": [ /* semantic content */ ]
7}
{
"success": true,
"editorUrl": "https://www.pastetoprint.com/open/…"
,
"requiresUserConfirmation": true
}
A standard destination for generated documents
Instead of returning a wall of text, give the user a real document they can inspect and finish in a browser.
The model emits semantic PTDF blocks: headings, paragraphs, lists, tables and more.
schemaVersion: ptp.document/1
The API validates the payload, selects a safe template and creates a temporary session.
POST /api/v2/documents
The user reviews the result, confirms the import, then edits text, draws directly on the page, adds shapes or image layers, prints or exports it.
editorUrl → review
No API required
A chatbot that can only return text and links can place a short plain-text document in the URL fragment. The document content is decoded locally and is not sent in an HTTP request.
Fetch-independent PTDF
Copy this self-contained instruction into an ordinary AI chat. It tells the model to collect the missing facts, stay with PTDF, and return JSON that can be checked in the PasteToPrint import dialog.
Create a PasteToPrint PTDF 1.0 document without browsing or fetching a schema.
Do not switch to HTML when a URL, web fetch, plugin, or external tool is unavailable.
First ask for every missing fact in the user's language. Never invent identity, price, date, legal, or property details.
Then return UTF-8 JSON with exactly "schemaVersion":"ptp.document/1" and a non-empty "blocks" array.
Optional root fields are title, locale, paper, and template. Use template "contract" for a contract.
Use only heading, paragraph, quote, list, table, key_value, party, address, date, money, notice, checkbox, signature, spacer, divider, and page_break blocks.
Unknown fields, HTML, CSS, scripts, comments, remote images, empty text, and empty arrays are forbidden.
For heading, paragraph, quote, and notice use exactly one of text or non-empty runs, never both.
Before returning, verify that JSON.parse succeeds, dates are real YYYY-MM-DD values, and every object contains only allowed members.
If files are supported, return document.ptdf.json with media type application/vnd.pastetoprint.ptdf+json; otherwise return exactly one JSON code block.
Tell the user to import or paste it into PasteToPrint, validate it, review the preview, and explicitly append, replace, or cancel.
If PasteToPrint reports validation errors, correct and return the complete JSON again.
The complete prompt includes the exact portable contract block shapes and requires no schema download. See the plain-language user guide → Open the complete plain-text prompt →
When the user asks to open short plain-text output in pasteToPrint:
1. Finish the complete document before creating the link.
2. Normalize line endings to LF.
3. Encode the text exactly once using JavaScript encodeURIComponent semantics.
4. Append it to:
https://www.pastetoprint.com/#text=ENCODED_TEXT
5. Verify that decoding once reproduces the complete source text.
6. Return exactly one clickable Markdown handoff:
[Open in pasteToPrint](https://www.pastetoprint.com/#text=ENCODED_TEXT)
7. Tell the user to click, review, and explicitly append, replace, or cancel.
Keep the complete URL at or below 8,000 characters.
Never truncate content to make it fit.
For longer or structured documents, use PTDF, MCP, or an API session.
Never place passwords, tokens, private keys, card data, or other secrets in the link.
Example:
[Open in pasteToPrint](https://www.pastetoprint.com/#text=Service%20report%0AInspection%20complete.)
Opening the link still downloads the PasteToPrint application over HTTPS. Only the document fragment stays local. The editor always shows a preview and requires a human decision. Read the normative link contract → Run the chatbot QA matrix →
Structured no-POST handoff
A code-capable AI client can serialize a compact PTDF 1.0 document deterministically and place its exact UTF-8 bytes in a Base64URL fragment.
const ptdfDocument = {
schemaVersion: "ptp.document/1",
blocks: [
{ type: "heading", level: 1, text: "Service report" },
{ type: "paragraph", text: "Inspection complete." }
]
};
// Validate ptdfDocument against PTDF 1.0 before encoding.
const json = JSON.stringify(ptdfDocument);
const bytes = new TextEncoder().encode(json);
let binary = "";
for (let offset = 0; offset < bytes.length; offset += 0x8000) {
binary += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));
}
const payload = btoa(binary)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/g, "");
const url = "https://www.pastetoprint.com/#ptdf=" + payload;
// Decode, byte-compare and validate again before returning the link.
// Keep the complete URL at or below 8,000 characters. Never truncate.
// Without deterministic byte encoding, use #text or a PTDF file instead.
Inline PTDF uses RFC 4648 Base64URL without padding or compression. It requires deterministic encoding and round-trip verification; a chatbot must never guess the payload. Read the structured-link contract → Run the structured-link QA matrix →
Long documents · no POST
When a document is too large for a portable URL, use a local PTDF file or the optional AI-chat radar. Both routes keep the validation preview and human confirmation boundary.
Ask a file-capable AI client for validated UTF-8 PTDF 1.0. Open the artifact with an installed PasteToPrint PWA, choose Import PTDF, or drag it anywhere over the editor.
The optional Manifest V3 extension detects assistant responses on ChatGPT, Gemini, Claude and Copilot. A user click transfers one response through the nonce-bound postMessage protocol.
The extension has no background worker, cookie access or clipboard permission. It reads the selected response only after its button is clicked. Neither route can confirm an import, print or export for the user. See the security boundary and release gate.
Quick start
No account is required for a short-lived anonymous session.
Keep the returned editorUrl private and give it to the user.
const documentData = {
schemaVersion: "ptp.document/1",
title: "AI-generated service report",
locale: "en-US",
paper: { size: "A4", orientation: "portrait" },
template: "work_report",
blocks: [
{ type: "heading", level: 1, text: "Service report" },
{ type: "paragraph", text: "Prepared by an AI assistant." },
{ type: "list", style: "bullet", items: ["Inspection complete", "No defects found"] }
]
};
const response = await fetch("https://www.pastetoprint.com/api/v2/documents", {
method: "POST",
headers: {
"Content-Type": "application/vnd.pastetoprint.ptdf+json",
"Idempotency-Key": `ai-${crypto.randomUUID()}`
},
body: JSON.stringify(documentData)
});
if (!response.ok) throw new Error(`PasteToPrint API: ${response.status}`);
const result = await response.json();
console.log(result.editorUrl); // Give this temporary URL to the user.
<?php
$document = [
'schemaVersion' => 'ptp.document/1',
'title' => 'AI-generated service report',
'locale' => 'en-US',
'paper' => ['size' => 'A4', 'orientation' => 'portrait'],
'template' => 'work_report',
'blocks' => [
['type' => 'heading', 'level' => 1, 'text' => 'Service report'],
['type' => 'paragraph', 'text' => 'Prepared by an AI assistant.'],
['type' => 'list', 'style' => 'bullet', 'items' => ['Inspection complete', 'No defects found']],
],
];
$curl = curl_init('https://www.pastetoprint.com/api/v2/documents');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/vnd.pastetoprint.ptdf+json',
'Idempotency-Key: ai-' . bin2hex(random_bytes(12)),
],
CURLOPT_POSTFIELDS => json_encode($document, JSON_THROW_ON_ERROR),
]);
$response = curl_exec($curl);
if ($response === false) throw new RuntimeException(curl_error($curl));
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
echo $result['editorUrl']; // Give this temporary URL to the user.
import json
import uuid
from urllib.request import Request, urlopen
document = {
"schemaVersion": "ptp.document/1",
"title": "AI-generated service report",
"locale": "en-US",
"paper": {"size": "A4", "orientation": "portrait"},
"template": "work_report",
"blocks": [
{"type": "heading", "level": 1, "text": "Service report"},
{"type": "paragraph", "text": "Prepared by an AI assistant."},
{"type": "list", "style": "bullet", "items": ["Inspection complete", "No defects found"]},
],
}
request = Request(
"https://www.pastetoprint.com/api/v2/documents",
data=json.dumps(document).encode("utf-8"),
method="POST",
headers={
"Content-Type": "application/vnd.pastetoprint.ptdf+json",
"Idempotency-Key": f"ai-{uuid.uuid4()}",
},
)
with urlopen(request, timeout=15) as response:
result = json.load(response)
print(result["editorUrl"]) # Give this temporary URL to the user.
curl --request POST "https://www.pastetoprint.com/api/v2/documents" \
--header "Content-Type: application/vnd.pastetoprint.ptdf+json" \
--header "Idempotency-Key: ai-demo-$(date +%s)-$RANDOM" \
--data '{
"schemaVersion": "ptp.document/1",
"title": "AI-generated service report",
"locale": "en-US",
"paper": { "size": "A4", "orientation": "portrait" },
"template": "work_report",
"blocks": [
{ "type": "heading", "level": 1, "text": "Service report" },
{ "type": "paragraph", "text": "Prepared by an AI assistant." },
{ "type": "list", "style": "bullet", "items": ["Inspection complete", "No defects found"] }
]
}'
Add Authorization: Bearer ptp_ai_… for provisioned clients
and longer TTL tiers. Never put tokens in a URL or document content.
Authentication guide →
Integration surface
Every path converges on the same validated PTDF document and the same human-controlled editor handoff.
Import the complete machine-readable contract into an agent builder, code generator or API client.
Validate PTDF, inspect its schema, create or update sessions, and retrieve separate editor and read-only links.
Add a secure “Open in PasteToPrint” handoff to a website without rebuilding the document editor.
Validate model output before sending it. The schema defines supported blocks, marks, paper settings and limits.
The specification is CC BY 4.0; its JSON Schema and reference validator/renderer are MIT licensed.
Return an inline text or PTDF link, a temporary HTTPS capability, an installed PWA route, or a native protocol link.
Model Context Protocol
The local MCP bridge keeps API credentials in the process environment. The model receives focused tools, never the bearer token.
{
"mcpServers": {
"pastetoprint": {
"command": "node",
"args": [
"/path/to/pastetoprint/integrations/mcp/src/server.js"
],
"env": {
"PASTETOPRINT_API_BASE_URL":
"https://www.pastetoprint.com",
"PASTETOPRINT_API_TOKEN":
"ptp_ai_..."
}
}
}
}
Automatic discovery
The discovery manifest points machines to the canonical OpenAPI contract, documentation, MCP guide, JSON Schema, PTDF specification and the no-POST inline links, PTDF files and the optional local AI-chat extension.
{
"name": "PasteToPrint"
,
"openapi":
"https://www.pastetoprint.com/api/v2/openapi.yaml"
,
"documentation":
"https://www.pastetoprint.com/ai-agents.html"
,
"mcp":
"https://www.pastetoprint.com/MCP-SERVER.md"
,
"inline_text_deep_link": {
"version": "1"
,
"http_post_required": false
},
"inline_ptdf_deep_link": {
"schema_version": "ptp.document/1"
,
"http_post_required": false
},
"long_document_handoff": {
"http_post_required": false,
"requires_user_confirmation": true
},
"document_format":
"https://www.pastetoprint.com/PTDF-1.0.md"
}
Deep links
Use a local fragment for short text or compact PTDF. Use capability or protocol links for API-created sessions.
Can’t inspect the user’s open tab? URL import does not require active-tab, DOM or MCP access. Read the canonical URL import guide →
https://www.pastetoprint.com/#text={encodedText}
A normal chatbot has short plain text and no API tool
https://www.pastetoprint.com/#ptdf={encodedPtdf}
A code-capable AI client has a compact structured document
https://www.pastetoprint.com/open/{editorToken}
Always safe as the default handoff
web+pastetoprint://open/{editorToken}
The installed PWA handler is known
pastetoprint://open/{editorToken}
A native handler is confirmed