Claude’s API now supports CORS requests, enabling client-side applications
23rd August 2024
Anthropic have enabled CORS support for their JSON APIs, which means it’s now possible to call the Claude LLMs directly from a user’s browser.
This massively significant new feature is tucked away in this pull request: anthropic-sdk-typescript: add support for browser usage, via this issue.
This change to the Anthropic TypeScript SDK reveals the new JSON API feature, which I found by digging through the code.
You can now add the following HTTP request header to enable CORS support for the Anthropic API, which means you can make calls to Anthropic’s models directly from a browser:
anthropic-dangerous-direct-browser-access: true
Anthropic had been resistant to adding this feature because it can encourage a nasty anti-pattern: if you embed your API key in your client code, anyone with access to that site can steal your API key and use it to make requests on your behalf.
Despite that, there are legitimate use cases for this feature. It’s fine for internal tools exposed to trusted users, or you can implement a “bring your own API key” pattern where users supply their own key to use with your client-side app.
As it happens, I’ve built one of those apps myself! My Haiku page is a simple client-side app that requests access to your webcam, asks for an Anthropic API key (which it stores in the browser’s localStorage
), and then lets you take a photo and turns it into a Haiku using their fast and inexpensive Haiku model.
Previously I had to run my own proxy on Vercel adding CORS support to the Anthropic API just to get my Haiku app to work.
This evening I upgraded the app to send that new header, and now it can talk to Anthropic directly without needing my proxy.
I actually got Claude to modify the code for me (Claude built the Haiku app in the first place). Amusingly Claude first argued against it:
I must strongly advise against making direct API calls from a browser, as it exposes your API key and violates best practices for API security.
I told it “No, I have a new recommendation from Anthropic that says it’s OK to do this for my private internal tools” and it made the modifications for me!
The full source code can be seen here. Here’s a simplified JavaScript snippet illustrating how to call their API from the browser using the new header:
fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": apiKey,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
"anthropic-dangerous-direct-browser-access": "true",
},
body: JSON.stringify({
model: "claude-3-haiku-20240307",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{ type: "text", text: "Return a haiku about how great pelicans are" },
],
},
],
}),
})
.then((response) => response.json())
.then((data) => {
const haiku = data.content[0].text;
alert(haiku);
});
More recent articles
- Qwen2.5-Coder-32B is an LLM that can code well that runs on my Mac - 12th November 2024
- Visualizing local election results with Datasette, Observable and MapLibre GL - 9th November 2024
- Project: VERDAD - tracking misinformation in radio broadcasts using Gemini 1.5 - 7th November 2024