> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bettertoken.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Use the OpenAI and Anthropic SDKs with BetterToken

> Use an OpenAI SDK custom Base URL or Anthropic SDK base_url with BetterToken. Run Python, JavaScript, and curl examples for three text API endpoints.

Use the OpenAI SDK with Base URL `https://bettertoken.ai/v1`, or the Anthropic SDK with `https://bettertoken.ai`. The examples below send a short text request through Chat Completions, Responses, or Messages using your BetterToken API Key.

## Choose an SDK and Base URL

| API | SDK | Base URL | Authentication on the wire | Reference |
| - | - | - | - | - |
| Chat Completions | OpenAI | `https://bettertoken.ai/v1` | `Authorization: Bearer YOUR_API_KEY` | [Chat Completions](/en/api-reference/chat-completions.md) |
| Responses | OpenAI | `https://bettertoken.ai/v1` | `Authorization: Bearer YOUR_API_KEY` | [Responses](/en/api-reference/responses.md) |
| Messages | Anthropic | `https://bettertoken.ai`, without `/v1` | `x-api-key: YOUR_API_KEY` | [Messages](/en/api-reference/messages.md) |

The SDK adds the endpoint path and authentication headers. The Anthropic SDK also sends the API version header. See the [protocol comparison](/en/faq/concepts/openai-compatible-vs-anthropic-compatible.md) if you are adapting existing code.

## Prerequisites

