OpenAI is shutting down Agent Builder, the visual canvas it launched less than a year ago, on November 30, 2026. The Evals platform and reusable prompt objects go with it. If you wired a document generation step into a drag-and-drop agent workflow, you have about two months to move that step into code.
This article covers the confirmed dates, what the migration actually looks like for a PDF workflow, and the more general point underneath: orchestration layers churn faster than the APIs they orchestrate.
What exactly is OpenAI deprecating, and when?
Three products, announced together on June 3, 2026 in the OpenAI developer changelog, all leaving the platform on November 30, 2026: the visual Agent Builder, the Evals platform, and reusable prompt objects including the v1/prompts API. Evals has one extra milestone, October 31, 2026, when existing evals become read-only.
| Product | Announced | Intermediate date | Shutdown | OpenAI points to |
|---|---|---|---|---|
| Agent Builder | June 3, 2026 | none | November 30, 2026 | Agents SDK, or Workspace Agents in ChatGPT |
| Evals platform | June 3, 2026 | October 31, 2026, existing evals read-only | November 30, 2026 | Datasets |
Reusable prompt objects (v1/prompts) | June 3, 2026 | none | November 30, 2026 | Move prompt content into application code |
The Agent Builder guide carries the notice directly: existing users can continue using it during the transition window, and the product is scheduled to shut down on November 30, 2026. ChatKit, the embeddable chat interface that shipped alongside it, is not on the list.
Agent Builder was announced as part of AgentKit at OpenAI DevDay on October 6, 2025. Eight months from launch to deprecation notice, fourteen months from launch to shutdown.
Why does this matter if you only used it to make documents?
Because the document step itself is fine, and the thing that called it is not. An HTTP node in a visual canvas is a few fields: a URL, a header, a JSON body. Those fields survive. What disappears is the canvas that held them, the branching logic around them, and the run history attached to them.
That asymmetry is the practical lesson. The API contract you called is a public, versioned, documented surface with its own deprecation policy. The builder that called it was a product feature, and product features get cut when a company decides a code-first SDK is the better bet. Anything you encoded only inside the canvas, retry rules, conditional branches, prompt text pasted into a node, has to be re-expressed somewhere else by hand.
So the migration work is proportional to how much of your logic lived in the visual layer rather than behind an API boundary. A team whose canvas had one HTTP node pointing at a documented endpoint rewrites a caller in an afternoon. A team that built a fifteen-node decision tree with inline prompts rebuilds a small application.
What does the migration look like for a PDF workflow?
You replace the canvas with a function. The node that posted to a PDF endpoint becomes a direct HTTP call in your own code, and the surrounding branching becomes ordinary control flow or an Agents SDK agent. The endpoint, the auth header, and the request body do not change.
Here is the direct REST call, with no agent framework involved at all:
const res = await fetch("https://pdf4.dev/api/v1/render", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PDF4_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
template_id: "invoice",
data: {
company_name: "Acme Corp",
invoice_number: "INV-2026-0912",
total: "1,500.00 EUR",
},
delivery: "url",
}),
});
const { url, expires_at, size_bytes } = await res.json();That is the whole document step. delivery: "url" returns a signed link valid for 24 hours instead of a base64 payload, which matters when the result passes back through a model context window.
If the workflow was orchestrated by an LLM rather than by fixed control flow, the same call becomes a tool the model can invoke:
from agents import Agent, function_tool
import httpx, os
@function_tool
def render_invoice(company_name: str, invoice_number: str, total: str) -> str:
"""Generate an invoice PDF and return a download URL."""
r = httpx.post(
"https://pdf4.dev/api/v1/render",
headers={"Authorization": f"Bearer {os.environ['PDF4_API_KEY']}"},
json={
"template_id": "invoice",
"data": {
"company_name": company_name,
"invoice_number": invoice_number,
"total": total,
},
"delivery": "url",
},
)
return r.json()["url"]
agent = Agent(
name="Billing agent",
instructions="Generate invoices when asked. Return the PDF link.",
tools=[render_invoice],
)Same endpoint, same payload, different caller. The knowledge that survived the shutdown is the API contract, not the orchestration.
When should you use an MCP server instead of a REST call?
Use REST when the document is a fixed step your code always takes, and MCP when the agent has to decide whether a document is needed at all. MCP exposes PDF generation as a discoverable tool with typed inputs, so the model reads the schema and picks the arguments. REST keeps that decision in your code, which makes the outcome deterministic and the failure modes easier to reason about.
For PDF4.dev the MCP endpoint is one config block, and it is the same account and the same API key as the REST path:
{
"mcpServers": {
"pdf4": {
"url": "https://pdf4.dev/api/mcp",
"headers": { "Authorization": "Bearer p4_live_xxx" }
}
}
}The reason MCP is worth considering during a forced migration is that it is a published protocol with a versioned specification rather than one vendor's product surface. The same server works from Claude, ChatGPT, Cursor, and any other client that speaks the protocol, so a client going away does not take the integration with it. That is the same durability argument as the REST endpoint, applied to the agent-facing side.
| Approach | Who decides to render | Breaks when | Best for |
|---|---|---|---|
| Direct REST call | Your code | The API provider deprecates the endpoint | Fixed pipeline steps, batch jobs, deterministic billing runs |
| Agent tool wrapping REST | The model, within your framework | The framework changes its tool API | Conversational flows in one runtime |
| MCP server | The model, in any MCP client | The protocol revision is breaking | Multi-client agent setups, tools reused across ChatGPT, Claude, Cursor |
| Visual builder node | The canvas | The vendor discontinues the product | Prototyping, validating a workflow before committing code |
Is the lesson that no-code orchestration was a mistake?
No, and treating it that way misreads the tradeoff. A visual builder answers one question faster than code: is this workflow worth building. Dragging four nodes onto a canvas and watching a real invoice come out the other end takes minutes and needs no deployment, no dependency install, and no CI. That is genuine value, and it is worth paying for with the occasional rewrite.
The failure mode is not using the builder. It is letting the builder accumulate logic that exists nowhere else. Prompt text typed into a node, a retry policy set in a dropdown, a branching condition drawn as an arrow: none of that is in your repository, none of it is in code review, and none of it survives a product sunset.
A reasonable split: prototype in the visual tool, then move anything that runs in production behind an interface you control. The visual layer stays thin enough that replacing it is a day of work rather than a quarter.
What should you check before November 30, 2026?
Inventory where your logic actually lives. The migration cost is entirely determined by how much of it sits inside the canvas rather than behind an API boundary, so the audit is more useful than any migration guide.
- Export every workflow definition now, before the shutdown. Screenshots of the canvas are not a backup. You want the prompt text, the node configuration, and the conditions in a file in your repo.
- List every external call. Each HTTP node is a URL, a method, an auth header, and a body schema. Those transfer unchanged to whatever calls them next.
- Find the logic that exists only in the canvas. Inline prompts, branch conditions, retry settings, default values. This is the part you rewrite, and the part you will forget if you do not write it down first.
- Check your evals separately. Evals go read-only on October 31, 2026, a month before the rest. If you have test suites there, export the datasets and the grading criteria before that date, not before November 30.
- Pick the replacement per workflow, not globally. Some flows are a scheduled script with three API calls and never needed an agent. Others genuinely need a model in the loop and belong in the Agents SDK or behind an MCP server.
The durable layer is the one with a contract
The pattern generalizes past this one shutdown. Orchestration layers are where vendors experiment, so they move fast and get replaced. API endpoints and open protocols carry explicit contracts, versioning, and published deprecation timelines, so they move slowly on purpose.
When you build a document workflow, the question worth asking is which parts have a contract behind them. A REST endpoint with an OpenAPI spec does. An MCP server implementing a published specification does. A node on a canvas in a product that launched eight months ago does not, and that is the part to keep replaceable.
PDF4.dev exposes both durable surfaces: a documented REST API at /api/v1/render and an MCP server at /api/mcp, sharing one account and one API key. Whatever orchestrates them next year, the call stays the same.
Sources
- OpenAI developer changelog, June 3, 2026 entry announcing the deprecation of reusable prompt objects, the Evals platform, and Agent Builder
- OpenAI deprecations page, shutdown dates and recommended replacements
- Agent Builder guide, in-product deprecation notice
- Evals guide, October 31, 2026 read-only date
- Introducing AgentKit, original launch announcement
Free tools mentioned:
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.



