Claude API Webflow Chatbot Integration Guide
Webflow sites are static by default, which means you can't call the Claude API directly from client-side JavaScript without exposing your API key to every visitor. This guide covers the architecture you actually need: a lightweight backend between Webflow and Claude, how to wire it up, and how to embed the chat widget in your Webflow project without touching the Designer's CMS logic.
If you've landed here searching for "claude api webflow chatbot integration guide," you're probably trying to add a support bot, sales assistant, or FAQ widget to a marketing site built in Webflow. The short answer: you need a server-side endpoint that holds your Claude credentials, and a small JavaScript snippet embedded in Webflow's custom code section that talks to that endpoint. Everything below walks through exactly how to build that.
Why you can't call Claude directly from Webflow
Webflow exports static HTML/CSS/JS plus whatever you add via Embed elements or the site-wide custom code panel. Any API key placed in that JavaScript is visible to anyone who opens dev tools. Anthropic's own API keys are meant to stay server-side, and the same applies to any wrapper service — including SubToAPI's sub_live_ keys. The fix is always the same pattern: browser → your backend → Claude API → your backend → browser.
This means a Webflow chatbot integration has two moving parts:
- A backend endpoint that accepts a user message, forwards it to Claude, and returns the response.
- A frontend widget embedded in Webflow that calls that endpoint and renders the conversation.
Choosing the backend
You have two realistic options:
- Direct Anthropic SDK in a serverless function (Vercel, Netlify, Cloudflare Workers, AWS Lambda). You write the code, manage prompt formatting, handle retries, and build your own usage tracking.
- A hosted API layer like SubToAPI sitting in front of Claude, giving you an HTTPS endpoint with streaming, tool use, and usage metadata already built in, so your Webflow backend call is a single
fetchinstead of SDK plumbing.
Either way, the Webflow side looks identical — a fetch call to a URL you control. The difference is what happens behind that URL. If you want to skip SDK setup, rate-limit logic, and streaming boilerplate, SubToAPI's docs at /docs/quickstart show the full request/response shape, and you can get a key from /signup in a few minutes.
Step 1: Create the backend endpoint
A minimal Node.js serverless function that proxies to SubToAPI:
// api/chat.js
export default async function handler(req, res) {
const { message, history } = req.body;
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 500,
messages: [...history, { role: "user", content: message }]
})
});
const data = await response.json();
res.status(200).json({ reply: data.content[0].text });
}
Deploy this to Vercel, Netlify, or a similar host. You get a public URL like https://your-project.vercel.app/api/chat — this is the only endpoint your Webflow code needs to know about.
Step 2: Add the chat widget to Webflow
In the Webflow Designer, drop an Embed element where you want the chat bubble or panel, and add your HTML markup for the chat UI (input box, message list, send button). Then go to Site Settings → Custom Code → Footer Code and add the JavaScript that drives it:
<script>
const chatForm = document.getElementById("chat-form");
const chatInput = document.getElementById("chat-input");
const chatLog = document.getElementById("chat-log");
let history = [];
chatForm.addEventListener("submit", async (e) => {
e.preventDefault();
const message = chatInput.value;
appendMessage("user", message);
chatInput.value = "";
const res = await fetch("https://your-project.vercel.app/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message, history })
});
const data = await res.json();
appendMessage("assistant", data.reply);
history.push({ role: "user", content: message });
history.push({ role: "assistant", content: data.reply });
});
function appendMessage(role, text) {
const div = document.createElement("div");
div.className = `chat-message ${role}`;
div.textContent = text;
chatLog.appendChild(div);
}
</script>
Webflow lets you add this site-wide or on a single page via the page settings panel. Since Webflow doesn't support npm packages natively, keep the widget vanilla JS or load a small bundled script from a CDN if you need something more polished.
Step 3: Add streaming for a better feel
A full response arriving all at once feels slow on longer answers. If your backend supports server-sent events, you can stream tokens as they generate. SubToAPI's streaming works the same way as the standard Messages endpoint, documented at /docs/streaming — you set stream: true and read chunks as they arrive, then forward them to the browser via your own SSE or WebSocket connection. This is the single biggest UX improvement for a chatbot and is worth doing once the basic flow works.
Step 4: Handle context, tools, and rate limits
For a support bot, you'll usually want to ground responses in your own content (FAQ pages, docs, pricing). You can inject that as a system prompt in your backend call, or use tool calling so Claude can fetch live data — order status, pricing lookups, docs search — before answering. The tool use pattern is covered in /docs/tools if you go that route. For the message format itself, including multi-turn history and system prompts, see /docs/messages.
On the operational side, think about per-visitor rate limiting in your backend function so one visitor can't exhaust your token budget. If you're running this for a team with multiple sites or multiple people managing the integration, a dashboard with usage breakdowns and seats (available on SubToAPI's Team and Scale plans — see /pricing) saves you from building that tooling yourself.
Security checklist before launch
- Never put
sub_live_or raw Anthropic keys in Webflow custom code — only in your backend's environment variables. - Add CORS restrictions on your backend endpoint so only your Webflow domain can call it.
- Cap
max_tokensand conversation history length to control cost per session. - Log errors server-side; don't surface raw API error messages to visitors.
questions
Can I call the Claude API directly from Webflow's custom code without a backend? No. Any key in client-side JavaScript is publicly visible in the page source, so you always need a server-side proxy between Webflow and the API.
Does Webflow support npm packages for building the chat widget? Not natively. Stick to vanilla JavaScript in the Embed or custom code panels, or load a pre-bundled script from a CDN if you need a more advanced UI.
How do I keep API costs predictable on a public marketing site? Cap max_tokens, limit conversation history length, and add basic rate limiting per visitor in your backend endpoint before it forwards requests to Claude.