Complete the [quickstart](/en/quickstart.md) to create a BetterToken API Key and add credit. Copy a Model ID from the [model plaza](https://bettertoken.ai/pricing) that is available for the endpoint you plan to call. Replace both placeholders below before running a request.

Set these variables in the terminal where you will run the examples. The shell commands on this page use macOS / Linux syntax:

```bash theme={null}
export BETTERTOKEN_API_KEY="YOUR_API_KEY"
export BETTERTOKEN_MODEL_ID="YOUR_MODEL_ID"
```

For Python, install the SDKs inside your project's virtual environment:

```bash theme={null}
python3 -m venv .venv
source .venv/bin/activate
python -m pip install openai anthropic
```

For JavaScript, install the packages in your project and save each example as a separate `.mjs` file, then run it with `node`:

```bash theme={null}
npm install openai @anthropic-ai/sdk
```

All examples read the Key from `BETTERTOKEN_API_KEY`. They disable SDK retries so one test does not silently become several attempts. For application retry policies, see [errors and limits](/en/api-reference/errors.md#retry-temporary-failures).

## Call Chat Completions

Use `messages` for the input conversation. A successful text response contains `choices[0].message.content`.

**Python**

```python theme={null}
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1",
    timeout=120.0,
    max_retries=0,
)
response = client.chat.completions.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    messages=[{"role": "user", "content": "Reply with one word: OK"}],
)
print(response.choices[0].message.content)
```

**JavaScript**

```javascript theme={null}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.BETTERTOKEN_API_KEY,
  baseURL: "https://bettertoken.ai/v1",
  timeout: 120000,
  maxRetries: 0,
});
const response = await client.chat.completions.create({
  model: process.env.BETTERTOKEN_MODEL_ID,
  messages: [{ role: "user", content: "Reply with one word: OK" }],
});
console.log(response.choices[0].message.content);
```

**curl**

```bash theme={null}
curl --fail-with-body --max-time 120 "https://bettertoken.ai/v1/chat/completions" \
  -H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"$BETTERTOKEN_MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply with one word: OK\"}]}"
```

## Call Responses

Use `input` for the prompt. OpenAI SDKs expose `output_text` as a text convenience property; the HTTP JSON response contains an `output` array. Inspect message items and their text content rather than assuming every output item is text.

**Python**

```python theme={null}
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1",
    timeout=120.0,
    max_retries=0,
)
response = client.responses.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    input="Reply with one word: OK",
)
print(response.output_text)
```

**JavaScript**

```javascript theme={null}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.BETTERTOKEN_API_KEY,
  baseURL: "https://bettertoken.ai/v1",
  timeout: 120000,
  maxRetries: 0,
});
const response = await client.responses.create({
  model: process.env.BETTERTOKEN_MODEL_ID,
  input: "Reply with one word: OK",
});
console.log(response.output_text);
```

**curl**

```bash theme={null}
curl --fail-with-body --max-time 120 "https://bettertoken.ai/v1/responses" \
  -H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"$BETTERTOKEN_MODEL_ID\",\"input\":\"Reply with one word: OK\"}"
```

## Call Messages

Use `messages` and supply `max_tokens`. For this short text request, a successful text response includes a text block such as `content[0].text`. In general, iterate through `content` and read only blocks with `type: "text"`.

**Python**

```python theme={null}
import os
from anthropic import Anthropic

client = Anthropic(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai",
    timeout=120.0,
    max_retries=0,
)
response = client.messages.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    max_tokens=256,
    messages=[{"role": "user", "content": "Reply with one word: OK"}],
)
for block in response.content:
    if block.type == "text":
        print(block.text)
```

**JavaScript**

```javascript theme={null}
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: process.env.BETTERTOKEN_API_KEY,
  baseURL: "https://bettertoken.ai",
  timeout: 120000,
  maxRetries: 0,
});
const response = await client.messages.create({
  model: process.env.BETTERTOKEN_MODEL_ID,
  max_tokens: 256,
  messages: [{ role: "user", content: "Reply with one word: OK" }],
});
for (const block of response.content) {
  if (block.type === "text") console.log(block.text);
}
```

**curl**

```bash theme={null}
curl --fail-with-body --max-time 120 "https://bettertoken.ai/v1/messages" \
  -H "x-api-key: $BETTERTOKEN_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"$BETTERTOKEN_MODEL_ID\",\"max_tokens\":256,\"messages\":[{\"role\":\"user\",\"content\":\"Reply with one word: OK\"}]}"
```

## List available models

Send `GET https://bettertoken.ai/v1/models` with `Authorization: Bearer` or `x-api-key` authentication. A successful response returns HTTP `200` with top-level `data`, `object`, and `success` fields. Each entry in `data` includes `id`, `object`, `created`, `owned_by`, and `supported_endpoint_types`.

**curl**

```bash theme={null}
curl --fail-with-body --max-time 120 "https://bettertoken.ai/v1/models" \
  -H "Authorization: Bearer $BETTERTOKEN_API_KEY"
```

To use `x-api-key`, replace the authentication header with `-H "x-api-key: $BETTERTOKEN_API_KEY"`.

**Python**

```python theme={null}
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1",
    timeout=120.0,
    max_retries=0,
)
for model in client.models.list():
    print(model.id)
```

Use a returned `id` as the `model` in your request. Do not require `type` or `display_name`; these fields are not present on every entry. Rely on `id` for model selection, and use the [model plaza](https://bettertoken.ai/pricing) for current prices and full model descriptions.

## Common errors

| Symptom | Check and fix |
| - | - |
| Wrong URL or `404` | OpenAI SDK Base URL includes `/v1`; Anthropic SDK Base URL does not. Do not append the final route to an SDK Base URL. |
| `401` or missing credential | The examples pass the Key explicitly from `BETTERTOKEN_API_KEY`. Direct OpenAI requests use Bearer; direct Messages requests use `x-api-key`. |
| Model not found | Replace `YOUR_MODEL_ID` with an exact, available Model ID from the model plaza. Check it for the selected endpoint. |
| Requests reach an old endpoint | Inspect SDK arguments and inherited variables; see [clear conflicting environment variables](/en/best-practices.md#clear-conflicting-environment-variables). |
| Empty text or an incomplete answer | Inspect the full response and stop reason; check [output token limits](/en/faq/model-calling/max-tokens.md). |

### Can I reuse one Key for both SDKs?

Yes. One BetterToken API Key works with all available models. Use the Base URL and request format for each SDK.

### Can I add streaming, tools, or structured output?

Streaming and tool calling support varies by model. Test a small request with your Model ID first; follow [streaming and tool calling](/en/guides/streaming-and-tool-calling.md). For JSON validation and model-dependent structured output, see the [structured JSON FAQ](/en/faq/model-calling/structured-json-pydantic.md).

## Related

* [API reference overview](/en/api-reference/introduction.md)
* [Supported tools](/en/ai-tools/overview.md)
* [Errors, status codes, and rate limits](/en/api-reference/errors.md)
* [API Key security and timeouts](/en/best-practices.md)
* [Cache billing rules](/en/faq/service-assurance/cache-billing.md)

## Official references

* [OpenAI Python SDK](https://github.com/openai/openai-python)
* [OpenAI JavaScript SDK](https://github.com/openai/openai-node)
* [Anthropic Python SDK](https://github.com/anthropics/anthropic-sdk-python)
* [Anthropic JavaScript SDK](https://github.com/anthropics/anthropic-sdk-typescript)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.