> 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/api-reference/completions.md).

# Chat Completions

`POST /v1/chat/completions`

You give me a conversation, I hand it to a model, and I return the model's reply. My requests and responses follow the OpenAI Chat Completions API shape exactly.

***

## What you send me

```
POST https://api.theacompute.com/v1/chat/completions
Authorization: Bearer thea_live_your_key_here
Content-Type: application/json
```

### The request body I accept

| Field               | Type            | Required | What it does                                                                                            |
| ------------------- | --------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `model`             | string          | Yes      | The ID of the model you want me to run. Browse them in \[my models]\().                                 |
| `messages`          | array           | Yes      | Your conversation up to now, as an ordered array of message objects.                                    |
| `stream`            | boolean         | No       | Set it to `true` and I stream SSE chunks to you as tokens come out. I default to `false`.               |
| `max_tokens`        | integer         | No       | The most tokens I'll generate.                                                                          |
| `temperature`       | number          | No       | The sampling temperature, anywhere from 0.0 to 2.0.                                                     |
| `top_p`             | number          | No       | The cutoff I use for nucleus sampling.                                                                  |
| `stop`              | string or array | No       | One or more sequences that make me stop generating as soon as they appear.                              |
| `frequency_penalty` | number          | No       | I penalize tokens based on how often they've already shown up (-2.0 to 2.0).                            |
| `presence_penalty`  | number          | No       | I penalize any token that has shown up even once (-2.0 to 2.0).                                         |
| `seed`              | integer         | No       | Asks me for reproducible sampling. I do my best, but inference is distributed, so I can't guarantee it. |

### The message object

```json
{
  "role": "user",
  "content": "Explain how Robinhood Chain achieves 100ms block times."
}
```

I accept these roles: `system`, `user`, `assistant`.

### A sample request

```json
{
  "model": "qwen3-8b",
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant. Keep answers concise."
    },
    {
      "role": "user",
      "content": "What is an ERC-4337 smart account?"
    }
  ],
  "stream": false,
  "max_tokens": 512,
  "temperature": 0.7
}
```

***

## What I send back (non-streaming)

```json
{
  "id": "chatcmpl-job_8fx2kp3m...",
  "object": "chat.completion",
  "created": 1750000000,
  "model": "qwen3-8b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "An ERC-4337 smart account is a smart contract wallet that can sponsor gas, batch transactions, and support social recovery..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 48,
    "completion_tokens": 214,
    "total_tokens": 262
  }
}
```

### Headers I attach (non-streaming)

```
x-theacompute-job-id: job_8fx2kp3m9qrstvwxyz
x-theacompute-tx-hash: 0x8c2f41ab9e07d3565f18c4ba20d97e631a5c08f2be49d176e0a3b58c917d24f0
x-theacompute-settlement-tx: 0x3a91d5c07f26e8b4915dc3a08e67f21b49c0d8a35e7612fb08d94ce5a172b36d
x-theacompute-worker: 0x9d24ab7e315f68c0d1b2fa4c8e0973d65a1cbe48
x-theacompute-credits-remaining: 1412
```

Here's what each header tells you:

* `x-theacompute-job-id`: the ID I gave your job
* `x-theacompute-tx-hash`: the escrow lock transaction
* `x-theacompute-settlement-tx`: the settlement transaction, where I release payment
* `x-theacompute-worker`: the address of the worker that ran your job
* `x-theacompute-credits-remaining`: how many units you have left (my API calls units credits)

***

## Streaming my reply

When you set `stream: true`, I answer with Server-Sent Events in the OpenAI chunk format. In each event I include a `delta` object with the content that was just generated.

```
data: {"id":"chatcmpl-job_8fx2kp3m...","object":"chat.completion.chunk","created":1750000000,"model":"qwen3-8b","choices":[{"index":0,"delta":{"role":"assistant","content":"A "},"finish_reason":null}]}

data: {"id":"chatcmpl-job_8fx2kp3m...","object":"chat.completion.chunk","created":1750000000,"model":"qwen3-8b","choices":[{"index":0,"delta":{"content":"Program "},"finish_reason":null}]}

data: {"id":"chatcmpl-job_8fx2kp3m...","object":"chat.completion.chunk","created":1750000000,"model":"qwen3-8b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
```

I put `finish_reason` on the final chunk before `[DONE]`. Once the stream closes, grab the `x-theacompute-settlement-tx` header from the response object. That's your settlement receipt.

### Try streaming

```bash
curl https://api.theacompute.com/v1/chat/completions \
  -H "Authorization: Bearer thea_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3.3-70b",
    "messages": [{"role": "user", "content": "Write a haiku about Robinhood Chain."}],
    "stream": true
  }'
```

***

## How I charge units

The moment your request reaches me, I move your units into escrow. The worker only gets them after the job settles on-chain.

| Charge point      | Timing                                                                             |
| ----------------- | ---------------------------------------------------------------------------------- |
| Escrow lock       | As soon as your request arrives, before I route it anywhere                        |
| Escrow release    | After the proof-of-completion clears on-chain verification                         |
| Unit deduction    | Once I confirm settlement                                                          |
| Refund on failure | I refund you automatically if 120 seconds go by and no worker has finished the job |

Once a completion runs past roughly 500 output tokens, I bill it per 1,000 output tokens instead of at the flat rate. I lock an estimate in escrow up front, and if fewer tokens get generated than I estimated, I return the difference to your balance.

***

## When something goes wrong

| Status | Code                   | What it means                                                                                     |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------- |
| `400`  | `invalid_request`      | I couldn't parse your body, or it's missing a required field                                      |
| `400`  | `model_not_found`      | I don't have a model with the ID you asked for                                                    |
| `402`  | `insufficient_credits` | You don't have enough units for this model's tier                                                 |
| `503`  | `no_workers_available` | No worker is hosting this model for me right now. I include `retry_after` in seconds.             |
| `504`  | `job_timeout`          | My 120-second window ran out before any worker finished. I've returned the escrowed units to you. |

You'll find my full error envelope in \[my errors reference]\(

).


---

# 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/api-reference/completions.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.
