The hosted gateway is OpenAI-compatible, so the official openai SDK works for the supported chat, streaming, and model-list methods. Start by changing the base URL and key, then select a model your own machine is serving.

Set B3IQ_API_KEY to your gateway key as described below. These examples use your-served-model-id; replace it with a model ID returned by client.models.list(). The model must be served by your machines and available to this key. Changing the client configuration does not change an existing request's model value.

python
import osfrom openai import OpenAIclient = OpenAI( base_url="https://b3iq.org/v1/api", api_key=os.environ["B3IQ_API_KEY"],)reply = client.chat.completions.create( model="your-served-model-id", messages=[{"role": "user", "content": "Hi"}],)print(reply.choices[0].message.content)

chat.completions.create, streaming, and models.list() use the SDK methods shown below. Provider-specific tools and unsupported endpoints do not become available by changing the base URL. Requests are free and route only to the machines on your own account.

Coming from OpenRouter or OpenAI directly?

Change base_url/baseURL and api_key/apiKey, then set model on each request to an ID available to your B3IQ key. Model IDs and optional features can differ between providers.

Before you start

1

Create a gateway key

Sign in to the dashboard and create a gateway key. Hosted keys are b3iq_gateway_ secrets, shown once, stored hashed, and revocable.

2

Have a machine online

Your key routes only to machines on your own account, so you need at least one online machine serving the model you want to call. See Run your first node.

3

Install the SDK

bash
pip install openai
Keep the key out of source

Read b3iq_gateway_ secrets from an environment variable, not a literal string in committed code.

bash
export B3IQ_API_KEY="b3iq_gateway_..."

Create the client

python
import osfrom openai import OpenAIclient = OpenAI( base_url="https://b3iq.org/v1/api", api_key=os.environ["B3IQ_API_KEY"],)

List your models

Call models.list() before you call chat. It tells you exactly what you can route to right now. Replace your-served-model-id in the examples with the exact ID returned by the list, including any model tag. The placeholder is not a model you can call.

python
for model in client.models.list(): print(model.id)
Your models, not the network's

Called with your gateway key, models.list() returns only the models the machines on your account serve right now: any node scope on the key is respected, and machines you've switched to Earn mode are excluded. The list reflects eligible routes at request time; the set changes as your machines come and go, so list before you call rather than hardcoding an id. Without an owner-scoped key, the same endpoint returns data: []. It does not advertise a shared public pool. See Hosted Gateway.

If the list is empty or your expected model is missing, check that the key belongs to the intended account, its machine scope includes the serving machine, and that machine is online, serving the model, and not in Earn mode. Check the machine's model status in the dashboard, then list models again.

Chat completion

python
response = client.chat.completions.create( model="your-served-model-id", # use an id from models.list() messages=[{"role": "user", "content": "Say hello from B3IQ."}],)print(response.choices[0].message.content)

A successful call returns a standard OpenAI ChatCompletion object, served free by a machine on your account.

Streaming

Set stream=True / stream: true and iterate the SDK's stream object exactly as you would against OpenAI.

python
stream = client.chat.completions.create( model="your-served-model-id", messages=[{"role": "user", "content": "Stream a short response."}], stream=True,)for chunk in stream: delta = chunk.choices[0].delta.content if chunk.choices else None if delta: print(delta, end="", flush=True)

Streamed requests are metered the same as non-streamed ones. Get the non-streaming call working first, then flip stream on.

Handling errors

Denials come back as a standard OpenAI-style error object, so SDK exceptions behave the way they do against OpenAI. Catch the SDK's API error type and branch on the stable machine code, not the human-readable message.

python
from openai import APIStatusErrortry: client.chat.completions.create( model="your-served-model-id", messages=[{"role": "user", "content": "Say hello from B3IQ."}], )except APIStatusError as e: print(e.status_code, e.code)

A no_eligible_nodes code means no machine on your account serves that model right now. Call models.list() again rather than retrying blind. See Errors for the full list of stable codes.

Or check with the CLI

The b3iq CLI makes the same calls without writing code: install it, run b3iq login, then b3iq models list to see what your keys can route to.

Call the gateway

The same flow over raw HTTP with curl and fetch, plus the full error and streaming walkthrough.

Learn More
Hosted gateway

Full endpoint list, headers, and the gate order a request passes.

Learn More
Usage & quotas

Free inference, per-key metering, rate limits, and the token quota.

Learn More
Ask a question... ⌘I