# A Raw HTTP Call: What the SDK Does for You — Claude API / OpenAI API Basics

Source: https://www.geekswithgeeks.com/en/llm-apis/b-raw

> Make the request by hand once to understand it.

## It is just HTTP and JSON

Any language that can send HTTPS and parse JSON can call these APIs. Doing it once by hand removes the mystery: build the JSON body, add the headers (an API key header, a content type, and for Anthropic an `anthropic-version` header), send a `POST`, check the **status code** and parse the JSON. **SDKs** add real value on top: typed request and response objects, automatic **retries with backoff**, **timeouts**, **streaming** helpers, error classes and pagination. Use the SDK in applications; use raw HTTP for debugging, unusual languages or when you need exact control.

## A raw call with urllib, run

I ran this in a Python virtual environment with the anthropic 1.11.0 and openai 3.22.1 SDKs against a small local stand-in server (shown in the testing topic, saved as `mock.py`). The server returns canned replies, so no key, network or real model is involved: it proves how the SDK builds requests and handles replies, not what a real model would say. The code sends a Messages-style request with `urllib` only, to the local stand-in server. It prints the status, the text, the usage and what the server actually received: the key header and the three required body fields.

```python
import json, urllib.request, mock
srv = mock.start(); base = f"http://127.0.0.1:{srv.server_address[1]}"

req = urllib.request.Request(base + "/v1/messages", method="POST",
    data=json.dumps({"model": "demo-model", "max_tokens": 100,
                     "messages": [{"role": "user", "content": "Capital of France?"}]}).encode(),
    headers={"x-api-key": "sk-test-123", "anthropic-version": "2023-06-01", "content-type": "application/json"})
with urllib.request.urlopen(req) as r:
    reply = json.load(r)
print("status OK, stop_reason:", reply["stop_reason"])
print("text:", reply["content"][0]["text"])
print("usage:", reply["usage"])
seen = mock.STATE["log"][-1]
print("server saw header x-api-key:", seen["headers"]["x-api-key"])
print("server saw body keys:", sorted(seen["body"]))

```

Output:

```
status OK, stop_reason: end_turn
text: Paris is the capital of France.
usage: {'input_tokens': 14, 'output_tokens': 8}
server saw header x-api-key: sk-test-123
server saw body keys: ['max_tokens', 'messages', 'model']
```

**Quiz:** What do SDKs add on top of raw HTTP?

- [ ] No need for a key
- [ ] A different model
- [ ] Free tokens
- [x] Typed objects, retries, timeouts and streaming helpers

*Answer:* Typed objects, retries, timeouts and streaming helpers. SDKs wrap the same HTTP API with convenience and reliability features.
