{"id":518,"date":"2026-08-11T09:00:00","date_gmt":"2026-08-11T00:00:00","guid":{"rendered":"https:\/\/www.theagenticprotocol.com\/?p=518"},"modified":"2026-08-11T08:34:27","modified_gmt":"2026-08-10T23:34:27","slug":"claude-api-python","status":"publish","type":"post","link":"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/","title":{"rendered":"Claude API Python Tutorial: Complete Guide 2026"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Claude API Python tutorial most developers need in 2026 is shorter than you&#8217;d expect \u2014 your first working API call is 10 lines of code. The part that takes longer is understanding the response object, getting system prompts right, handling the streaming correctly, and avoiding the three parameter changes in Claude Sonnet 5 that silently break code written for Sonnet 4.x.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58-1024x576.jpg\" alt=\"claude api python tutorial complete guide 2026\" class=\"wp-image-519\" srcset=\"https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58-1024x576.jpg 1024w, https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58-300x169.jpg 300w, https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58-768x432.jpg 768w, https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58-1536x864.jpg 1536w, https:\/\/www.theagenticprotocol.com\/wp-content\/uploads\/2026\/08\/grok-image-04d4534a-1cf8-46ea-9824-c70ad12eff58.jpg 1792w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers all of it. By the end you&#8217;ll have working code for every major Claude API pattern: basic calls, multi-turn conversations, streaming, tool use, and production error handling with cost tracking. Everything runs against <code>claude-sonnet-5<\/code> \u2014 the current production default at $2 per million input tokens through August 31, 2026.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Setup_API_Key_and_SDK_in_2_Minutes\" >Setup: API Key and SDK in 2 Minutes<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Step_1_%E2%80%94_Get_your_API_key\" >Step 1 \u2014 Get your API key<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Step_2_%E2%80%94_Install_the_SDK\" >Step 2 \u2014 Install the SDK<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Step_3_%E2%80%94_Store_the_key_safely\" >Step 3 \u2014 Store the key safely<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Your_First_Claude_API_Python_Call\" >Your First Claude API Python Call<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Reading_the_response_object_correctly\" >Reading the response object correctly<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#System_Prompts_The_Most_Important_Parameter\" >System Prompts: The Most Important Parameter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Multi-Turn_Conversations\" >Multi-Turn Conversations<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Streaming_Token-by-Token_Output\" >Streaming: Token-by-Token Output<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#The_Three_Sonnet_5_Breaking_Changes_From_Sonnet_4x\" >The Three Sonnet 5 Breaking Changes From Sonnet 4.x<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Production_Error_Handling_and_Cost_Tracking\" >Production Error Handling and Cost Tracking<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#The_Builders_Takeaway\" >The Builder&#8217;s Takeaway<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/#Continue_in_This_Series\" >Continue in This Series<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Setup_API_Key_and_SDK_in_2_Minutes\"><\/span>Setup: API Key and SDK in 2 Minutes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_1_%E2%80%94_Get_your_API_key\"><\/span>Step 1 \u2014 Get your API key<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Go to <a href=\"https:\/\/console.anthropic.com\" target=\"_blank\" rel=\"noopener\">console.anthropic.com<\/a>, create an account, and generate an API key under API Keys. New accounts include free credits. Copy the key once \u2014 the console doesn&#8217;t show it again.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_2_%E2%80%94_Install_the_SDK\"><\/span>Step 2 \u2014 Install the SDK<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install anthropic python-dotenv<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_3_%E2%80%94_Store_the_key_safely\"><\/span>Step 3 \u2014 Store the key safely<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># .env file in your project root \u2014 never commit this to git\nANTHROPIC_API_KEY=sk-ant-your-key-here<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># .gitignore\n.env<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Your_First_Claude_API_Python_Call\"><\/span>Your First Claude API Python Call<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport anthropic\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nclient = anthropic.Anthropic(api_key=os.environ.get(\"ANTHROPIC_API_KEY\"))\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=1024,\n    messages=&#91;\n        {\"role\": \"user\", \"content\": \"Explain what an API is in two sentences.\"}\n    ]\n)\n\nprint(message.content&#91;0].text)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run this and you&#8217;ll see Claude&#8217;s response in your terminal. That&#8217;s the complete minimal Claude API Python call. Now let&#8217;s understand what came back.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Reading_the_response_object_correctly\"><\/span>Reading the response object correctly<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>print(message.model)               # \"claude-sonnet-5\"\nprint(message.stop_reason)         # \"end_turn\" = completed normally\nprint(message.usage.input_tokens)  # tokens you sent (= your cost)\nprint(message.usage.output_tokens) # tokens in the response (= your cost)\nprint(message.content&#91;0].text)     # the actual response text\nprint(message.content&#91;0].type)     # \"text\" for standard responses<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Two fields matter most: <code>stop_reason<\/code> tells you why Claude stopped \u2014 <code>end_turn<\/code> means it finished normally, <code>max_tokens<\/code> means it was cut off and you need a higher limit. <code>usage<\/code> is how you track costs \u2014 essential before you put anything into production.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"System_Prompts_The_Most_Important_Parameter\"><\/span>System Prompts: The Most Important Parameter<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A system prompt sets Claude&#8217;s role, constraints, and output format for the entire conversation. It&#8217;s the highest-leverage single parameter in any Claude API Python integration \u2014 the difference between a generic response and a response that matches your product exactly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>message = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=1024,\n    system=\"\"\"You are a senior Python engineer doing code review.\nWhen reviewing code:\n- Start with a one-line verdict: APPROVE, REQUEST_CHANGES, or NEEDS_DISCUSSION\n- List specific issues with line numbers\n- End with the single highest-priority fix\nKeep your review under 200 words.\"\"\",\n    messages=&#91;\n        {\"role\": \"user\", \"content\": \"Review this code:\\n\\ndef get_user(id):\\n    return db.query(f'SELECT * FROM users WHERE id={id}')\"}\n    ]\n)\n\nprint(message.content&#91;0].text)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Three system prompt patterns that consistently produce better Claude API responses:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Define a role with context:<\/strong> &#8220;You are a [role] with [specific expertise]&#8221; gives Claude a consistent perspective to respond from.<\/li>\n\n\n\n<li><strong>Specify the output format:<\/strong> Telling Claude exactly what structure you expect (bullet points, JSON, numbered steps) makes the output far easier to parse.<\/li>\n\n\n\n<li><strong>Set explicit constraints:<\/strong> Word limits, what to include, what to exclude. Claude follows precise constraints reliably.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Multi-Turn_Conversations\"><\/span>Multi-Turn Conversations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Claude doesn&#8217;t have memory between API calls. To maintain a conversation, you pass the full history with every request. The SDK doesn&#8217;t manage this for you \u2014 you build the list yourself.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport anthropic\nfrom dotenv import load_dotenv\n\nload_dotenv()\nclient = anthropic.Anthropic(api_key=os.environ.get(\"ANTHROPIC_API_KEY\"))\n\ndef chat():\n    \"\"\"A simple multi-turn CLI chatbot using the Claude API.\"\"\"\n    history = &#91;]\n    print(\"Claude \u2014 type 'quit' to exit\\n\")\n\n    while True:\n        user_input = input(\"You: \").strip()\n        if user_input.lower() in (\"quit\", \"exit\", \"q\"):\n            break\n        if not user_input:\n            continue\n\n        # Add user message to history\n        history.append({\"role\": \"user\", \"content\": user_input})\n\n        response = client.messages.create(\n            model=\"claude-sonnet-5\",\n            max_tokens=1024,\n            system=\"You are a helpful assistant. Be concise.\",\n            messages=history\n        )\n\n        assistant_text = response.content&#91;0].text\n\n        # Add Claude's response to history for the next turn\n        history.append({\"role\": \"assistant\", \"content\": assistant_text})\n\n        print(f\"Claude: {assistant_text}\\n\")\n\n        # Track token usage per turn\n        print(f\"&#91;Tokens: in={response.usage.input_tokens} out={response.usage.output_tokens}]\")\n\nif __name__ == \"__main__\":\n    chat()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The pattern is always the same: append the user message, make the API call, append Claude&#8217;s response to the same list, repeat. The context grows with each turn \u2014 which is why token tracking per turn matters. A 10-turn conversation with 500 tokens per response is using 5,000 output tokens before you&#8217;ve done anything interesting.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Streaming_Token-by-Token_Output\"><\/span>Streaming: Token-by-Token Output<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Streaming makes long responses feel fast by printing each token as it&#8217;s generated rather than waiting for the full response. For any user-facing application with responses longer than a sentence, streaming is the default choice.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport anthropic\nfrom dotenv import load_dotenv\n\nload_dotenv()\nclient = anthropic.Anthropic(api_key=os.environ.get(\"ANTHROPIC_API_KEY\"))\n\ndef stream_response(prompt: str) -&gt; str:\n    \"\"\"Stream Claude's response token by token, return the full text.\"\"\"\n    full_response = \"\"\n\n    with client.messages.stream(\n        model=\"claude-sonnet-5\",\n        max_tokens=2048,\n        messages=&#91;{\"role\": \"user\", \"content\": prompt}]\n    ) as stream:\n        for text in stream.text_stream:\n            print(text, end=\"\", flush=True)\n            full_response += text\n\n    print()  # newline after streaming completes\n    return full_response\n\n\n# Usage\nresult = stream_response(\n    \"Write a step-by-step explanation of how HTTPS works.\"\n)\nprint(f\"\\n&#91;Total characters: {len(result)}]\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>stream.text_stream<\/code> iterator yields only the text tokens, automatically filtering out thinking blocks if extended thinking is active. For non-streaming use cases (batch processing, background jobs), omit the stream context manager and use <code>client.messages.create()<\/code> as shown earlier.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Three_Sonnet_5_Breaking_Changes_From_Sonnet_4x\"><\/span>The Three Sonnet 5 Breaking Changes From Sonnet 4.x<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;ve used the Claude API with Sonnet 4.6 or earlier and are migrating to Sonnet 5, three parameter changes produce silent failures or 400 errors:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Do not pass <code>temperature<\/code>.<\/strong> Sonnet 5 uses an effort-level system instead of temperature. Passing <code>temperature<\/code> to a Sonnet 5 call returns a 400 error. Remove it entirely or replace it with the effort toggle (see below).<\/li>\n\n\n\n<li><strong>Effort toggle, not temperature:<\/strong> To control reasoning intensity, pass the thinking parameter with a budget: <code>thinking={\"type\": \"enabled\", \"budget_tokens\": 5000}<\/code> for extended reasoning. For most tasks, omit this entirely \u2014 the default reasoning level is appropriate.<\/li>\n\n\n\n<li><strong>Model string:<\/strong> Use <code>claude-sonnet-5<\/code>. The <code>claude-sonnet-4-6<\/code> string still works for that model \u2014 but if you&#8217;re migrating, the strings are not interchangeable aliases.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code># WRONG \u2014 returns 400 error with claude-sonnet-5\nresponse = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=1024,\n    temperature=0.7,  # \u2190 causes 400 error\n    messages=&#91;{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\n# CORRECT \u2014 omit temperature entirely\nresponse = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=1024,\n    messages=&#91;{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\n# CORRECT \u2014 use thinking param for high-reasoning tasks\nresponse = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=8000,\n    thinking={\"type\": \"enabled\", \"budget_tokens\": 5000},\n    messages=&#91;{\"role\": \"user\", \"content\": \"Solve this step by step: ...\"}]\n)<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Production_Error_Handling_and_Cost_Tracking\"><\/span>Production Error Handling and Cost Tracking<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Two additions that every Claude API Python integration needs before it sees production traffic: structured error handling and per-call cost tracking.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport anthropic\nfrom dotenv import load_dotenv\nfrom dataclasses import dataclass\n\nload_dotenv()\nclient = anthropic.Anthropic(api_key=os.environ.get(\"ANTHROPIC_API_KEY\"))\n\n# Sonnet 5 pricing (introductory, valid through August 31, 2026)\nPRICE_INPUT_PER_MTK = 2.0   # $2.00 per million input tokens\nPRICE_OUTPUT_PER_MTK = 10.0  # $10.00 per million output tokens\n\n@dataclass\nclass APIResult:\n    text: str\n    input_tokens: int\n    output_tokens: int\n    cost_usd: float\n    stop_reason: str\n\n\ndef call_claude(\n    prompt: str,\n    system: str = \"\",\n    max_tokens: int = 1024\n) -&gt; APIResult | None:\n    \"\"\"\n    Call Claude API with full error handling and cost tracking.\n    Returns None on failure \u2014 always check the return value.\n    \"\"\"\n    try:\n        kwargs = {\n            \"model\": \"claude-sonnet-5\",\n            \"max_tokens\": max_tokens,\n            \"messages\": &#91;{\"role\": \"user\", \"content\": prompt}]\n        }\n        if system:\n            kwargs&#91;\"system\"] = system\n\n        response = client.messages.create(**kwargs)\n\n        # Extract text safely\n        text = \"\"\n        for block in response.content:\n            if hasattr(block, \"text\"):\n                text += block.text\n\n        # Calculate cost\n        input_cost = (response.usage.input_tokens \/ 1_000_000) * PRICE_INPUT_PER_MTK\n        output_cost = (response.usage.output_tokens \/ 1_000_000) * PRICE_OUTPUT_PER_MTK\n        total_cost = input_cost + output_cost\n\n        return APIResult(\n            text=text,\n            input_tokens=response.usage.input_tokens,\n            output_tokens=response.usage.output_tokens,\n            cost_usd=total_cost,\n            stop_reason=response.stop_reason\n        )\n\n    except anthropic.AuthenticationError:\n        print(\"ERROR: Invalid API key. Check your ANTHROPIC_API_KEY.\")\n        return None\n\n    except anthropic.RateLimitError:\n        print(\"ERROR: Rate limit exceeded. Add retry logic or reduce request rate.\")\n        return None\n\n    except anthropic.APIStatusError as e:\n        print(f\"ERROR: API error {e.status_code}: {e.message}\")\n        return None\n\n    except Exception as e:\n        print(f\"ERROR: Unexpected error: {e}\")\n        return None\n\n\n# Usage\nresult = call_claude(\n    prompt=\"What are the top 3 Python best practices for API integrations?\",\n    system=\"You are a senior Python developer. Be specific and concise.\"\n)\n\nif result:\n    print(result.text)\n    print(f\"\\n--- Usage ---\")\n    print(f\"Tokens: {result.input_tokens} in \/ {result.output_tokens} out\")\n    print(f\"Cost: ${result.cost_usd:.6f}\")\n    print(f\"Stop reason: {result.stop_reason}\")\nelse:\n    print(\"Call failed \u2014 check the error above.\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>APIResult<\/code> dataclass makes it easy to log costs to a database, aggregate them per user or per session, and alert when a single call exceeds a cost threshold. Running this in production without cost tracking is how teams discover they&#8217;ve spent $200 on a single batch job.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the complete Claude API reference, authentication options, and SDK changelog, see <a href=\"https:\/\/docs.anthropic.com\/en\/api\/getting-started\" target=\"_blank\" rel=\"noopener\">Anthropic&#8217;s official API documentation<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Builders_Takeaway\"><\/span>The Builder&#8217;s Takeaway<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Claude API Python integration pattern is: install the SDK, initialize the client with your key, build a messages list, call <code>client.messages.create()<\/code>, and read <code>response.content[0].text<\/code>. Everything else \u2014 system prompts, multi-turn history, streaming, error handling, cost tracking \u2014 layers onto that foundation. The three Sonnet 5 breaking changes (no temperature, effort toggle, new model string) are the only migration friction from 4.x. Once past those, Sonnet 5&#8217;s 1M context window, adaptive reasoning, and introductory pricing make it the right default for almost any Python application adding Claude in 2026. The next step after this guide is adding tool use \u2014 which turns the Claude API from a text generator into an agent that can take actions in your codebase and beyond.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Continue_in_This_Series\"><\/span>Continue in This Series<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/how-to-build-ai-agent-python\/\">How to Build an AI Agent With Python<\/a> \u2014 the next step: add tools, memory, and a loop to what you built here<\/li>\n\n\n\n<li><a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/langgraph-vs-crewai\/\">LangGraph vs CrewAI<\/a> \u2014 when you&#8217;re ready for a framework above the raw API calls<\/li>\n\n\n\n<li><a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/sonnet-5-migration\/\">Sonnet 5 Migration<\/a> \u2014 the complete breaking change list from Sonnet 4.6 to Sonnet 5<\/li>\n\n\n\n<li><a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/model-fallback-routing\/\">Model Fallback Routing<\/a> \u2014 never hardcode <code>claude-sonnet-5<\/code>: the multi-provider fallback chain for production<\/li>\n\n\n\n<li><a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/how-to-deploy-ai-agents\/\">How to Deploy AI Agents<\/a> \u2014 the complete production checklist once your Claude API integration is working<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>This post is part of The Agentic Protocol&#8217;s Work series \u2014 the connective infrastructure layer beneath every autonomous pipeline. See also: <a href=\"https:\/\/www.theagenticprotocol.com\/index.php\/how-to-build-ai-agent-python\/\">How to Build an AI Agent With Python<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Claude API Python tutorial most developers need in 2026 is shorter than you&#8217;d expect \u2014 your first working API call is 10 lines of code. The part that takes longer is understanding the response object, getting system prompts right, handling the streaming correctly, and avoiding the three parameter changes in Claude Sonnet 5 that &#8230; <a title=\"Claude API Python Tutorial: Complete Guide 2026\" class=\"read-more\" href=\"https:\/\/www.theagenticprotocol.com\/index.php\/claude-api-python\/\" aria-label=\"Read more about Claude API Python Tutorial: Complete Guide 2026\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":519,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[643,642,644,645,646],"class_list":["post-518","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-work-agentic-ai","tag-anthropic-python-sdk","tag-claude-api-python","tag-claude-api-tutorial-2026","tag-claude-python-example","tag-claude-sonnet-5-api"],"_links":{"self":[{"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/posts\/518","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/comments?post=518"}],"version-history":[{"count":1,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/posts\/518\/revisions"}],"predecessor-version":[{"id":520,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/posts\/518\/revisions\/520"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/media\/519"}],"wp:attachment":[{"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/media?parent=518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/categories?post=518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.theagenticprotocol.com\/index.php\/wp-json\/wp\/v2\/tags?post=518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}