[{"data":1,"prerenderedAt":824},["ShallowReactive",2],{"guide-\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fchatgpt":3,"guides-all":755},{"id":4,"title":5,"body":6,"category":745,"description":746,"extension":747,"icon":748,"meta":749,"navigation":750,"order":197,"path":751,"seo":752,"stem":753,"__hash__":754},"guides\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fchatgpt.md","ChatGPT (via Custom GPT Actions)",{"type":7,"value":8,"toc":736},"minimark",[9,14,27,48,53,76,80,92,99,118,122,137,589,596,628,631,635,638,644,651,656,663,667,673,681,685,695,703,709,713,732],[10,11,13],"h1",{"id":12},"chatgpt","ChatGPT",[15,16,17,18,22,23,26],"p",{},"ChatGPT doesn't (yet) consume MCP natively. The workaround is a ",[19,20,21],"strong",{},"Custom GPT"," with ",[19,24,25],{},"Actions"," pointed at the Transactional REST API. The end result is the same: ChatGPT can list your documents and generate PDFs.",[28,29,42],"aside",{"className":30},[31,32,33,34,35,36,37,38,39,40,41],"not-prose","my-6","rounded-md","border","border-amber-200","bg-amber-50","text-amber-900","px-4","py-3","text-[14px]","leading-relaxed",[15,43,44,47],{},[19,45,46],{},"MCP support in ChatGPT"," is being rolled out in stages. When it lands fully, this guide will be replaced with a one-step config like the other clients. In the meantime, Custom GPT Actions are the supported path.",[49,50,52],"h2",{"id":51},"prerequisites","Prerequisites",[54,55,56,68],"ul",{},[57,58,59,60,63,64,67],"li",{},"ChatGPT ",[19,61,62],{},"Plus"," or ",[19,65,66],{},"Team\u002FEnterprise"," (Custom GPTs require a paid plan)",[57,69,70,71,75],{},"A Transactional API token (",[72,73,74],"code",{},"tk_live_…",")",[49,77,79],{"id":78},"_1-create-a-custom-gpt","1. Create a Custom GPT",[15,81,82,83,86,87,91],{},"In ChatGPT, click your avatar → ",[19,84,85],{},"My GPTs → Create",". Pick a name (e.g. ",[88,89,90],"em",{},"Transactional Assistant",") and a description.",[15,93,94,95,98],{},"In the ",[19,96,97],{},"Configure"," tab:",[54,100,101,107,113],{},[57,102,103,106],{},[19,104,105],{},"Instructions"," — paste the snippet at the bottom of this guide.",[57,108,109,112],{},[19,110,111],{},"Capabilities"," — disable Web browsing and DALL-E unless you actually need them. Leave Code interpreter off.",[57,114,115,117],{},[19,116,25],{}," — see step 2.",[49,119,121],{"id":120},"_2-add-the-action","2. Add the Action",[15,123,124,125,128,129,136],{},"Click ",[19,126,127],{},"Create new action",". In the schema field, paste the trimmed OpenAPI document below (it's the relevant subset of our full ",[130,131,135],"a",{"href":132,"rel":133},"https:\u002F\u002Fapi.transactional.dev\u002Fopenapi.yaml",[134],"nofollow","openapi.yaml",", reduced to the endpoints a GPT actually needs):",[138,139,144],"pre",{"className":140,"code":141,"language":142,"meta":143,"style":143},"language-yaml shiki shiki-themes github-light github-dark","openapi: 3.1.0\ninfo:\n  title: Transactional API\n  version: \"1.0.0\"\nservers:\n  - url: https:\u002F\u002Fapi.transactional.dev\npaths:\n  \u002Fv1\u002Fdocuments:\n    get:\n      operationId: listDocuments\n      summary: List the user's templates.\n      responses:\n        \"200\": { description: OK }\n  \u002Fv1\u002Fdocuments\u002F{id}:\n    get:\n      operationId: getDocument\n      summary: Get a template with its sample variables.\n      parameters:\n        - in: path\n          name: id\n          required: true\n          schema: { type: integer }\n      responses:\n        \"200\": { description: OK }\n  \u002Fv1\u002Fgenerate:\n    post:\n      operationId: generatePdf\n      summary: Render a template to PDF.\n      requestBody:\n        required: true\n        content:\n          application\u002Fjson:\n            schema:\n              type: object\n              required: [documentId]\n              properties:\n                documentId: { type: string, format: uuid }\n                variables: { type: object }\n      responses:\n        \"200\": { description: OK }\n","yaml","",[72,145,146,163,172,184,195,203,217,225,233,241,252,263,271,291,299,306,316,326,334,348,359,370,388,395,410,418,426,436,446,454,464,472,480,488,499,514,522,550,567,574],{"__ignoreMap":143},[147,148,151,155,159],"span",{"class":149,"line":150},"line",1,[147,152,154],{"class":153},"s9eBZ","openapi",[147,156,158],{"class":157},"sVt8B",": ",[147,160,162],{"class":161},"sj4cs","3.1.0\n",[147,164,166,169],{"class":149,"line":165},2,[147,167,168],{"class":153},"info",[147,170,171],{"class":157},":\n",[147,173,175,178,180],{"class":149,"line":174},3,[147,176,177],{"class":153},"  title",[147,179,158],{"class":157},[147,181,183],{"class":182},"sZZnC","Transactional API\n",[147,185,187,190,192],{"class":149,"line":186},4,[147,188,189],{"class":153},"  version",[147,191,158],{"class":157},[147,193,194],{"class":182},"\"1.0.0\"\n",[147,196,198,201],{"class":149,"line":197},5,[147,199,200],{"class":153},"servers",[147,202,171],{"class":157},[147,204,206,209,212,214],{"class":149,"line":205},6,[147,207,208],{"class":157},"  - ",[147,210,211],{"class":153},"url",[147,213,158],{"class":157},[147,215,216],{"class":182},"https:\u002F\u002Fapi.transactional.dev\n",[147,218,220,223],{"class":149,"line":219},7,[147,221,222],{"class":153},"paths",[147,224,171],{"class":157},[147,226,228,231],{"class":149,"line":227},8,[147,229,230],{"class":153},"  \u002Fv1\u002Fdocuments",[147,232,171],{"class":157},[147,234,236,239],{"class":149,"line":235},9,[147,237,238],{"class":153},"    get",[147,240,171],{"class":157},[147,242,244,247,249],{"class":149,"line":243},10,[147,245,246],{"class":153},"      operationId",[147,248,158],{"class":157},[147,250,251],{"class":182},"listDocuments\n",[147,253,255,258,260],{"class":149,"line":254},11,[147,256,257],{"class":153},"      summary",[147,259,158],{"class":157},[147,261,262],{"class":182},"List the user's templates.\n",[147,264,266,269],{"class":149,"line":265},12,[147,267,268],{"class":153},"      responses",[147,270,171],{"class":157},[147,272,274,277,280,283,285,288],{"class":149,"line":273},13,[147,275,276],{"class":182},"        \"200\"",[147,278,279],{"class":157},": { ",[147,281,282],{"class":153},"description",[147,284,158],{"class":157},[147,286,287],{"class":182},"OK",[147,289,290],{"class":157}," }\n",[147,292,294,297],{"class":149,"line":293},14,[147,295,296],{"class":153},"  \u002Fv1\u002Fdocuments\u002F{id}",[147,298,171],{"class":157},[147,300,302,304],{"class":149,"line":301},15,[147,303,238],{"class":153},[147,305,171],{"class":157},[147,307,309,311,313],{"class":149,"line":308},16,[147,310,246],{"class":153},[147,312,158],{"class":157},[147,314,315],{"class":182},"getDocument\n",[147,317,319,321,323],{"class":149,"line":318},17,[147,320,257],{"class":153},[147,322,158],{"class":157},[147,324,325],{"class":182},"Get a template with its sample variables.\n",[147,327,329,332],{"class":149,"line":328},18,[147,330,331],{"class":153},"      parameters",[147,333,171],{"class":157},[147,335,337,340,343,345],{"class":149,"line":336},19,[147,338,339],{"class":157},"        - ",[147,341,342],{"class":153},"in",[147,344,158],{"class":157},[147,346,347],{"class":182},"path\n",[147,349,351,354,356],{"class":149,"line":350},20,[147,352,353],{"class":153},"          name",[147,355,158],{"class":157},[147,357,358],{"class":182},"id\n",[147,360,362,365,367],{"class":149,"line":361},21,[147,363,364],{"class":153},"          required",[147,366,158],{"class":157},[147,368,369],{"class":161},"true\n",[147,371,373,376,378,381,383,386],{"class":149,"line":372},22,[147,374,375],{"class":153},"          schema",[147,377,279],{"class":157},[147,379,380],{"class":153},"type",[147,382,158],{"class":157},[147,384,385],{"class":182},"integer",[147,387,290],{"class":157},[147,389,391,393],{"class":149,"line":390},23,[147,392,268],{"class":153},[147,394,171],{"class":157},[147,396,398,400,402,404,406,408],{"class":149,"line":397},24,[147,399,276],{"class":182},[147,401,279],{"class":157},[147,403,282],{"class":153},[147,405,158],{"class":157},[147,407,287],{"class":182},[147,409,290],{"class":157},[147,411,413,416],{"class":149,"line":412},25,[147,414,415],{"class":153},"  \u002Fv1\u002Fgenerate",[147,417,171],{"class":157},[147,419,421,424],{"class":149,"line":420},26,[147,422,423],{"class":153},"    post",[147,425,171],{"class":157},[147,427,429,431,433],{"class":149,"line":428},27,[147,430,246],{"class":153},[147,432,158],{"class":157},[147,434,435],{"class":182},"generatePdf\n",[147,437,439,441,443],{"class":149,"line":438},28,[147,440,257],{"class":153},[147,442,158],{"class":157},[147,444,445],{"class":182},"Render a template to PDF.\n",[147,447,449,452],{"class":149,"line":448},29,[147,450,451],{"class":153},"      requestBody",[147,453,171],{"class":157},[147,455,457,460,462],{"class":149,"line":456},30,[147,458,459],{"class":153},"        required",[147,461,158],{"class":157},[147,463,369],{"class":161},[147,465,467,470],{"class":149,"line":466},31,[147,468,469],{"class":153},"        content",[147,471,171],{"class":157},[147,473,475,478],{"class":149,"line":474},32,[147,476,477],{"class":153},"          application\u002Fjson",[147,479,171],{"class":157},[147,481,483,486],{"class":149,"line":482},33,[147,484,485],{"class":153},"            schema",[147,487,171],{"class":157},[147,489,491,494,496],{"class":149,"line":490},34,[147,492,493],{"class":153},"              type",[147,495,158],{"class":157},[147,497,498],{"class":182},"object\n",[147,500,502,505,508,511],{"class":149,"line":501},35,[147,503,504],{"class":153},"              required",[147,506,507],{"class":157},": [",[147,509,510],{"class":182},"documentId",[147,512,513],{"class":157},"]\n",[147,515,517,520],{"class":149,"line":516},36,[147,518,519],{"class":153},"              properties",[147,521,171],{"class":157},[147,523,525,528,530,532,534,537,540,543,545,548],{"class":149,"line":524},37,[147,526,527],{"class":153},"                documentId",[147,529,279],{"class":157},[147,531,380],{"class":153},[147,533,158],{"class":157},[147,535,536],{"class":182},"string",[147,538,539],{"class":157},", ",[147,541,542],{"class":153},"format",[147,544,158],{"class":157},[147,546,547],{"class":182},"uuid",[147,549,290],{"class":157},[147,551,553,556,558,560,562,565],{"class":149,"line":552},38,[147,554,555],{"class":153},"                variables",[147,557,279],{"class":157},[147,559,380],{"class":153},[147,561,158],{"class":157},[147,563,564],{"class":182},"object",[147,566,290],{"class":157},[147,568,570,572],{"class":149,"line":569},39,[147,571,268],{"class":153},[147,573,171],{"class":157},[147,575,577,579,581,583,585,587],{"class":149,"line":576},40,[147,578,276],{"class":182},[147,580,279],{"class":157},[147,582,282],{"class":153},[147,584,158],{"class":157},[147,586,287],{"class":182},[147,588,290],{"class":157},[15,590,591,592,595],{},"Then in ",[19,593,594],{},"Authentication"," pick:",[54,597,598,604,610,619],{},[57,599,600,603],{},[19,601,602],{},"Type"," — API Key",[57,605,606,609],{},[19,607,608],{},"Auth Type"," — Custom",[57,611,612,615,616],{},[19,613,614],{},"Custom header name"," — ",[72,617,618],{},"x-api-token",[57,620,621,624,625,627],{},[19,622,623],{},"API Key"," — your ",[72,626,74],{}," token",[15,629,630],{},"Save the action.",[49,632,634],{"id":633},"_3-use-it","3. Use it",[15,636,637],{},"In any chat with this Custom GPT:",[639,640,641],"blockquote",{},[15,642,643],{},"\"List my Transactional templates.\"",[15,645,646,647,650],{},"ChatGPT will call ",[72,648,649],{},"listDocuments",", ask permission, then summarize what it found. Then:",[639,652,653],{},[15,654,655],{},"\"Generate the invoice template for customer Acme Corp, total 1280.50 €, one line item 'Pro subscription'.\"",[15,657,658,659,662],{},"ChatGPT calls ",[72,660,661],{},"generatePdf"," with the right body. The response includes the signed PDF URL — ChatGPT will print it inline.",[49,664,666],{"id":665},"suggested-system-instructions","Suggested system instructions",[15,668,669,670,672],{},"Paste this into the Custom GPT's ",[19,671,105],{}," field:",[138,674,679],{"className":675,"code":677,"language":678,"meta":143},[676],"language-text","You are a Transactional assistant. The user has HTML\u002FTailwind\u002FHandlebars templates\nstored in Transactional. You can:\n1. listDocuments() to see what's available.\n2. getDocument({id}) to inspect a template's body, fonts, and the sample variables it expects.\n3. generatePdf({documentId, variables}) to render a PDF.\n\nWorkflow:\n- If the user asks to generate a PDF, first listDocuments and then getDocument\n  to learn the exact variables shape. Don't invent variable names — they must match\n  what the template expects.\n- documentId is the template's UUID, not the numeric id.\n- The response of generatePdf includes `url`. It is short-lived. Print it to the user\n  immediately and tell them to save it.\n- Branch on the `error` field of any non-2xx response. Common codes:\n  invalid_document_id (400), UNAUTHORIZED (401), quota_exceeded (402),\n  NOT_FOUND (404), SERVICE_UNAVAILABLE (503 — safe to retry).\n- Never log the API token.\n","text",[72,680,677],{"__ignoreMap":143},[49,682,684],{"id":683},"troubleshooting","Troubleshooting",[15,686,687,690,691,694],{},[19,688,689],{},"\"Allowed domains\" warning"," — ChatGPT requires the domain to be added when you publish the GPT. Use ",[72,692,693],{},"api.transactional.dev",".",[15,696,697,702],{},[19,698,699],{},[72,700,701],{},"quota_exceeded"," — Out of generation credits. Top up or upgrade in the dashboard.",[15,704,705,708],{},[19,706,707],{},"Calls succeed but the URL ChatGPT prints is mangled"," — Some GPT models truncate long URLs. Ask \"show me the raw URL from the last response\" — it'll print it verbatim.",[49,710,712],{"id":711},"next-steps","Next steps",[54,714,715,723],{},[57,716,717],{},[19,718,719],{},[130,720,722],{"href":721},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fuse-from-ai#a-first-prompt-to-try","A first prompt to try →",[57,724,725,731],{},[19,726,727],{},[130,728,730],{"href":729},"\u002Fdocs\u002Fguides\u002Fintegrations\u002Fnode-bun","Calling \u002Fv1\u002Fgenerate from your own code →"," — once you've sketched a workflow with ChatGPT, you may want to bake it into your backend.",[733,734,735],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":143,"searchDepth":165,"depth":165,"links":737},[738,739,740,741,742,743,744],{"id":51,"depth":165,"text":52},{"id":78,"depth":165,"text":79},{"id":120,"depth":165,"text":121},{"id":633,"depth":165,"text":634},{"id":665,"depth":165,"text":666},{"id":683,"depth":165,"text":684},{"id":711,"depth":165,"text":712},"ai-mcp","ChatGPT doesn't speak MCP natively yet — but you can give it the same powers through a Custom GPT pointed at the Transactional REST API.","md","message-circle",{},true,"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fchatgpt",{"title":5,"description":746},"docs\u002Fguides\u002Fai-mcp\u002Fchatgpt","8bbHJWbdz-A9DwOryBAtkT9qGTy4EpwbckWn0_1Z8PI",[756,757,761,765,769,773,777,781,786,790,794,798,803,807,811,815,820],{"path":751,"title":5,"description":746,"category":745,"order":197},{"path":758,"title":759,"description":760,"category":745,"order":174},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fclaude-code","Claude Code (CLI)","Connect Transactional to Claude Code so it can read your templates and generate PDFs from your terminal.",{"path":762,"title":763,"description":764,"category":745,"order":165},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fclaude-desktop","Claude Desktop","Connect Transactional to Claude Desktop on macOS or Windows so Claude can read your templates and generate PDFs.",{"path":766,"title":767,"description":768,"category":745,"order":186},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fcursor","Cursor","Wire Transactional into Cursor's MCP support so you can generate PDFs from inside your editor.",{"path":770,"title":771,"description":772,"category":745,"order":205},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fgemini","Gemini Code Assist \u002F Gemini CLI","Connect Transactional to Google's Gemini agents through their MCP support.",{"path":774,"title":775,"description":776,"category":745,"order":219},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Ftools-reference","MCP tools reference","Every tool the Transactional MCP server exposes, with arguments, return shapes, and a prompt that typically triggers each one.",{"path":778,"title":779,"description":780,"category":745,"order":150},"\u002Fdocs\u002Fguides\u002Fai-mcp\u002Fuse-from-ai","Use Transactional from your AI assistant","Connect Transactional to Claude, Cursor, ChatGPT, or Gemini via MCP so your assistant can read your templates and generate PDFs directly.",{"path":782,"title":783,"description":784,"category":785,"order":165},"\u002Fdocs\u002Fguides\u002Fauthoring\u002Fdesign-for-pdf","Designing templates that survive PDF rendering","PDFs are static — drop the animations, oversample your canvas charts, lean on vectors. The rules that make a template look sharp at print resolution.","authoring",{"path":787,"title":788,"description":789,"category":785,"order":150},"\u002Fdocs\u002Fguides\u002Fauthoring\u002Fhandlebars","Handlebars cheat sheet","The exact subset of Handlebars supported in Transactional templates — variables, conditionals, loops, and what NOT to reach for.",{"path":791,"title":792,"description":793,"category":785,"order":174},"\u002Fdocs\u002Fguides\u002Fauthoring\u002Fmodeling-variables","Modeling your variables","When to make something a variable vs. inline. Keep the API contract small, your templates portable, and your integration code boring.",{"path":795,"title":796,"description":797,"category":785,"order":186},"\u002Fdocs\u002Fguides\u002Fauthoring\u002Fworking-with-ai","Working with the AI assistant","Prompts and patterns to get good templates fast — what to ask, when to iterate, when to start over.",{"path":799,"title":800,"description":801,"category":802,"order":150},"\u002Fdocs\u002Fguides\u002Fgetting-started\u002Fquickstart","Quickstart — your first PDF in 5 minutes","Sign up, design a template, render your first PDF through the API. End-to-end in five minutes.","getting-started",{"path":729,"title":804,"description":805,"category":806,"order":150},"Calling \u002Fv1\u002Fgenerate from Node.js & Bun","Production-grade integration using native fetch — retries, error handling, streaming the PDF to your storage.","integrations",{"path":808,"title":809,"description":810,"category":806,"order":165},"\u002Fdocs\u002Fguides\u002Fintegrations\u002Fphp-laravel","Calling \u002Fv1\u002Fgenerate from PHP & Laravel","cURL extension, Guzzle, or Laravel's HTTP client — render PDFs with retries and proper error handling.",{"path":812,"title":813,"description":814,"category":806,"order":174},"\u002Fdocs\u002Fguides\u002Fintegrations\u002Fpython","Calling \u002Fv1\u002Fgenerate from Python","urllib (stdlib), requests, or httpx with retry — render PDFs from Django, FastAPI, or any Python service.",{"path":816,"title":817,"description":818,"category":819,"order":150},"\u002Fdocs\u002Fguides\u002Foperations\u002Fmonitoring-usage","Monitoring usage & credits","Read the dashboard gauges, set sane alerts, and decide when to top up vs. upgrade.","operations",{"path":821,"title":822,"description":823,"category":819,"order":165},"\u002Fdocs\u002Fguides\u002Foperations\u002Fstoring-pdfs","Storing & serving the generated PDF","The \u002Fv1\u002Fgenerate URL is signed and short-lived. Patterns for keeping the PDF around — your bucket, your CDN, your DB.",1780347733846]