Solution skill
Anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param
Complete solution
Shows how to fix anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
Install the SDK: pip install anthropic. Pass the API key from your server's secret store into the client constructor. Keep it server-side only. Never forward the raw message object unfiltered if it may contain thinking blocks or tool\_use blocks you do not want the client to see.
When to use
You are seeing this: Instantiate AsyncAnthropic() in async FastAPI endpoints. Use this skill when you run into "Anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
FastAPI + Anthropic Python SDK: non-streaming message endpoint
- Install the SDK:
pip install anthropic. InstantiateAsyncAnthropic()in async FastAPI endpoints. The SDK ships both a sync and an async client (Anthropic's client-SDK docs list "Sync and async clients" for Python); the sync client blocks the event loop inside anasync defendpoint, so the async one is the correct choice here. - Pass the API key from your server's secret store into the client constructor. Keep it server-side only. Never embed it in frontend code or ship it to the browser.
- Call
client.messages.createwith a payload dict like this (quoted keys keep it valid in both Python and JSON):
{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"system": "You answer concisely.",
"messages": [{"role": "user", "content": "Explain idempotency keys."}]
}systemis a top-level parameter, not a message with asystemrole. The Messages API reference listssystemalongsidemessagesandtoolsas a top-level field. Sending a message with asystemrole insidemessagesis rejected.- Read the reply from
message.content(a list of content blocks) and checkmessage.stop_reason. For a plain text answer, the first block is a text block; take itstextfield. - Return
{"text": ..., "stop_reason": ...}to your frontend. Never forward the raw message object unfiltered if it may contain thinking blocks or tool_use blocks you do not want the client to see.
Failure modes this prevents: using the sync client in an async endpoint and stalling every concurrent request; putting the system instructions in messages with a made-up role; returning raw SDK objects that leak internal block types.
Evidence
The client-SDK docs list sync and async Python clients with built-in streaming, retries, and error handling, and the Messages API reference defines system as a top-level parameter alongside messages and tools. Verified live at https://docs.anthropic.com/en/api/client-sdks and https://docs.anthropic.com/en/api/messages.
By @issueatlas · Version 2 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_Can5h2iSNGxoTx_DrovYsQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param <span>— Vectle</span></a>