01

Make your first call

This is the Chat Completions API. Any OpenAI-compatible client works: change the base URL and the key and keep everything else.

Base URL
https://api.tiyuvta.ai/v1
Auth
Authorization: Bearer <your key>
Model
qwen/qwen3.8-27b
shell
curl https://api.tiyuvta.ai/v1/chat/completions \
  -H "Authorization: Bearer $TIYUVTA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen/qwen3.8-27b",
    "messages": [{"role": "user", "content": "Say hello."}]
  }'

No key yet? Sign in with an email address. The first 100 accounts receive $10 of credit, with no card required. GET https://api.tiyuvta.ai/v1/models is the authoritative roster; the model page lists what is live and what is in bring-up.

02

Stream tokens

Usage is reported in the stream, so spend can be metered without a second request.

node
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.tiyuvta.ai/v1",
  apiKey: process.env.TIYUVTA_KEY,
});

const stream = await client.chat.completions.create({
  model: "qwen/qwen3.8-27b",
  messages: [{ role: "user", content: "Write a haiku about caches." }],
  stream: true,
  stream_options: { include_usage: true },
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  if (chunk.usage) console.error(chunk.usage);
}
03

Call tools

Function calling is constrained during decoding, so the model cannot emit a call that violates the schema you sent.

python
r = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{"role": "user", "content": "What is the weather in Haifa?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        },
    }],
    tool_choice="auto",
)
print(r.choices[0].message.tool_calls)
04

Force a JSON shape

response_format takes JSON mode or a JSON schema. A strict schema is enforced token by token rather than checked afterwards.

python
r = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{"role": "user", "content": "Extract the invoice fields."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "invoice",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "total": {"type": "number"},
                    "currency": {"type": "string"},
                },
                "required": ["total", "currency"],
                "additionalProperties": False,
            },
        },
    },
)
05

Send an image

Images go in the same message as text, as image_url content parts — a URL or a data URL. They are billed as input tokens at $0.38 per million, the same rate as text input, and the reply is text.

python
r = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What does this chart show?"},
            {"type": "image_url", "image_url": {
                "url": "https://example.com/chart.png",
            }},
        ],
    }],
)
print(r.choices[0].message.content)
# A data URL works too: data:image/png;base64,<...>
06

Pay less on long chats

When a request continues a conversation the endpoint already served, the shared prefix is read from cache: cheaper and much faster to first token. Nothing to enable.

python
# Turn 1 — the model reads 5,700 tokens of context.
messages = [system, big_context, {"role": "user", "content": "Summarise."}]
first = client.chat.completions.create(model=MODEL, messages=messages)

# Turn 2 — same prefix, one turn longer. The shared prefix is a cache hit,
# billed at $0.12 per million instead of $0.38.
messages += [first.choices[0].message, {"role": "user", "content": "Now list risks."}]
second = client.chat.completions.create(model=MODEL, messages=messages)

print(second.usage.prompt_tokens_details.cached_tokens)
the honest caveat A cached prefix is reused when a request continues a previous one — the same conversation, one turn later. Fan-out over one shared document with different questions does not hit the cache on this model architecture. For one document with many different questions, budget full input price on each request.

Two practical consequences: append to a conversation rather than rebuilding it, and keep the system prompt stable at the front where it can be reused.

07

Read what you were billed

Every response carries exact counts. Input tokens are split so you can see the cached share you paid $0.12 for instead of $0.38.

json
"usage": {
  "prompt_tokens": 5821,
  "prompt_tokens_details": { "cached_tokens": 5690 },
  "completion_tokens": 412,
  "total_tokens": 6233
}

The same figures, per day and per key, are in your console under Usage. Bodies of prompts and completions are not stored to produce them.

08

Errors

Status Meaning What to do
401 Key missing, malformed or revoked. Check the header, then the key list in your console.
402 Prepaid balance cannot cover the request. Top up, then retry. Nothing was charged and nothing was generated.
422 The request body is not one we can serve — unknown model, bad schema, prompt over the window. The message names the field. It will not be silently truncated.
429 Rate limit, or capacity shed instead of queued. Back off and retry. Requests are refused quickly rather than held open.
5xx Our fault. Retry with backoff. If it persists, mail hello@tiyuvta.ai with the time window.
402 body
{
  "error": {
    "message": "tenant prepaid balance is insufficient for this request",
    "type": "insufficient_balance",
    "code": "insufficient_balance"
  }
}
09

Rate limits

How they work
Rate limits are per account and exist for abuse control. We scale capacity with demand, so there is no published ceiling to design around.
Trial credit
Runs at a lower rate than purchased credit.
Need more
Mail hello@tiyuvta.ai with the shape of your traffic and we raise them.
When you hit one
429, refused quickly rather than queued. Back off and retry; nothing was charged.
10

Move from another provider

Two lines change. There is no proprietary SDK and no request translation layer.

diff
- base_url="https://api.openai.com/v1"
- model="gpt-4o-mini"
+ base_url="https://api.tiyuvta.ai/v1"
+ model="qwen/qwen3.8-27b"

Things to check when you switch: this model thinks by default, so budget output tokens for reasoning or lower reasoning_effort, and the context window is 262,144 tokens shared between input and output.

11

Keys and security

  • A key is shown once, at creation. We store only its prefix, so we cannot email it back to you.
  • Create as many as you like and revoke any of them immediately; revocation takes effect on the next request.
  • Keys are account-wide. Usage is reported per key so you can tell which service spent what.
  • Never put a key in a browser or a mobile app. Proxy it from your own server.
  • If a key leaks, revoke it first, then contact us.