# SDK 101: what happens when you call the method?

You have a small application and want it to ask a model for a draft. You can write
an HTTP request yourself, or install a library that prepares the request for you.
That library is a **client SDK**, short for software development kit. Think of it
like a database driver: useful code in your application that knows how to talk to
a service. Installing the driver does not install the database. Installing a
model-provider client SDK does not install the model.

This original 45-minute lab uses the real Anthropic TypeScript SDK from JavaScript.
It sends actual HTTP requests to a tiny server on your own computer. The server
returns authored examples, not model output. You will see the request, a retry,
an error and a timeout before introducing an agent framework.

## 1. Name the pieces before using them

| Piece | What it is | Where it is in this lab |
| --- | --- | --- |
| Your application | The code deciding what work to request and what result to accept | The `run` and `decide` functions |
| Client SDK | An installed library that prepares requests and handles responses | `@anthropic-ai/sdk` |
| API | The service's agreed request and response contract | A small local imitation of the Messages HTTP contract |
| Endpoint | The address receiving a request | A temporary port on `127.0.0.1`, the loopback address |
| Model | A trained system that performs inference | Absent; the server returns fixed fictional text |
| Agent loop | Application control that can choose and repeat steps using results | Absent; each case requests one operation |

An SDK is not a language. The TypeScript SDK also runs in server-side JavaScript,
as this exercise shows. An API is not necessarily an SDK: you can call an HTTP API
with `fetch`. A client SDK typically saves you from hand-writing parts of that
integration. An **Agent SDK** is a different abstraction that may supply a tool
loop and runtime. The similarly named products do not do the same job.

In a real hosted-model integration, the endpoint normally belongs to the provider
or an approved gateway. Here the destination is deliberately local so you can
inspect transport behavior without a provider account or bill.

## 2. Prepare the small local experiment

Download **fde-sdk-request-lab.mjs** into a new, empty folder. Open a terminal in
that folder with Node.js 24 installed. Install the exact version tested for this
workbook, then run the checks and cases:

```sh
node --version
npm init -y
npm install --ignore-scripts --save-exact @anthropic-ai/sdk@0.131.0
node fde-sdk-request-lab.mjs test
node fde-sdk-request-lab.mjs demo
```

Installation needs registry access. After installation, the exercise uses only
loopback HTTP. The program opens a temporary local port for each case and closes
it afterward. It accepts no destination argument, refuses other endpoints and
redirects, and explicitly supplies a useless lab placeholder instead of reading
your provider credentials. Do not add a real key or change it to a hosted endpoint.

Version `0.131.0` is the reproducible lab baseline, not a claim to be the latest
release. The official SDK documentation linked below is the place to check current
versions and supported configuration. This lab adds no cloud resource or model.

## 3. Compare raw HTTP with the SDK method

First run only these two cases:

```sh
node fde-sdk-request-lab.mjs raw-http
node fde-sdk-request-lab.mjs sdk
```

Both should record one `POST` to `/v1/messages`, with the same `model`,
`max_tokens`, `messages` and API version. Compare the `requests` arrays. The model
identifier `local-fixture-not-a-model` is a marker for this exercise, not a usable
provider model name.

Open the code. The raw path builds headers, serializes the body and parses the
HTTP response. The SDK path calls `client.messages.create(body)`. The SDK handles
that transport work, but an HTTP request still crosses the boundary. The selected
fields match; the lab does not claim every SDK-added header is identical.

The text “Authored reply: forms are at reception” comes from the `reply` object in
this file. The usage numbers there are fictional fixture values, not measured token
counts or billing. Neither the SDK call nor its response proves a model ran.

## 4. Observe retries, errors and missing responses

Predict the attempt count and application decision before running each case:

