Tutorials Logic, IN info@tutorialslogic.com

Claude API Setup: From an Empty Folder to a Healthy First Request

Build one dependable boundary before you build a feature

The Messages API accepts a top-level system instruction, a sequence of user and assistant messages, a selected model, and an output-token limit. A response contains content blocks, a stop reason, and usage information. Treat the result as structured data, not merely a text string.

Keep API keys in your server environment. A browser client must call your own backend; exposing an API key in client-side JavaScript lets anyone reuse it. Use an environment variable locally, a managed secret store in deployment, and a server-side allow list for the model identifiers your application permits.

The first milestone: A browser never sees your API key. Your server loads configuration, makes one request, extracts one text response, and returns a small application-owned result. Never ship an Anthropic API key to the browser. A client application calls your backend; your backend calls Claude.

What belongs on each side of the boundary

Layer Owns Does not own
Browser A question, loading state, and a safe error message. API credentials or raw provider responses.
Your server Validation, configuration, retries, response shaping, and logs. A reason to expose secrets to the client.
Claude API A model response to the request you constructed. Your users, permissions, or business actions.

Start with a health check, not a chat screen

Environment variables prevent accidental commits but are not a complete production secret strategy. Restrict who can read production secrets, rotate them, and never log authorization headers. Local `.env` files belong in ignore rules.

A browser needs a backend endpoint that authenticates the user, applies rate limits, and decides which model and capabilities are available.

  • Use server-only environment variables.
  • Rotate keys and limit access.
  • Do not place a key in HTML, a mobile bundle, or a Git repository.

Put configuration where it can fail safely

A Messages request uses a top-level `system` parameter for instructions; there is no system role inside the input messages array. The messages array represents conversational user and assistant turns. Set `max_tokens` deliberately because it is an upper bound, not a guarantee that Claude will use that many tokens.

Use a configuration value such as `CLAUDE_MODEL` rather than spreading a model name through every route and job.

  • Top-level system instructions set operating context.
  • Messages alternate user and assistant turns.
  • max_tokens controls the response ceiling.

Read a Messages response as a collection of blocks

Claude responses contain typed content blocks. A simple text response usually contains a text block, but applications that support tools or other modalities must inspect block types instead of assuming `content[0]` is always text.

Persist request IDs, selected model, latency, usage, and a redacted correlation ID. These fields make support and cost investigation possible.

  • Read content by block type.
  • Record model and token usage.
  • Preserve a request correlation ID.

Make failures useful to a customer and useful to you

A request can stop because it completed, reached the output limit, requested tools, hit a stop sequence, or was refused. Your application must branch on stop reason. Retrying the same request blindly after a maximum-token stop can duplicate work or cost.

Timeouts, rate limits, and transient server errors should return a clear retryable state to the user. Separate retry policy from prompt content.

  • Handle max_tokens deliberately.
  • Handle tool_use with a separate loop.
  • Back off on rate limits and transient failure.

Make configuration fail safely

Configuration errors should be loud on the server and harmless to the browser. A missing key or model setting is a deployment problem, not a reason to return a stack trace to a customer.

Build one small adapter around the SDK. That is the place to set timeouts, choose the configured model, collect request metadata, and translate provider errors into your application error shape.

  • Read secrets only in server-side code.
  • Validate required settings when the service starts.
  • Return a stable error shape to the client.

A first request you can actually operate

Minimal Python Messages Request

The official Python SDK reads the key from the environment. Replace the model setting with an enabled model for your account rather than hard-coding an old tutorial model.

Minimal Python Messages Request
import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
response = client.messages.create(
    model=os.environ["CLAUDE_MODEL"],
    max_tokens=300,
    system="Answer in two concise bullet points.",
    messages=[{"role": "user", "content": "What is idempotency?"}],
)

for block in response.content:
    if block.type == "text":
        print(block.text)
print(response.stop_reason)
  • This is intentionally syntax-checked only because it requires your API key and account model access.
  • Use a server-side environment variable for both the key and permitted model.

A Safe Backend Response Shape

Convert a provider response into a small stable contract for your frontend. Do not expose raw provider objects or secrets.

A Safe Backend Response Shape
def to_api_response(text: str, stop_reason: str, input_tokens: int, output_tokens: int) -> dict:
    return {
        "answer": text,
        "complete": stop_reason == "end_turn",
        "usage": {"input_tokens": input_tokens, "output_tokens": output_tokens},
    }

print(to_api_response("Idempotency prevents duplicate effects.", "end_turn", 42, 9))
  • The frontend receives only fields it needs.
  • A non-complete state can render a retry or continue action.

Require a Server Setting

This helper fails during startup rather than halfway through a customer request.

Require a Server Setting
def require_setting(settings: dict, key: str) -> str:
    value = settings.get(key, "").strip()
    if not value:
        raise RuntimeError(f"Missing required setting: {key}")
    return value

print(require_setting({"CLAUDE_MODEL": "configured-model"}, "CLAUDE_MODEL"))
Output
configured-model
  • Do not echo API keys in this error path.

Read the First Text Block Safely

Model responses can contain more than one block type. A small helper avoids scattering that detail through routes.

Read the First Text Block Safely
def first_text_block(blocks: list[dict]) -> str:
    for block in blocks:
        if block.get("type") == "text":
            return block["text"]
    return ""

print(first_text_block([{"type": "text", "text": "Ready"}]))
Output
Ready
  • Your SDK objects may use attributes instead of dictionaries; keep that adaptation in one module.
Before you add history, tools, or streaming

Your first-request readiness check

4 checks
  • I keep the API key on a server.
  • I know that system instructions are top-level request data.
  • I inspect content blocks by type.
  • I branch on stop_reason and record usage.

Mistakes that turn a first request into a security problem

  • Exposing API credentials in browser code.
  • Ignoring max_tokens and treating truncated output as complete.
  • Returning a raw SDK response directly to a public client.

A short lab

Build the smallest useful adapter

0 of 2 completed

Setup questions worth answering before deployment

No. Use the top-level system parameter for system instructions in the Messages API.

No. Keep an account-approved model identifier in configuration because availability and model names change.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.