Every signing workflow starts the same way: someone opens a PDF editor, drags and drops signature fields onto the right lines, exports, uploads to a signing service, adds signer emails, and hits send. When you're doing this once a month for an NDA it's fine. When you're generating hundreds of contracts per day from templates, it's a bottleneck.

QuantoSign's Markdown Automation API solves this. Write your document in plain Markdown. Drop {{RTAI:Signer1:Signature}} placeholders wherever you want signature fields. One API call converts it to a PDF, extracts the exact coordinates of each placeholder, places interactive signing fields there, and sends signing links to every signer.

The Flow

Markdown POST /from-markdown LibreOffice PDF Field Placement Signing Links Signed PDF

The API ingests Markdown, converts it to PDF via LibreOffice, scans the PDF content stream for invisible marker text to find each placeholder's exact page coordinates, then creates interactive signing fields at those locations. The signed PDF includes inline stamps — the signature image and date appear exactly where the placeholders were in your Markdown.

Step 1 — Write the NDA in Markdown

Here's a two-party NDA written entirely in Markdown. The {{RTAI:SignerN:FieldType}} placeholders render as invisible markers in the PDF, replaced by interactive signing fields:

# Mutual Non-Disclosure Agreement **Effective Date:** April 20, 2026 This Mutual Non-Disclosure Agreement ("Agreement") is entered into as of the Effective Date by and between the parties identified below. --- ## Parties **Party A:** Acme Technologies Inc., a Delaware corporation 1 Platform Way, Suite 200, San Francisco, CA 94105 **Party B:** Buildco Corp Inc. — New York, NY --- ## 1. Purpose The Parties wish to explore a potential business relationship and may disclose certain confidential and proprietary information... [... full agreement terms ...] --- ## Signatures **Party A — Acme Technologies Inc.** Signature: {{RTAI:Signer1:Signature}} Name: {{RTAI:Signer1:Text}} Date: {{RTAI:Signer1:Date}} --- **Party B — Buildco Corp Inc.** Signature: {{RTAI:Signer2:Signature}} Name: {{RTAI:Signer2:Text}} Date: {{RTAI:Signer2:Date}}

Placeholders follow the format {{RTAI:SignerN:FieldType}}. Signer number matches the signing order — Signer1 signs first, Signer2 receives their link after Signer1 completes. Supported field types:

Placeholder Field Type Description
{{RTAI:Signer1:Signature}} signature Drawn or typed signature
{{RTAI:Signer1:Date}} date Auto-filled signing date
{{RTAI:Signer1:Text}} text Free-text (name, title, etc.)
{{RTAI:Signer1:Initials}} initials Initials field
{{RTAI:Signer1:Checkbox}} checkbox Checkbox agreement

Step 2 — One API Call

Point the API at your Markdown string and declare your signers. The API handles everything else.

bash
curl -X POST https://esign.rt19.runtimeai.io/api/v1/sign/documents/from-markdown \
  -H "Authorization: Bearer $ESIGN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Mutual NDA — April 2026",
    "markdown_content": "# NDA\n\nSee nda.md for full content",
    "signers": {
      "Signer1": {"name":"Alice Smith","email":"alice@acme.com","order":1},
      "Signer2": {"name":"Bob Jones",  "email":"bob@buildco.com","order":2}
    },
    "send_immediately": true
  }'
import requests

response = requests.post(
    "https://esign.rt19.runtimeai.io/api/v1/sign/documents/from-markdown",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "title": "Mutual NDA — April 2026",
        "markdown_content": open("nda.md").read(),
        "signers": {
            "Signer1": {"name": "Alice Smith", "email": "alice@acme.com",    "order": 1},
            "Signer2": {"name": "Bob Jones",   "email": "bob@buildco.com",   "order": 2},
        },
        "send_immediately": True,
    }
)
doc = response.json()
print(f"Document {doc['document_id']} sent to {len(doc['signers'])} signers")
const response = await fetch(
  'https://esign.rt19.runtimeai.io/api/v1/sign/documents/from-markdown',
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      title: 'Mutual NDA — April 2026',
      markdown_content: fs.readFileSync('nda.md', 'utf8'),
      signers: {
        Signer1: { name: 'Alice Smith', email: 'alice@acme.com',   order: 1 },
        Signer2: { name: 'Bob Jones',   email: 'bob@buildco.com',  order: 2 },
      },
      send_immediately: true,
    }),
  }
);
const { document_id, signers } = await response.json();

Step 3 — The Response

The API returns the document ID and a signing link for each signer. Signer2's link is inactive until Signer1 completes — sequential order is enforced automatically.

