Module 3 of 7 · 54 min

Build Reliable Claude API Workflows

Integrate the Claude Messages API with environment-based credentials, explicit request contracts, state ownership, validation, observability, and bounded recovery.

Anthropic

By the end

You will be able to

  • Explain the Messages API request, response, content-block, and conversation-state contracts.
  • Use official SDKs with environment-based credentials and configurable model identifiers.
  • Validate outputs and handle stop reasons, rate limits, timeouts, and uncertain outcomes explicitly.
  • Record safe operational evidence without logging secrets or sensitive prompt content.
01

Messages are structured and application-managed

A Messages API request identifies a model, output budget, prior user and assistant turns, and optional system instructions, tools, or other controls. Responses contain typed content blocks, usage, and a stop reason. Do not assume that every response is one prose string.

The application owns conversational state. For a continued exchange, preserve the required prior turns and send them again according to the current API contract. Define retention, truncation, summarization, privacy, and deletion behavior as application policies rather than accidental side effects.

02

Keep credentials and volatile choices in configuration

Load the API key from the runtime environment or a managed secret store. Fail closed when it is unavailable, keep it out of prompts and logs, scope access to the workload, and use an operational process for rotation and revocation.

Treat model identifiers, output budgets, timeouts, retry policy, and region or deployment choices as reviewed configuration. Verify currently supported values from official documentation and avoid baking an unverified model name into reusable learning code.

Secret-safe SDK request boundary
typescript
import Anthropic from "@anthropic-ai/sdk";

const model = process.env.ANTHROPIC_MODEL;
if (!process.env.ANTHROPIC_API_KEY || !model) {
  throw new Error("Claude API configuration is incomplete");
}

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const response = await client.messages.create({
  model,
  max_tokens: 800,
  system: "Return a concise, evidence-linked risk summary.",
  messages: [{ role: "user", content: approvedInput }],
});

switch (response.stop_reason) {
  case "end_turn":
    await handleValidatedAnswer(response.content);
    break;
  case "tool_use":
    await handleAuthorizedToolRequests(response.content);
    break;
  default:
    throw new Error(`Unhandled stop reason: ${response.stop_reason}`);
}
03

Validate the response contract

Inspect content-block types and stop reasons before consuming output. A normal end turn, output-budget stop, tool request, refusal, pause, and transport failure imply different next actions. Never concatenate unknown blocks into trusted application data.

Validate required fields, allowed values, lengths, citations, and business rules at the application boundary. When downstream code needs structured intent, use an explicit structured interface and schema rather than recovering a decision from free-form prose.

04

Recover with bounds and reconciliation

Classify failures before retrying. A transient availability or rate-limit response may be retried with provider guidance, jitter, a maximum attempt count, and an end-to-end deadline. Authentication, authorization, malformed requests, and validation failures require correction rather than unchanged retry.

A timed-out read-only request can often be retried safely. A timeout surrounding an external side effect has an unknown outcome until the system of record is reconciled. Use idempotency or operation identifiers in your own workflow and verify postconditions before repeating an action.

05

Observe the workflow without leaking data

Record a request or trace identifier, application and prompt version, configured model reference, latency, usage, stop reason, retry count, validation result, and final workflow state. These fields support evaluation, cost analysis, incident response, and rollback decisions.

Do not log API keys, authorization headers, raw secrets, or unrestricted prompt and response bodies. Use data classification, redaction, access control, retention limits, and sampled or derived metrics appropriate to the workload.

Practice activity

Design a production-shaped Claude API client

  1. Define a request contract with configurable model reference, output budget, system instruction, messages, timeout, and trace identifier; load credentials only from an environment or managed secret boundary.
  2. Define handlers for text and non-text content blocks plus end-turn, output-budget, tool-use, refusal or pause, rate-limit, authentication, validation, timeout, and server-failure outcomes.
  3. Create deterministic tests with synthetic responses for a successful answer, truncated output, malformed block, retryable failure, non-retryable failure, and uncertain side-effect outcome.
  4. Write a telemetry allowlist and redaction policy, then demonstrate one trace that proves behavior without exposing prompt content or credentials.

What to produce

  • A secret-free client design or implementation with typed request and response handling, bounded retries, reconciliation, and deterministic tests.
  • A telemetry example and policy showing request correlation, versions, latency, usage, stop reason, validation, retry, and terminal state without sensitive values.

Reflect before continuing

Which failure in your client requires reconciliation rather than retry, and what evidence proves the real outcome?

Evidence

Sources and verification

Knowledge check

Make it stick.

Pass at 80%

Choose the strongest answer for each question. Your attempts become part of your device-local transcript.

01Who owns multi-turn conversation state for a Messages API workflow?
02Where should a reusable application obtain its model identifier?
03What should happen when the response has an unhandled stop reason?
04Which failure should not be retried unchanged?
05Which telemetry set is safest and most useful by default?