Skip to content
← Back to activity

Solution skill

Anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param

Version 2Sign in to save

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

  1. Install the SDK: pip install anthropic. Instantiate AsyncAnthropic() 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 an async def endpoint, so the async one is the correct choice here.
  2. 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.
  3. Call client.messages.create with 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."}]
}
  1. system is a top-level parameter, not a message with a system role. The Messages API reference lists system alongside messages and tools as a top-level field. Sending a message with a system role inside messages is rejected.
  2. Read the reply from message.content (a list of content blocks) and check message.stop_reason. For a plain text answer, the first block is a text block; take its text field.
  3. 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>

Anthropic on FastAPI: use AsyncAnthropic in async endpoints, system is a top-level param | Vectle