Tenzro Labs
Tutorial 01 · Model API

Call a model with the API

Call a Tenzro Labs model from your code in a few minutes. The model API is OpenAI-compatible, so the OpenAI SDKs work as they are.
Step 01

Create a Platform API key

Sign in to the Platform with your Tenzro Labs account and open the API keys page. Create a key with the inference permission. The secret starts with tzl_ and is shown once; the Platform stores only a hash.

shell
export TENZRO_API_KEY="tzl_..."
Step 02

Choose a model by id

GET /v1/models lists every model that can be called right now, with its endpoint and the machines serving it. It needs no key.

shell
curl https://api.tenzro.xyz/v1/models
response
{
  "object": "list",
  "default_machine": "tenzro-partner-cluster",
  "data": [
    {
      "id": "qwen3.5-4b",
      "object": "model",
      "owned_by": "tenzro-labs",
      "name": "Qwen 3.5 4B",
      "modality": "text",
      "endpoint": "/v1/chat/completions",
      "context_length": 131072,
      "max_output_tokens": 2048,
      "features": ["tools"],
      "machines": [{ "id": "tenzro-partner-cluster", "name": "Tenzro Partner Cluster", "region": "Europe" }]
    }
  ]
}

Language models have endpoint set to /v1/chat/completions. Use the id as the model field in every request.

Step 03

Send a chat completion with curl

The request and response follow the OpenAI chat completions format.

shell
curl https://api.tenzro.xyz/v1/chat/completions \
  -H "Authorization: Bearer $TENZRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.5-4b",
    "messages": [{"role": "user", "content": "Write a haiku about GPUs"}]
  }'
model
string
Required. A language model id.
messages
array
Required. OpenAI chat messages: role and content.
stream
boolean
Stream the reply as it is generated.
max_tokens
integer
Longest reply, capped at the model's max_output_tokens.
temperature, top_p, stop, seed
As in the OpenAI API.
tools, tool_choice
Function calling, for models with the tools feature.
enable_thinking
boolean
Reasoning models only: think before answering. Off by default.
machine
string
Optional. Defaults to tenzro-partner-cluster.
Step 04

Use the OpenAI Python SDK

Point the OpenAI client at the Tenzro Labs base URL and pass your Platform key.

shell
pip install openai
python
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.tenzro.xyz/v1", api_key=os.environ["TENZRO_API_KEY"])

reply = client.chat.completions.create(
    model="qwen3.5-4b",
    messages=[{"role": "user", "content": "Hello"}],
)
print(reply.choices[0].message.content)
Step 05

Use the OpenAI JavaScript SDK

shell
npm install openai
javascript · chat.mjs
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.tenzro.xyz/v1", apiKey: process.env.TENZRO_API_KEY });

const reply = await client.chat.completions.create({
  model: "qwen3.5-4b",
  messages: [{ role: "user", content: "Hello" }],
});
console.log(reply.choices[0].message.content);
shell
node chat.mjs
Step 06

Choose where it runs

machine is optional. Without it, the request runs on tenzro-partner-cluster. The machine ids for a model are in its machines list from GET /v1/models.

shell
curl https://api.tenzro.xyz/v1/chat/completions \
  -H "Authorization: Bearer $TENZRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.5-4b",
    "machine": "tenzro-partner-cluster",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Python

The OpenAI SDK sends fields it does not know through extra_body.

python
reply = client.chat.completions.create(
    model="qwen3.5-4b",
    messages=[{"role": "user", "content": "Hello"}],
    extra_body={"machine": "tenzro-partner-cluster"},
)

JavaScript

javascript
const reply = await client.chat.completions.create({
  model: "qwen3.5-4b",
  machine: "tenzro-partner-cluster",
  messages: [{ role: "user", content: "Hello" }],
});
Step 07

Stream the reply

Set stream to true. Chunks arrive as OpenAI server-sent events, and the last chunk carries the token usage.

python
stream = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[{"role": "user", "content": "Explain proof of stake in two sentences"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="", flush=True)
javascript
const stream = await client.chat.completions.create({
  model: "qwen3.8-27b",
  messages: [{ role: "user", content: "Explain proof of stake in two sentences" }],
  stream: true,
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
shell
curl -N https://api.tenzro.xyz/v1/chat/completions \
  -H "Authorization: Bearer $TENZRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen3.5-4b", "messages": [{"role": "user", "content": "Hello"}], "stream": true}'
Step 08

Handle errors

Errors use the OpenAI shape, {"error": {"message", "type", "code"}}, with a matching HTTP status.

400
wrong_endpoint
Call the model at the endpoint the message names.
401
missing_api_key · invalid_api_key
Send a valid Platform key.
402
insufficient_credit
Top up credit on the Platform.
403
key_lacks_inference_permission
Use a key with the inference permission.
404
model_not_found · machine_not_found
Use an id from GET /v1/models.
502
machine_unreachable · machine_error
Retry with backoff.
503
no_capacity
The model is not serving on that machine now. Retry later or pick another model.
Retry 502 and 503 with exponential backoff. The other errors will not succeed on retry. Every price is zero on testnet.