How to self-host SimplePDF Copilot

SimplePDF Copilot is a MIT-licensed reference implementation for adding an AI chat sidebar to the SimplePDF editor. You can fork the Copilot app, deploy it on your own infrastructure, plug in your own AI provider, and route completed documents to your own storage.
The SimplePDF editor itself remains a hosted iframe. Self-hosting Copilot means you own the chat app, AI routing, prompts, tools, and storage flow around the editor.
This guide covers the path from localhost to production.
If you are using Claude Code, Codex, or another agentic coding tool, point it at the fork-and-go skill. The skill walks the agent through the fork, configuration, and deployment flow one question at a time.
What you self-host
- Copilot chat app. Runs on your infrastructure. You control it.
- System prompt and tool registry. Live in your Copilot deployment. You control them.
- AI routing. Server-side, browser BYOK, or local endpoint. You control it.
- Completed document storage. SimplePDF storage by default, or your storage with BYOS. You control it when BYOS is enabled.
- SimplePDF editor iframe. Stays hosted by SimplePDF.
Prerequisites
- A SimplePDF Pro plan or higher. Running Copilot on your own domain requires white-labeling, programmatic editor control, and an allowed origin in your SimplePDF dashboard. Without those capabilities, the editor only loads on the hosted demo origin or
http://localhost:3001. - An AI provider key, a BYOK flow, or a local OpenAI-compatible endpoint. Anthropic, OpenAI, DeepSeek, Google Gemini, and Mistral are wired in out of the box.
- A Node 24 runtime. The current Copilot deployment template uses Node 24 and the app runs unmodified on DigitalOcean App Platform, Cloudflare Containers, Vercel, Render, fly.io, Railway, or self-hosted Docker.
Step 1: Run the demo locally
Clone the repository and run the demo against the shared SimplePDF demo workspace. No SimplePDF account is required for this step.
git clone https://github.com/SimplePDF/simplepdf-embed.git
cd simplepdf-embed/copilot
npm install
cp .env.example .env
printf "\nVITE_SIMPLEPDF_COMPANY_IDENTIFIER=spdf-copilot\n" >> .env
npm run dev
The dev server runs on http://localhost:3001. Open the chat sidebar, paste a provider key, or point at a local OpenAI-compatible endpoint such as Ollama or LM Studio.
The demo workspace whitelists exactly one local origin: http://localhost:3001. Any other port or host will be refused by the iframe. To run on your own domain, continue to Step 2.
Step 2: Set up your SimplePDF account
Subscribe to Pro or higher. From the SimplePDF dashboard:
- Copy your
companyIdentifier. This is the value you will put inVITE_SIMPLEPDF_COMPANY_IDENTIFIER. - Whitelist your serving origin, for example
https://app.example.com. The iframe refuses to load on origins that are not whitelisted. - Optionally customize your branding to remove SimplePDF chrome from the editor.
Step 3: Deploy to your host
The fastest path is the one-click DigitalOcean deploy button in the SimplePDF Copilot README. DigitalOcean builds the copilot/ folder with Node 24 and prompts for environment variables.
VITE_SIMPLEPDF_COMPANY_IDENTIFIER(required): your SimplePDF company identifier.SHARED_API_KEYS(optional): lets you share a demo without asking each visitor to paste a provider key.REDIS_URL(optional): persists rate-limit counters across containers.IP_HASH_SALT(required whenREDIS_URLis set): salts persisted IP hashes.
For other deploy targets, including Cloudflare Containers, Vercel, Render, fly.io, Railway, and self-hosted Docker, follow the other deploy targets section of the README.
Once deployed, add the deployed origin, for example https://copilot.example.com, to your SimplePDF dashboard whitelist before opening the app.
Step 4: Wire up your AI provider
Server-side streaming lives in src/routes/api/chat.ts. Provider selection lives in src/server/language_model.ts. Use this path when your application owns the provider key, rate limits, logs, and tenant configuration.
For user-provided keys, the browser-direct BYOK path in src/lib/byok/ calls the provider from the browser and bypasses your server. This is also the right shape for local OpenAI-compatible endpoints such as Ollama or LM Studio.
Three routes, three trust boundaries:
- Server-side provider key. Your app owns the provider account and tenant policy. AI traffic flows through your server to the AI provider.
- Browser BYOK. Users bring their own provider key. AI traffic flows from the browser directly to the selected provider, bypassing your server.
- Local OpenAI-compatible endpoint. AI traffic stays on the user's device or network. The browser talks to the local endpoint; nothing goes to a third-party AI provider.
Step 5: Route submissions to your own storage
By default, completed documents land in SimplePDF storage. With Bring Your Own Storage on Pro and above, completed documents upload directly from the browser to your configured storage using pre-signed URLs.
This changes the completed-document storage path. It does not, by itself, control what document context is sent to your configured AI provider. Configure the AI route separately in Step 4.
Configure storage:
Step 6: Verify the production setup
Before sharing the app with users, verify the full path end to end:
- Open the deployed Copilot URL from the whitelisted origin.
- Confirm the SimplePDF editor iframe loads without origin errors.
- Send a test prompt and confirm the selected AI route is used.
- Fill a field and confirm the value appears in the PDF editor.
- Submit or download a test document.
- If BYOS is enabled, confirm the completed PDF lands in your storage, not SimplePDF storage.
- Review logs for secrets, document text, PHI, PII, or other sensitive data you do not want persisted.
Customize the system prompt and tools
Once Copilot runs end to end on your infrastructure, the next layer of customization is the system prompt and tool registry exposed to the model. Both live under src/server/tools.ts. The chat UI itself is src/components/chat_pane.tsx. Locales are in src/locales/.
For everything else, including forking, configuration, and adapting Copilot to a non-trivial product surface, the fork-and-go skill drives an AI coding assistant through the work one decision at a time.
Troubleshooting
The editor iframe refuses to load
Check that the parent app origin is whitelisted in the SimplePDF dashboard. The local demo workspace only allows http://localhost:3001.
The local demo works but production does not
Confirm VITE_SIMPLEPDF_COMPANY_IDENTIFIER uses your own SimplePDF company identifier and that your production domain is in the allowed origins list.
Users are asked to paste an AI key
That is expected for BYOK mode. To share a preconfigured demo, configure SHARED_API_KEYS and use the ?share=<id> URL flow.
Rate limits reset on each deploy
In-memory rate limits reset when the app restarts. Use REDIS_URL and IP_HASH_SALT if counters need to persist across containers or restarts.
Completed PDFs do not land in your storage
Confirm Bring Your Own Storage is configured in SimplePDF and test with a small PDF before using production forms.
That's it! Your Copilot app now runs on your infrastructure, uses your configured AI route, and can send completed documents to your storage when BYOS is enabled.
If you have any questions, feel free to reach out to support@simplepdf.com
You may also be interested in
- Add required fields on PDF forms
- Customize the editor and add your own branding
- Customize the submission confirmation
- Save edited PDF submissions to Supabase
- Get email notifications on PDF form submissions
- Organize documents with tags
- Connect SharePoint as your storage for PDF submissions
- Embed the PDF editor in SharePoint
- Configure your own S3 bucket for PDF form submissions
- Configure your own Azure Blob Storage for PDF form submissions
- Configure Webhooks to get notified of new PDF form submissions
- Save the PDF submissions to your Bubble Database using Bubble workflows
- Connect SimplePDF with Activepieces to automate your PDF forms processing
- Use the Robocorp integration to leverage AI in your IDP workflow
- Add the embed PDF editor to a Next.js App
- View and edit PDF in Excalidraw