A contract on PitchStation lives at a single URL from first draft to executed PDF. The other side comments on it, you revise it, everyone signs it, and the link never changes — so there is one place to look and one audit trail to point at. This manual walks the whole life of a contract, from publishing it to filing the executed copy.
Five stages. Stages 2 and 3 repeat as many times as the negotiation needs.
Share the PDF the way you would share anything else. Turn on comments if you expect a negotiation — that is what turns a link into a negotiating table.
Open the Share composer, drop in the PDF, choose Anyone with the link, set an expiry, and tick “Let viewers comment”. Nothing else is required.
If you work in a terminal assistant — Claude Code, Codex, Kimi — connect PitchStation once (§05) and then simply say what you want. You are not typing a command; the assistant calls the tool:
“Publish msa-draft.pdf on PitchStation as a link anyone can open, let viewers comment, expire it in 30 days, and give me the URL.”
Browser assistants — ChatGPT, Claude, Gemini — are where most people draft the contract. They can publish it too if you have connected PitchStation as a connector; if not, draft there and publish in the app. Either way the reviewer’s side works identically.
Any client that can make an HTTP request, with a token from /tokens.html:
POST /api/share
{ "title": "Master Services Agreement", "pdfBase64": "…",
"access": "link", "comments": true, "expires_in": "30d" }
Send the resulting link to the other side. They can read it and — because comments are on — object to specific clauses and propose replacement wording, without an account and without installing anything. Full detail in the reviewer guide.
Their comments land in one feed. When you revise, replace the document rather than publishing a new link — the URL, the password, the analytics and the whole discussion carry forward. Publishing again instead splits the negotiation across two links and strands every comment on the old one.
Ask for it in the same plain language:
“Read the comments on that PitchStation link, then replace it with msa-round2.pdf and note: Round 2 — term shortened to 12 months, liability capped at fees paid.”
In the app, use Replace on the share’s analytics page and write the note in the box. Over the API it is POST /api/share/<slug>/replace with mode: "announce" and your note.
| After you revise… | Their comment… |
|---|---|
| you kept the text they quoted | stays anchored exactly where it was |
| you revised the wording they flagged | reads ✓ addressed — you acted on it |
| you deleted that text entirely | reads ⚠ orphaned, with their original quote preserved |
Returning reviewers see an “updated since you read it” banner with your note, and /s/<slug>/changes gives a redline of exactly what moved between rounds.
When the wording is agreed, create a signature request. A request is always born with a document, so it is made at the moment you put one there — at publish, or on the round that closes the negotiation. Both produce the same thing.
Put a signing block on the replace call that publishes the agreed wording. The request freezes the version that call creates, so the thing being signed is exactly the thing you just sent — there is no window in which an earlier draft could be bound by mistake.
Already at the final wording and nothing left to change? Replace the document with itself and attach the block; the round is a no-op and the request binds to it.
POST /api/share
{
"title": "Mutual NDA", "access": "link",
"pdfBase64": "…",
"signing": {
"signers": [
{ "name": "Dana Wu", "email": "dana@acme.com", "title": "General Counsel" },
{ "name": "Leo Lin", "email": "leo@verlin.com" }
],
"mode": "sequential",
"fields": "auto",
"send": true
}
}
Open the share’s analytics page. The Signatures panel lists every request on the document with its live state, and is where you act on it: send a draft once you have checked the signer list, remind whoever is holding it up, discard or cancel, download the signed PDF, and read the audit trail.
The panel manages requests; it does not create them — a request needs a document to freeze, which is why it is born with one.
send is false unless you say otherwise: a signature invitation cannot be un-sent, so publishing prepares a draft you review before it goes out. And fields: "auto" appends a standard signature block (signature, printed name, date, per signer) so a request can never go out with nothing to sign.Signers are always listed explicitly. Recipients are not signers — a share can carry a hundred readers, and turning a distribution list into a signature ceremony is not something that should ever happen by accident. Each signer needs a name (printed on the document) and an email; order controls sequence, and role: "copy_recipient" adds someone who receives the executed copy without signing. To countersign, add yourself as a signer.
Most contracts on PitchStation are put there by an assistant — Claude Code or another MCP-capable client, holding a personal access token, working from a folder on your machine. Everything in §02–§04 is reachable that way. One thing is not, deliberately.
An agent can carry a contract all the way up to the moment of signing, and no further. Preparing is clerical work; signing is an act of assent, and assent belongs to a person.
signers list for this reason. Ask the person, every time.Create a token at /tokens.html, then point your assistant at PitchStation’s MCP server. The token carries your full account authority, so treat it like a password — anything your assistant can do with it, anyone holding it can do.
Claude Code:
claude mcp add pitchstation -- node /path/to/generator/mcp/pitchstation-mcp-server.js # env: PITCHSTATION_URL=https://pitchstation.ai PITCHSTATION_TOKEN=pst_…
Codex, Kimi, or any other MCP client — the same server, declared in that client’s config file:
{ "mcpServers": {
"pitchstation": {
"command": "node",
"args": ["/path/to/generator/mcp/pitchstation-mcp-server.js"],
"env": { "PITCHSTATION_URL": "https://pitchstation.ai",
"PITCHSTATION_TOKEN": "pst_…" }
} } }
Browser assistants — ChatGPT, Claude, Gemini — reach it the same way if they support custom connectors; add the server there and the tools appear. Where they do not, use the app or the REST calls below. Nothing about the signer’s experience changes either way.
Pass a signing block to pitchstation_publish. It creates a draft — nothing is emailed:
pitchstation_publish
title: "Mutual NDA — Acme × Verlin"
pdfBase64: "…"
access: "link"
signing:
signers: [ { name: "Dana Wu", email: "dana@acme.com" },
{ name: "Leo Lin", email: "leo@verlin.com" } ]
fields: "auto" # standard signature block, per signer
mode: "sequential" # or "parallel" (default)
# send: omitted -> false. The draft waits for you.
→ Published as imOUqXsJ (link mode, pdf)
URL: https://pitchstation.ai/s/imOUqXsJ?k=…
Signing: request #48 — draft
Nothing has been emailed. Confirm the signer list with the owner,
then send it from the Signing panel.
Closing a negotiation round instead? Put the same block on pitchstation_replace. The request freezes the version that call creates, so there is no window in which the wrong draft could be bound.
pitchstation_signature_status is read-only — it reports, it cannot act:
pitchstation_signature_status requestId: 48 → Request #48 — partially_signed (1/2 signed) Document: Mutual NDA — Acme × Verlin (v3 of /s/imOUqXsJ) Deadline: 2026-08-21T00:00:00Z · Dana Wu <dana@acme.com> signer signed 2026-08-07T09:12:44Z · Leo Lin <leo@verlin.com> signer viewed 2026-08-07T09:40:02Z
Ask your assistant “has Acme signed the NDA yet?” and this is what it reads. It cannot nudge Leo, and it cannot fetch the executed PDF: the owner downloads it from the Signatures panel, and each signer receives it as an email attachment when the last party signs. There is no signer-facing download page.
| You ask your agent… | What happens |
|---|---|
| “Publish this NDA and set it up for Dana and me to sign” | Draft request created. Nothing sent. |
| “Send it” | You are confirming — the agent releases the invitations. |
| “Has anyone signed?” | Reads the status. No side effects. |
| “Just sign it for me, I approve” | Refused. There is no tool for it, and the signing link is not the agent’s to use. |
| “Send it to everyone on the share” | Refused. Readers are not signers — you must name them. |
Any client that can make an HTTP request can do the same, with the token as a bearer credential. This is the whole flow:
curl -X POST https://pitchstation.ai/api/share \
-H "Authorization: Bearer $PITCHSTATION_TOKEN" -H "Content-Type: application/json" \
-d '{ "title":"Mutual NDA", "access":"link", "pdfBase64":"…",
"signing": { "signers":[{"name":"Dana Wu","email":"dana@acme.com"}],
"fields":"auto" } }'
# -> { "signing": { "created": true, "requestId": 48, "status": "draft" } }
curl -X POST https://pitchstation.ai/api/signatures/48/send -H "Authorization: Bearer $TOK"
curl https://pitchstation.ai/api/signatures/48 -H "Authorization: Bearer $TOK"
curl https://pitchstation.ai/api/signatures/48/audit/verify -H "Authorization: Bearer $TOK"
Works on a phone. They can read the entire document before anything else happens.
Unchecked by default, shown in their language, and recorded with the exact wording they agreed to.
Typed signatures use a signature face; drawn ones capture the stroke. Either way it renders correctly in any script — 張偉, Владимир and محمد all appear exactly as entered.
Declining stops the whole request, notifies you, and preserves everything recorded so far.
The moment you create a signature request, PitchStation takes a private copy of that exact version and fingerprints it. That copy is what everyone signs.
Practically: if the contract text needs to change after you have sent it, cancel the request and create a new one. That is deliberate. A signature belongs to a specific set of words.
| Status | What it means |
|---|---|
| Draft | Prepared but nobody has been emailed. Signers and fields can still be changed. |
| Awaiting signatures | Sent. In sequential mode, only the first signer has been emailed. |
| Partially signed | At least one party has signed; the next has been notified. |
| Signed | Everyone has signed. The executed PDF and certificate exist. |
| Declined | A signer refused. Routing stopped; every outstanding link is dead. |
| Cancelled | You stopped it. Links are dead; the record is kept. |
From the Signatures panel you can remind whoever is holding things up (only the people whose turn it actually is), cancel, or open the audit trail.
When the last party signs, PitchStation builds the executed PDF: every signature flattened into place, followed by a completion certificate recording the document title, the version, the fingerprint before and after, and — for each party — their name, masked email, authentication method, the consent text they accepted and in which language, and their timestamps. Behind it sits the event log, hash-chained so that altering any entry breaks the chain.
The executed PDF is emailed to every signer and copy recipient, and stays downloadable from the Signatures panel. The original unsigned document is never overwritten — both remain, each with its own fingerprint.
An MSA between Acme and Verlin, start to finish, as it actually happens: you talking to a terminal assistant with PitchStation connected. Nothing here is a command you have to memorise.
You: Publish msa-v1.pdf on PitchStation. Link anyone can open,
let them comment, expire in 45 days. Title it "MSA — Acme × Verlin".
AI: Published as imOUqXsJ (link mode, pdf)
URL: https://pitchstation.ai/s/imOUqXsJ?k=…
Comments: on — viewers can comment, suggest edits, and annotate
Send that URL to Acme. They need no account and install nothing.
You: What did Acme say on that link?
AI: 6 open comments. The substantive ones:
· §4.2 Term — "3 years is too long, we need 12 months"
· §9 Liability — "uncapped indemnity is a blocker"
· §11 — suggested edit replacing "sole discretion" with "reasonable discretion"
…
You: Draft v2: term to 12 months, cap liability at fees paid,
accept the §11 wording. Show me the diff before anything ships.
AI: [shows the redline]
You: Good. Replace the share with it, note "Round 2 — term 12 months,
liability capped at fees paid".
AI: Replaced imOUqXsJ (v2, announce). 4 comments re-anchored,
2 marked addressed. Returning viewers see your note.
Same link. Same discussion. Acme opens the URL they already have.
You: Acme is happy. Publish msa-final.pdf as the execution copy and
set it up for signature — Dana Wu at dana@acme.com signs first,
then me, leo@verlin.com. Don't send it yet.
AI: Replaced imOUqXsJ (v3, announce — "Execution copy")
Signing: request #48 — draft
Nothing has been emailed. Confirm the signer list,
then send it from the Signing panel.
Open the Signatures panel on the analytics page, check the two names, and press Send for signature. From here nobody needs you:
Ask “has Acme signed the MSA yet?” at any point and you get the live state — signed, viewed, or still untouched.
The link still works, and still tells the whole story: the first draft, every comment, every round, who signed and when, and the executed document at the end of it. That is the point of keeping one URL from beginning to end.