{ "document_id": "c6ab47d1-f4b1-4438-b128-c64624af53b0", "status": "sent", "signers": [ { "signer_id": "a1b2c3d4-...", "email": "alice@acme.com", "signing_link": "https://esign.rt19.runtimeai.io/sign/<token1>", "order": 1 }, { "signer_id": "e5f6a7b8-...", "email": "bob@buildco.com", "signing_link": "https://esign.rt19.runtimeai.io/sign/<token2>", "order": 2 } ] }

Step 4 — Signing Experience

Each signer opens their link in any browser. They see the full NDA rendered as a PDF with interactive fields at every placeholder location. The signature field renders a drawing pad; date fields auto-fill to today. After signing, the document moves to the next signer in the sequence.

Field positioning is exact. The API extracts the y-coordinate of each placeholder from the LibreOffice-generated PDF content stream and places the signing field at that precise location — not at a fixed offset or page bottom.

Step 5 — The Signed PDF

Once all signers complete, the executed PDF is available for download. Signatures and dates appear inline with their original placeholder labels — exactly where you placed them in the Markdown source.

Demo B: Claude Code via MCP

If you use Claude Code (Anthropic's CLI), the QuantoSign MCP server lets you orchestrate the entire signing workflow as a conversation — no scripts, no curl commands. This demo uses two separate Claude Code sessions: one for Alice (the sender, Acme Technologies) and one for Bob (the counterparty, Buildco Corp — a different company).

1. Add QuantoSign to Claude Code

Both Alice and Bob add this to their Claude Code MCP config at ~/.claude/settings.json. Each uses their own API key:

~/.claude/settings.json
{
  "mcpServers": {
    "quantosign": {
      "command": "npx",
      "args": ["@runtimeai/mcp-server-quantosign"],
      "env": {
        "QUANTOSIGN_API_KEY": "your-api-key-here",
        "QUANTOSIGN_BASE_URL": "https://esign.rt19.runtimeai.io/api/v1/sign"
      }
    }
  }
}

Get your API key from the API Keys dashboard. Restart Claude Code — the QuantoSign tools load automatically and are listed via /mcp.

2. Alice's Session — Create & Send

Alice opens a Claude Code terminal and runs these prompts:

Alice I need to send a Mutual NDA to Buildco Corp for signing. Create it from the contents of nda.md, with me (Alice Smith, alice@acme.com) as Signer1 and Bob Jones (bob@buildco.com) as Signer2. Don't send yet — I want to review first.
Tool
create_and_send_markdown_document title: "Mutual NDA — Acme / Buildco", send_immediately: false Signer1: alice@acme.com (order 1) · Signer2: bob@buildco.com (order 2)
Out
document_id: 5ee0304c-9fd3-4b04-ad14-4413fac64032 status: draft · signers: 2 · signing fields placed: 6

Alice Looks good. Send it for signing with the message: "Please review and sign this Mutual NDA at your earliest convenience."
Tool
send_for_signing — document_id: 5ee0304c-...
Out
status: sent · 2 emails dispatched → alice@acme.com: "You have a document to sign — [Sign Now]" → bob@buildco.com: "You've been invited to sign — awaiting prior signer"

Alice I just got the signing email. My link is https://esign.rt19.runtimeai.io/sign/<alice_token> — please sign it with a typed signature.
Tool
complete_guest_signing token: <alice_token>, signature_method: type ↳ auto-fetches fields (get_guest_signing), fills field_values (date → today)
Out
Alice Smith ✓ signed Document: partially signed (1/2) → bob@buildco.com receives: "It's now your turn to sign — [Sign Now]" (link is now active)

3. Bob's Session — Review & Sign

Bob is at a different company. He opens his own Claude Code session after receiving the "your turn" email, and pastes his signing link:

Bob I got a signing request from Acme Technologies. My link is https://esign.rt19.runtimeai.io/sign/<bob_token> — what exactly am I signing?
Tool
get_guest_signing — token: <bob_token>
Out
Document: "Mutual NDA — Acme / Buildco" Sender: alice@acme.com Your fields: signature, name (text), date — all on page 1 Signer1 (Alice Smith, alice@acme.com) has already signed.

Bob Looks fine. Sign it for me with a typed signature.
Tool
complete_guest_signing token: <bob_token>, signature_method: type ↳ auto-fetches fields, fills field_values (date → today)
Out
Bob Jones ✓ signed Document: completed (2/2 — fully executed) → Both parties receive: "Your document has been fully executed — [Download]"

Bob Download the signed NDA.
Tool
download_guest_document — token: <bob_token>
Out
Saved: mutual_nda_executed.pdf — 53 KB Signatures stamped inline at placeholder positions in the PDF

Two parties, different companies, different Claude Code sessions. From Markdown source to fully executed PDF — six conversational turns, zero code.

When to Use This