Your Prompt Worked in Chat. Why Is the LLM API Different?
A chat prompt moved into code goes flat, forgets and fails with 400s. Send the history, write the system prompt, set effort and a schema, and read the stop reason first.
Key takeaways
- An LLM API is stateless, so every request must carry the whole conversation, and you pay for that history on every turn.
- Over the API your system prompt does the job the chat app's hidden prompt used to do.
- Effort, structured outputs and prompt caching replace instructions people used to write as prose.
- Set effort explicitly: Opus 5.5 and Haiku 5.5 default to medium, most other models to high.
- Read the stop reason on every response before the answer; a refusal arrives with HTTP 200.
- temperature, top_p, top_k, budget_tokens and assistant prefill return HTTP 400 on current Claude models.
Contents
FAQ
Why does the model forget earlier messages over the API?
The API keeps no memory between calls. Your code has to send the full message history on every request.
Should I set effort explicitly?
Yes. Default effort differs between models, so an upgrade can silently change how deeply your app reasons unless you set it.
Sources
Only you and the owner see your answer and rating. Send private feedback
Enjoyed it? Support fx-blog with a coffee.
Related posts
Your LLM Proxy Retries the Wrong Errors
What an LLM proxy has to decide on every failure: limits are per organization, which statuses to retry, why nothing is retried after the first streamed byte, and the headroom headers the API already sends.
Your LLM Demo Works. What Every Call Needs in Production
One timestamp in the system prompt and every call misses the cache. Pricing each call, making failures loud, logging per feature, and treating outside text as untrusted.
RAG That Works: Why Retrieval Matters More Than the Prompt
Most bad RAG answers are retrieval problems. How RAG works end to end, the three parts of the grounded prompt, how to measure retrieval alone, and when long context is enough.
Comments
Oldest firstNo comments yet. Start the conversation.
You paste the prompt that worked in the chat app into
client.messages.create. The answer comes back flat and oddly formatted. Your follow-up gets a reply with no idea what you asked a minute ago. Then you copy a snippet from an older tutorial and get HTTP 400 fortemperature.None of that is a bug. The chat app was doing that work for you, and over the API it is yours.
This series, in six parts:
One feature runs through all six: a test-case generator that turns a requirement into test cases. Here it is a single call. Not covered: fine-tuning, and a parameter-by-parameter reference (the guide's Claude API page has that).
The API remembers nothing
Every request carries the whole conversation. If your code did not send an earlier turn, the model never saw it.
The system prompt is yours now
In the chat app, the vendor wrote a large hidden system prompt: tone, safety, formatting. Over the API you get a nearly raw model, which is why the same prompt reads flat. I'd spend more time on the
systemfield than on the user message. It does the job a rules file does for an IDE agent.Here is the test-case generator's first call:
The answer is a list of typed blocks, not a string. Check
block.typebefore you read.text.Settings replaced the prose
Three things people try to get with words are settings now:
low,medium,high,xhigh,maxWith a schema, the generator hands back a
TestCaseyour code can store. No regex:Read the stop reason before the answer
A response that stopped early still looks like a response.
stop_reasontells you which kind you got.stop_reasonend_turnmax_tokensmax_tokens, or streamtool_userefusalstop_details.categoryA refusal arrives with status 200, so your error handling never sees it. Only this field does.
Try it
The test-case generator now writes one case per call, but it cannot run a test, so it cannot check its own work against the orders suite. For that it needs a tool, and a loop around the tool. Part 2, Build the Agent Loop Yourself, writes that loop by hand.
Read this with your AI