# Your First Call With Each SDK — Claude API / OpenAI API Basics

Source: https://www.geekswithgeeks.com/en/llm-apis/m-first

> Make a basic request and read the reply, stop reason and usage.

## Create, read, check

With an SDK a basic call is a few lines. Create a client (it reads the key from the environment unless you pass one), call the create method with a **model**, the **messages** and limits, then read the reply from the response object. Always also read the **stop reason** (did the model finish, hit your token limit, or ask to use a tool?) and the **usage** numbers (for cost tracking). The model name is a string such as `<model-name>`: take current names from the provider's documentation, store them in configuration and expect them to change as models are released and retired.

## Shape the conversation and the reply

Roles, history, a system prompt and a few parameters control what the model sees and how it answers.

![Four controls: roles, history, parameters, format.](assets/figures/llm-apis/section-2-map.svg) — Figure 2.1 — Roles, history, parameters and format.

## Anthropic Messages call, 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 SDK sends the key as `x-api-key` with an `anthropic-version` header to `/v1/messages`, and the response object exposes the text, the stop reason (`end_turn`) and the token usage (14 in, 8 out).

```python
import mock, anthropic, openai
srv = mock.start(); base = f"http://127.0.0.1:{srv.server_address[1]}"      # local stand-in server, not a real API

client = anthropic.Anthropic(api_key="sk-test-123", base_url=base)
msg = client.messages.create(model="demo-model", max_tokens=100,
                             messages=[{"role": "user", "content": "Capital of France?"}])
print(msg.content[0].text)
print(msg.stop_reason, msg.usage.input_tokens, msg.usage.output_tokens)
sent = mock.STATE["log"][-1]
print("SDK sent:", sent["headers"]["x-api-key"], sent["headers"]["anthropic-version"], sent["path"])

```

Output:

```
Paris is the capital of France.
end_turn 14 8
SDK sent: sk-test-123 2023-06-01 /v1/messages
```

## OpenAI Chat Completions call, 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 OpenAI SDK sends `Authorization: Bearer ...` to `/v1/chat/completions`. The reply is in `choices[0].message.content`, the finish reason is `stop`, and usage reports prompt, completion and total tokens.

```python
import mock, anthropic, openai
srv = mock.start(); base = f"http://127.0.0.1:{srv.server_address[1]}"      # local stand-in server, not a real API

client = openai.OpenAI(api_key="sk-test-456", base_url=base + "/v1")
resp = client.chat.completions.create(model="demo-model",
                                      messages=[{"role": "user", "content": "Capital of France?"}])
print(resp.choices[0].message.content)
print(resp.choices[0].finish_reason, resp.usage.prompt_tokens, resp.usage.completion_tokens, resp.usage.total_tokens)
sent = mock.STATE["log"][-1]
print("SDK sent:", sent["headers"]["authorization"], sent["path"])

```

Output:

```
Paris is the capital of France.
stop 14 8 22
SDK sent: Bearer sk-test-456 /v1/chat/completions
```

## Pin the SDK version

SDKs change quickly. Pin the version in your lockfile and read release notes before upgrading.

**Quiz:** Why read the stop reason as well as the text?

- [ ] It contains the API key
- [x] It tells you if the answer was cut off or a tool was requested
- [ ] It is the model name
- [ ] It is decorative

*Answer:* It tells you if the answer was cut off or a tool was requested. A truncated or tool-requesting response must be handled differently from a finished one.