| Case | Local server behavior | Expected observation | Application decision |
| --- | --- | --- | --- |
| `retry` | First 503, then 200 | 2 HTTP attempts with `maxRetries: 1` | `review-draft` |
| `bad-request` | 400 | 1 attempt; `BadRequestError` with status 400 | `inspect-error` |
| `timeout` | Receives the request but does not answer | 1 attempt; `APIConnectionTimeoutError`, no HTTP status | `outcome-unknown` |
| `unexpected-body` | 200 with valid JSON in the wrong shape | 1 attempt; parsed object fails the application's check | `inspect-response` |

```sh
node fde-sdk-request-lab.mjs retry
node fde-sdk-request-lab.mjs bad-request
node fde-sdk-request-lab.mjs timeout
node fde-sdk-request-lab.mjs unexpected-body
```

A retry is an additional attempt, so one retry can mean two requests. This lab's
first 503 does no model work. That does not establish how a real provider handles a
lost response or duplicate operation. Do not infer free retries or exactly-once
effects from this local example.

The timeout case waits 500 milliseconds with retries disabled. The server's
request record proves receipt in this experiment, even though the client gets no
response. In production, a client timeout alone cannot tell you whether remote
work started or finished. Record that uncertainty and use the service's documented
status, reconciliation or idempotency mechanism where one exists.

An HTTP 200 means the server returned a successful status, not that your user has
a usable answer. This SDK baseline parses the unexpected JSON without enforcing
our application's acceptance rule. The separate `decide` function requires a
normally finished nonempty text response. It is a deliberately narrow check, not
a full provider schema validator, factual review or tool-execution loop.

## 5. Change the policy and predict the consequence

Make a separate copy before changing the file. Restore the original between these
two experiments:

1. Set `RETRY_LIMIT` from `1` to `0`, then run `retry`. Expect one attempt, a 503
   error and `inspect-error`. The server's second response is never reached. What
   did the client policy change, and what did it leave unchanged?
2. In the authored `reply`, change `stop_reason` from `end_turn` to `max_tokens`,
   then run `sdk`. The server still returns 200, but `decide` should withhold the
   text and choose `inspect-response`. Explain why transport success and normal
   completion are different observations.

The `test` command checks the original baseline and the retry-limit experiment;
changing the normal-completion fixture intentionally invalidates the baseline's
accepted-draft expectation. Keep that failed expectation as evidence, then restore
the original file.

Write one small integration card: the installed client version, endpoint owner,
request route, retry limit, timeout, accepted response shape and an explicit action
for unknown outcomes. Record no real keys or private prompts. Ask a partner to
point to the line that crosses HTTP and the line that accepts the response.

## 6. Connect this to agent and cloud engineering

A LangChain agent can call a provider adapter; LangGraph can coordinate a workflow;
an MCP client can exchange protocol messages with a tool server. None removes the
need to understand each connection's request, errors and authority. An SDK retry
is transport behavior, not evidence of an agent planning another step.

The [cloud response lab](/training/guides/cloud-responses) compares selected GCP,
AWS and Azure response contracts. Those services have distinct identifiers,
authentication and SDKs. Do not replace only a base URL and assume this Anthropic
Messages example becomes a universal cloud adapter.

With Academy access, continue to the [SDK lesson](/app/academy?course=agent-engineering&lesson=sdk-first-request&view=focus),
then the first LangChain agent. Keep the integration card beside the workflow
diagram so a framework name never hides where data goes.

## 7. Check the primary references

Checked 21 October 2026. This workbook, local fixture and teaching code are
original LockedIn Labs material. The exercise demonstrates the installed client
against its local fixture; it does not certify a production integration.

- [Anthropic: client SDKs, CLI and higher-level agent tooling](https://platform.claude.com/docs/en/cli-sdks-libraries/overview)
- [Anthropic: TypeScript client documentation](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/typescript)
- [Anthropic: Messages API reference](https://platform.claude.com/docs/en/api/typescript/messages/create)
- [Node.js: HTTP server behavior](https://nodejs.org/api/http.html)
