Docs
Guides

Chat completions

Send messages to Tase models and read the response: roles, system prompts, parameters, multi-turn conversations, and token usage.

The chat completions endpoint is the core of the Tase API. You send a list of messages, the model reads them in order, and it returns the next assistant message. Everything else in the platform — streaming, tool calling, structured outputs — is a variation of this one request.

OpenAI-compatible

The Tase API follows the OpenAI chat completions wire format. Any OpenAI SDK works out of the box — point it at https://api.tase.app/v1 and authenticate with your Tase API key.

Your first request

Send a POST request to https://api.tase.app/v1/chat/completions with your API key in the Authorization header. Only two fields are required: model and messages.

curl https://api.tase.app/v1/chat/completions \
  -H "Authorization: Bearer tase_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tase-8b",
    "messages": [
      { "role": "system", "content": "You are a concise assistant." },
      { "role": "user", "content": "What makes a good morning routine?" }
    ]
  }'

The response is a single JSON object. The reply lives inside the first choice, and the usage object reports exactly what the request cost in tokens.

{
  "id": "chatcmpl-9f3a1c",
  "object": "chat.completion",
  "model": "tase-8b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Water first, ten minutes of movement, then a written plan for the day."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 27,
    "completion_tokens": 18,
    "total_tokens": 45
  }
}

Read the reply from choices[0].message.content. The finish_reason field tells you why generation ended: stop means the model finished naturally, length means it hit your max_tokens limit and the reply may be cut off mid-sentence.

Message roles

  • system — instructions that frame the whole conversation: persona, tone, rules, output format. Put it first in the array.
  • user — what the person (or your application) is asking.
  • assistant — earlier model replies. You send these back yourself to give the model conversational context.
  • tool — the result of a tool call the model requested, used together with the tools parameter.

Writing a good system message

The system message is the highest-leverage text in the request. State who the model is, what it must do, and what the output should look like — in that order. Constraints written here hold across every turn of the conversation, so anything you find yourself repeating in user messages belongs in the system message instead.

One clear directive sentence beats three vague paragraphs. "Answer in two sentences or fewer, no bullet points" is a better system message than a long description of the assistant's personality.

Using the OpenAI SDKs

Because the API is OpenAI-compatible, the official OpenAI SDKs work unchanged — set baseURL to the Tase endpoint and pass your Tase key.

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.TASE_API_KEY, // tase_sk_...
  baseURL: 'https://api.tase.app/v1',
});

const completion = await client.chat.completions.create({
  model: 'tase-8b',
  messages: [
    { role: 'system', content: 'You are a concise assistant.' },
    { role: 'user', content: 'What makes a good morning routine?' },
  ],
  temperature: 0.7,
  max_tokens: 256,
});

console.log(completion.choices[0].message.content);
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TASE_API_KEY"],  # tase_sk_...
    base_url="https://api.tase.app/v1",
)

completion = client.chat.completions.create(
    model="tase-8b",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "What makes a good morning routine?"},
    ],
    temperature=0.7,
    max_tokens=256,
)

print(completion.choices[0].message.content)

Parameters that shape the response

  • temperature — controls randomness. Low values make output focused and repeatable; higher values make it more varied. Use low temperatures for extraction and code, higher ones for brainstorming and creative writing.
  • max_tokens — a hard cap on how many tokens the model may generate. When the cap is hit, finish_reason comes back as length. Set it explicitly whenever you need to bound cost or latency.
  • stream — deliver the reply token by token instead of all at once. Covered in the streaming guide.
  • tools and tool_choice — let the model call functions you define.
  • response_format — force the reply to be valid JSON. Covered in the structured outputs guide.

Picking a temperature

Start at 0 to 0.3 for anything you will parse programmatically, around 0.7 for conversational replies, and above 1.0 only when you explicitly want variety across runs.

Multi-turn conversations

The API is stateless: it has no memory of previous requests. To build a conversation, keep the message history on your side and send the entire array — system message, every user turn, every assistant reply — with each new request. The model then answers with full context.

const history = [
  { role: 'system', content: 'You are a helpful planning assistant.' },
];

async function send(userText) {
  history.push({ role: 'user', content: userText });

  const completion = await client.chat.completions.create({
    model: 'tase-8b',
    messages: history,
  });

  const reply = completion.choices[0].message;
  history.push({ role: 'assistant', content: reply.content });
  return reply.content;
}

await send('Plan a three-step evening routine.');
await send('Make step two shorter.'); // the model sees the full history

History grows, and so does cost

Every turn you resend counts toward prompt_tokens. For long-running conversations, trim the oldest turns or replace them with a short summary once the history gets large.

Reading token usage

Every response includes a usage object: prompt_tokens (everything you sent), completion_tokens (everything the model generated), and total_tokens (the sum). Log these in production — they are the ground truth for cost tracking and for catching runaway histories early.

const { prompt_tokens, completion_tokens, total_tokens } = completion.usage;

console.log('prompt:', prompt_tokens);
console.log('completion:', completion_tokens);
console.log('total:', total_tokens);
Does the API remember my previous messages?+

No. Every request is independent. Conversation memory is your responsibility: store the message history and resend it with each request.

What happens if I omit max_tokens?+

The model generates until it reaches a natural stopping point or runs out of context. Set max_tokens explicitly whenever you need predictable cost or latency.

Which model name do I use?+

Use tase-8b. It is the general-purpose Tase model and the default choice for chat, extraction, and tool calling.

Next: stream responses token by token

Cut perceived latency to near zero by rendering the reply as it is generated.

Read the streaming guide