> For the complete documentation index, see [llms.txt](https://docs.theacompute.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.theacompute.com/integrations/openai-compatible.md).

# OpenAI-Compatible Usage

Swap one line and keep the rest of your code. I speak the OpenAI wire protocol (the same request bodies go in, the same response bodies come out), so anything you wrote against the OpenAI SDK, in any language, comes over to me with a new base URL and a new API key. That's two config values and nothing more.

***

## What I support

| Feature                                 | Do I support it?                           |
| --------------------------------------- | ------------------------------------------ |
| `POST /v1/chat/completions`             | Yes, and I stream it too                   |
| `GET /v1/models`                        | Yes, and I add my own `theacompute` fields |
| Streaming (SSE)                         | Yes                                        |
| `max_tokens`, `temperature`, `top_p`    | Yes                                        |
| `stop` sequences                        | Yes                                        |
| `frequency_penalty`, `presence_penalty` | Yes                                        |
| System prompts and multi-turn chats     | Yes                                        |
| Tool / function calling                 | On my Phase 2 plan                         |
| Embeddings (`/v1/embeddings`)           | On my Phase 2 plan                         |
| Image inputs (`vision`)                 | On my Phase 2 plan                         |
| Assistants API                          | No                                         |
| Fine-tuning API                         | No                                         |

***

## Calling me from Python (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.theacompute.com/v1",
    api_key="thea_live_your_key_here"
)

# One answer, all at once
response = client.chat.completions.create(
    model="qwen3-8b",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "What is llama.cpp?"}
    ]
)
print(response.choices[0].message.content)

# Or let me stream it to you
stream = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Explain zero-knowledge proofs."}],
    stream=True
)

for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)
```

***

## Calling me from TypeScript / Node.js (OpenAI SDK)

```typescript
import OpenAI from "openai"

const client = new OpenAI({
    baseURL: "https://api.theacompute.com/v1",
    apiKey: "thea_live_your_key_here"
})

// One answer, all at once
const response = await client.chat.completions.create({
    model: "qwen3-8b",
    messages: [
        { role: "system", content: "You are a concise assistant." },
        { role: "user", content: "What is llama.cpp?" }
    ]
})
console.log(response.choices[0].message.content)

// Or let me stream it to you
const stream = await client.chat.completions.create({
    model: "llama-3.3-70b",
    messages: [{ role: "user", content: "Explain zero-knowledge proofs." }],
    stream: true
})

for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content ?? "")
}
```

***

## Keep your key out of your code

You make API keys in Settings. Each one starts with `thea_live_`, and I show it to you only once, so copy it somewhere safe. Then put it in an environment variable, please. Your source files are for code, not secrets.

```bash
export THEACOMPUTE_API_KEY="thea_live_your_key_here"
```

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.theacompute.com/v1",
    api_key=os.environ["THEACOMPUTE_API_KEY"]
)
```

```typescript
const client = new OpenAI({
    baseURL: "https://api.theacompute.com/v1",
    apiKey: process.env.THEACOMPUTE_API_KEY!
})
```

***

## Reading my on-chain receipts

I attach headers to every response that point at the job's on-chain transactions: `x-theacompute-tx-hash` is the escrow lock, and `x-theacompute-settlement-tx` is the settlement that releases payment. Together they're your proof the job ran and settled. The OpenAI SDK throws headers away, so if you want the transaction hashes, make the HTTP call yourself and look at the raw response.

```python
import httpx

response = httpx.post(
    "https://api.theacompute.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "qwen3-8b",
        "messages": [{"role": "user", "content": "Hello"}]
    }
)

job_id = response.headers.get("x-theacompute-job-id")
settlement_tx = response.headers.get("x-theacompute-settlement-tx")
print(f"Job: {job_id}")
print(f"Settlement tx: https://robinhoodchain.blockscout.com/tx/{settlement_tx}")
```

Rather have typed receipts, structured streaming, or wallet-native auth? Grab \[my JavaScript SDK]\(

) or read \[my Python guide]\().

***

## Choosing one of my models

I name my own models, so none of OpenAI's IDs work with me. Call `GET /v1/models` and I'll hand you my live catalog. Trust that endpoint over this table. Here's roughly how things line up:

| OpenAI model    | My closest match | Notes                                   |
| --------------- | ---------------- | --------------------------------------- |
| `gpt-4o`        | `llama-3.3-70b`  | Good at reasoning across the board      |
| `gpt-4o-mini`   | `qwen3-8b`       | Fast, cheap, and fine for most jobs     |
| `gpt-3.5-turbo` | `mistral-7b`     | My cheapest and fastest pick            |
| none            | `deepseek-r1`    | Made for long reasoning, math, and code |

***

## Where I behave differently from OpenAI

**You prepay, I don't invoice.** I never send you a monthly bill. You load units up front (1 USDG gets you 100 units) from Settings with **Add more units**, and each call spends some of them. My API calls units "credits", so that's the word you'll see in field and header names. When the balance hits zero, the calls stop. You can check my prices before you spend, not after.

**I put on-chain receipt headers on every response.** I stamp each completion with `x-theacompute-job-id`, `x-theacompute-tx-hash` (the escrow lock transaction), and `x-theacompute-settlement-tx` (the settlement transaction), so you can open both on Blockscout. OpenAI responses don't include anything like that.

**I price by capacity, not rate limits.** I don't do quota tiers, and nobody gets to decide how much inference you deserve. If I run out of workers for your model, I send back a `503` with a `retry_after` value. That's my entire policy: if your client behaves itself, it never sits in a queue or gets throttled.

**My community decides what gets retired.** I keep model IDs stable. To retire one, the TheaCompute community has to vote it off the recommended list, and I announce that vote ahead of time. The ID keeps working until the vote passes, not until some two-week warning window runs out.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.theacompute.com/integrations/openai-compatible.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
