# Python and TypeScript clients

OpenAI-compatible SDKs can connect to SimpleLLM by setting the base URL and API key. The examples below use Chat Completions, not the Responses API.

## Install and configure

~~~bash
# Python, preferably inside a virtual environment:
python -m pip install openai

# JavaScript / TypeScript, inside your application:
npm install openai
~~~

~~~bash
export SIMPLELLM_API_KEY='YOUR_API_KEY'
export SIMPLELLM_MODEL='qwen3.8-flash-next'
~~~

The model above was present in the public catalogue on 2026-09-14. Check [Models & pricing](/docs/models.html) before running the example; paid-model calls consume credits.

Use these examples on your backend or in a terminal, not in a publicly delivered browser bundle.

## Non-streaming response

Save the Python version as `chat.py` and run `python chat.py`. Save the JavaScript version as `chat.mjs` and run `node chat.mjs`; the same client calls work inside a TypeScript project.

~~~python
import os
from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://api.simplellm.eu/v1",
    api_key=os.environ["SIMPLELLM_API_KEY"],
    max_retries=0,
    timeout=600.0,
)
try:
    response = client.chat.completions.create(
        model=os.environ["SIMPLELLM_MODEL"],
        messages=[{"role": "user", "content": "Explain a hash table briefly."}],
        max_tokens=2048,
    )
    print(response.choices[0].message.content or "")
    print("Usage:", response.usage)
except APIStatusError as error:
    print("Request failed with HTTP", error.status_code)
    raise
finally:
    client.close()
~~~

~~~javascript
import OpenAI from "openai";

if (!process.env.SIMPLELLM_API_KEY || !process.env.SIMPLELLM_MODEL) {
  throw new Error("Set SIMPLELLM_API_KEY and SIMPLELLM_MODEL");
}
const client = new OpenAI({
  baseURL: "https://api.simplellm.eu/v1",
  apiKey: process.env.SIMPLELLM_API_KEY,
  maxRetries: 0,
  timeout: 600_000,
});
try {
  const response = await client.chat.completions.create({
    model: process.env.SIMPLELLM_MODEL,
    messages: [{ role: "user", content: "Explain a hash table briefly." }],
    max_tokens: 2048,
  });
  console.log(response.choices[0]?.message.content ?? "");
  console.log("Usage:", response.usage);
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    console.error("Request failed with HTTP", error.status);
  }
  throw error;
}
~~~

The example disables automatic SDK retries so one invocation does not silently become several inference attempts. Choose your application's retry policy using the [retry guide](/docs/limits.html).

## Stream with JavaScript

This is a complete Node.js example. Ctrl+C aborts the stream; an application can connect its Stop button to the same abort handler.

~~~javascript
import OpenAI from "openai";

if (!process.env.SIMPLELLM_API_KEY || !process.env.SIMPLELLM_MODEL) {
  throw new Error("Set SIMPLELLM_API_KEY and SIMPLELLM_MODEL");
}
const client = new OpenAI({
  baseURL: "https://api.simplellm.eu/v1",
  apiKey: process.env.SIMPLELLM_API_KEY,
  maxRetries: 0,
  timeout: 600_000,
});
const stream = await client.chat.completions.create({
  model: process.env.SIMPLELLM_MODEL,
  messages: [{ role: "user", content: "Explain streaming responses." }],
  max_tokens: 2048,
  stream: true,
  stream_options: { include_usage: true },
});
const stop = () => stream.controller.abort();
process.once("SIGINT", stop);
try {
  for await (const chunk of stream) {
    for (const choice of chunk.choices) {
      process.stdout.write(choice.delta.content ?? "");
    }
    if (chunk.usage) console.log("\nUsage:", chunk.usage);
  }
} finally {
  process.removeListener("SIGINT", stop);
  stream.controller.abort();
}
~~~

For Python streaming with cleanup, see the complete example in [Streaming & cancellation](/docs/streaming.html).

## Common migration mistakes

- Python uses `base_url`; JavaScript uses `baseURL`.
- Include `/v1` once in the SDK base URL.
- Use a SimpleLLM model ID, not an ID copied from another provider.
- Do not enable browser-side secret exposure to work around an SDK warning.
- SDK types may contain endpoints or options that SimpleLLM V1 does not implement.

See [Compatibility](/docs/compatibility.html) for supported endpoints and [Go & Rust](/docs/go-rust.html) for direct HTTP clients.
