AI setup prompt
One-prompt setup — paste into any AI assistant to generate a complete integration for your stack.
AI project setup — one-prompt Craftkit integration
Copy the prompt below and paste it directly into Claude, ChatGPT, Cursor, or any AI coding assistant. The AI will ask you a few questions and then generate a complete, production-ready Craftkit integration tailored to your project.
The prompt
You are setting up a complete Craftkit document-generation integration. Craftkit (https://www.craftkit.dev) lets SaaS apps embed a template builder and/or a document form-fill widget. It also exposes a REST API for programmatic PDF rendering.
Ask me the following questions ONE AT A TIME before writing any code:
- Stack: What framework and language is your backend? (Next.js App Router, Express, FastAPI, Rails, Laravel, etc.)
- Frontend: What framework is your frontend? (React, Vue, Svelte, vanilla JS, etc.)
- Auth: What auth system do you use? (Clerk, NextAuth, custom JWT, session cookies, etc.) — I need to know how to protect the Craftkit proxy routes.
- Tenancy: Is this single-tenant (one org) or multi-tenant (many orgs, each needing isolated templates)?
- Use case: Which embed surfaces do you need?
- (A) Builder only — your customers design their own templates
- (B) Form-fill only — your users fill and generate documents from pre-built templates
- (C) Both — customers design templates; users fill them
- (D) API-only — your backend triggers renders programmatically (no embed)
- Variables: Describe your data model briefly — what fields will populate the documents? (e.g. "customer name/email, booking date/vessel, invoice total")
Once I answer all six questions, generate the following complete, working code with no placeholders:
A. Environment variables
List every env var needed with a comment explaining each one.
B. Backend proxy routes
For Next.js App Router: generate the full
app/api/craftkit/directory tree with all route files. For other frameworks: generate equivalent middleware/controllers. Always use the admin provision pattern for multi-tenant:
lib/credentials.ts—getOrgApiKey(orgId)caches per-org keys viaPOST /v1/admin/provisionsession/route.ts— mint sessions; resolve org key; support modes: create/edit/fill/viewrefresh/route.ts— refresh sessions; must passorgIdand usegetOrgApiKey(orgId), NOT a single fixedCRAFTKIT_API_KEY(that breaks multi-tenant refresh)templates/route.ts— list published templates for an orgrenders/route.ts— list renders for an orgrenders/[id]/download/route.ts— proxy PDF downloadC. Frontend embed component
A complete, reusable React/Vue/vanilla component that:
- Mints a session on mount (calls the backend session route)
- Renders the Craftkit iframe using the returned
iframe_url- Handles
session.expiringby calling the refresh route withorgId- Handles
session.expiredby re-minting- Emits
onPublishedwhen a template is published (savescraftkitTemplateIdto your DB)- Emits
onCompletedwhen a form-fill document is ready- Shows a loading state while minting and an error state on failure
D. Variable catalog
Generate a
POST /v1/embed/catalogscall (curl + equivalent code) with my data model mapped to Craftkit field types (text,number,currency,date,url,image,boolean,longtext). Mark fields that should be required in the form.E. Example page
One example page/route that uses the embed component — create mode for a new template or fill mode for a document.
F. Checklist
A copy-paste checklist of everything I need to do in the Craftkit dashboard before this code will work:
- Create account and project
- Enable embed mode (Dashboard → Project → Embed → Overview)
- Add allowed origins for the embed iframe
- Note the CRAFTKIT_ADMIN_KEY from project settings
- (if catalog) Publish the variable catalog and note its name
Key rules the AI must follow when generating code:
- Never hardcode API keys or secrets — always use env vars
- The refresh route MUST use
getOrgApiKey(orgId), not a fixedCRAFTKIT_API_KEY- The
templateExternalIdpassed to session minting must be the Craftkit UUID (from thetemplate.publishedevent), NOT an internal MongoDB ObjectId or integer ID- The
iframe_urlfrom the session response must be used verbatim — never construct the iframe URL manually (path differs between fill and builder modes)- Validate
e.originbefore acting on postMessage events- Always mint a fresh session for each iframe mount — never cache
iframe_url
What the AI will generate
Depending on your answers, the AI generates a complete, drop-in integration:
| Answer | Generated output |
|---|---|
| Next.js + Clerk + multi-tenant + builder + form | Full app/api/craftkit/ directory, CraftkitEmbed component, Clerk auth() guard, Zustand/React Query hooks |
| Express + JWT + single-tenant + API-only | Middleware, render controller, webhook handler, polling utility |
| Next.js + NextAuth + single-tenant + form-fill | Slim proxy (no provision), form-fill component, catalog |
Quick reference — key decisions
Multi-tenant vs single-tenant
| Single-tenant | Multi-tenant | |
|---|---|---|
| Env vars | CRAFTKIT_API_KEY (one fixed key) |
CRAFTKIT_ADMIN_KEY (provision key) |
| Session mint | Use CRAFTKIT_API_KEY directly |
Call getOrgApiKey(orgId) |
| Session refresh | Use CRAFTKIT_API_KEY directly |
Call getOrgApiKey(orgId) — MUST match session's org |
| Org isolation | Shared project | One Craftkit project per org, auto-provisioned |
Mode cheat sheet
| Mode | iframe path | Permissions required |
|---|---|---|
create |
/embed/builder |
publish: true, saveDraft: true (defaults) |
edit |
/embed/builder |
publish: true, saveDraft: true (defaults) |
view |
/embed/builder |
publish: false, saveDraft: false |
fill |
/embed/form |
submitForm: true ← must set explicitly |
Critical pitfalls
Never use a MongoDB ObjectId as
templateExternalId— Craftkit requires UUID format. Store the UUID from thetemplate.publishedevent and use that.Never cache
iframe_urlacross page navigations — each mount needs a fresh mint.Never use a fixed
CRAFTKIT_API_KEYfor refresh in multi-tenant — the session'spartnerIdmust match the key used for refresh. UsegetOrgApiKey(orgId).submitFormdefaults tofalse— fill sessions must explicitly set it totrue.API keys are environment-specific — a key created in local dev does not exist in production. Always create keys in the target environment's Craftkit dashboard.
Related
- Integration guide — full phase-by-phase walkthrough
- Multi-tenant embed — admin provision deep dive
- Embed quickstart — minimal setup
- Variable catalog — field schema reference
- Client integration guide — pitfall checklist