pitch2pdf CLI

Convert presentations to PDF from your terminal. Scriptable, pipeable, and designed for AI agents.

Install

npx pitch2pdf-cli https://pitch.com/v/your-deck

Or install globally:

npm install -g pitch2pdf-cli

Usage

pitch2pdf <url> [options]

Options:
  --email <email>        Email for protected presentations
  --password <password>  Password for protected presentations
  -o, --output <path>    Output file path (use - for stdout)
  --json                 Output NDJSON events to stdout
  --no-progress          Suppress progress output
  --api-url <url>        Custom API URL
  -V, --version          Show version
  -h, --help             Show help

Examples

Convert a Pitch presentation:

pitch2pdf https://pitch.com/v/my-deck

DocSend with email authentication:

pitch2pdf https://docsend.com/view/abc --email you@company.com

Save to a specific file:

pitch2pdf https://docs.google.com/presentation/d/1abc/pub -o slides.pdf

Pipe to another command:

pitch2pdf https://canva.com/design/abc/token/view -o - | wc -c

JSON output for scripting:

pitch2pdf https://pitch.com/v/deck --json
# Each line is a JSON object:
# {"status":"processing","stage":"loading","jobId":"abc123"}
# {"status":"processing","stage":"capturing","currentSlide":1,"totalSlides":10}
# {"status":"completed","jobId":"abc123","numSlides":10,...}
# {"event":"saved","path":"deck.pdf","size":2451623}

Exit Codes

CodeMeaning
0Success
1General error (invalid URL, server error)
2Network error
3Authentication required or failed
4Bot detection blocked the request
5Timeout
6Connection dropped during conversion
7PDF download failed
130Interrupted (Ctrl+C)

Error Code Reference

Every failed conversion carries a code field — in --json output it's {"status":"failed","code":"...","message":"..."}, and it also determines the exit code above. This table covers what each one means, which services most commonly trigger it, and what to do about it.

CodeExitMeaningCommon onWhat to do
UNSUPPORTED_SERVICE1The URL points to something pitch2pdf doesn't convert.Prezi Video/Design links, Pitch Data Rooms, Canva templates, DocSend links that forward off-siteUse a supported URL format for that service, or find the actual presentation/document link.
AUTH_REQUIRED3The presentation or document needs credentials pitch2pdf doesn't have.Google Slides/Docs/Sheets/Drive not shared as "Anyone with the link", private Canva designs, gated DocSend/Pitch/Presentations.AI links, private or password-protected Figma Slides decksPass --email/--password if the deck supports gated access, or ask the owner to share it publicly.
AUTH_FAILED3Credentials were supplied but rejected.DocSend, PitchDouble-check the email/password, and confirm you're using the address the owner actually granted access to.
NAVIGATION_FAILED1The presentation viewer didn't load as expected.Any service, occasionally — usually a transient viewer hiccupRetry. If it persists on the same link, report it.
DECK_NOT_FOUND1The link points to a presentation that was deleted, expired, or mistyped.Pitch, DocSendConfirm the link opens in a regular browser and ask the sender for a fresh one.
BOT_BLOCKED4The service temporarily blocked automated access to this link.DocSend, Canva, Prezipitch2pdf retries once automatically. If it keeps happening, wait a while and try again.
BLANK_SLIDES1Every captured page came back blank.Google Docs/Drive right after a sharing-settings change, occasional DocSend rendering hiccupsRetry — most are transient rendering issues on the source service.
CAPTURE_FAILED1Too many pages in a row failed to render within the time available.Very large decks, especially CanvaRetry. Extremely large presentations may need to be split into smaller ones.
TIMEOUT5The conversion exceeded the maximum time limit (15 minutes).Very large presentations (100+ slides), long Prezi decksRetry, or split an unusually large deck into smaller ones.
BROWSER_CRASHED1Rendering crashed unexpectedly mid-conversion.Any service, rarelyRetry — this is almost always transient.
DOWNLOAD_FAILED7The underlying file couldn't be downloaded.Direct PDF links, Google Drive/Sheets exportsConfirm the link serves the file directly (not a landing page) and is under the size/page limits.
DOWNLOAD_DISABLED1The file owner disabled downloads and the file couldn't be captured another way either.Google DriveAsk the owner to enable "Viewers can download", or share it as a Slides/Docs link.
FILE_NOT_FOUND1The linked file or document doesn't exist.Google Drive/Sheets, direct PDF linksConfirm the file still exists and the link is correct and complete.
NETWORK_ERROR2The CLI couldn't reach the API at all.—Check your internet connection and --api-url (or PITCH2PDF_API_URL).
HTTP_ERROR1The server returned an error not covered by a more specific code above.—Check the message field for details; retry if it looks transient.
INVALID_RESPONSE1The server responded, but not in the expected streaming format.—Usually transient — retry.
NO_BODY1The server accepted the request but returned no data.—Usually transient — retry.
STREAM_DROPPED6The connection to the server was lost before a job could be identified.—Retry the conversion.
STREAM_RECOVERY_TIMEOUT6The connection dropped mid-conversion and automatic recovery timed out.—The conversion may still finish server-side for very large decks; retry after a few minutes.

Environment Variables

VariableDescription
PITCH2PDF_API_URLOverride the default API URL
PITCH2PDF_EMAILEmail for protected presentations (avoids passing via CLI arg)
PITCH2PDF_PASSWORDPassword for protected presentations (avoids exposure in process list)

Free Tier

The CLI uses the free tier: first 10 slides at full resolution, remaining slides as preview thumbnails. For full deck with OCR-powered searchable text, upgrade at pitch2pdf.com.

Pay from an agent

An AI agent can buy the full deck without a person or a checkout page. Take the jobId from the --json output and call POST https://api.pitch2pdf.com/api/jobs/<jobId>/generate-paid; unpaid, the API answers 402 Payment Required with a payment challenge in the headers (x402 for USDC on Base, or Stripe's Machine Payments Protocol for a card via a Link agent wallet or USDC on Tempo). The agent pays the challenge — $3 per deck, the same as the one-time unlock — and retries the same request with the credential to receive the searchable PDF.

curl -N -X POST https://api.pitch2pdf.com/api/jobs/<jobId>/generate-paid \
  -H 'Content-Type: application/json' -d '{"size":"medium"}' \
  -H 'Authorization: Payment <credential>'     # or PAYMENT-SIGNATURE: … for x402

--pay is coming to the CLI; until then use the HTTP flow. The full contract, both rails, error codes and refunds are on the agents page.