Integration Guides

Calling ROIBest AI Directly from SDKs and curl

ROIBest AI

Not everything runs inside a CLI client. When you are writing your own script, wiring the gateway into an existing service, or just want to verify a path quickly, calling the API directly is the shortest route — the official SDKs need no code changes, only a different base URL and key.

What the gateway exposes

ROIBest AI serves two protocols, with the same endpoint paths as upstream:

Anthropic-compatible (requires a key from the Anthropic-compatible group)

  • POST /v1/messages
  • POST /v1/messages/count_tokens

OpenAI-compatible (requires a key from the OpenAI-compatible group)

  • POST /v1/chat/completions
  • POST /v1/responses
  • POST /v1/embeddings
  • POST /v1/images/generations, POST /v1/images/edits
  • GET /v1/models

Both authentication styles are accepted:

Authorization: Bearer <your-key>
x-api-key: <your-key>

Use whichever your SDK prefers; there is no need to standardise on one.

curl: the fastest check

Running one curl call before configuring any client cleanly separates "can the gateway be reached" from "is the client configured correctly".

OpenAI protocol:

curl https://ai.roibest.com/v1/chat/completions \
  -H "Authorization: Bearer $ROIBEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5",
    "messages": [{"role": "user", "content": "ping"}]
  }'

Anthropic protocol:

curl https://ai.roibest.com/v1/messages \
  -H "Authorization: Bearer $ROIBEST_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 64,
    "messages": [{"role": "user", "content": "ping"}]
  }'

The two keys are not interchangeable — they belong to different protocol groups.

Python

OpenAI SDK:

from openai import OpenAI

client = OpenAI(
    base_url="https://ai.roibest.com/v1",
    api_key="your-key",
)

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "ping"}],
)
print(resp.choices[0].message.content)

Anthropic SDK:

from anthropic import Anthropic

client = Anthropic(
    base_url="https://ai.roibest.com",
    api_key="your-key",
)

msg = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=64,
    messages=[{"role": "user", "content": "ping"}],
)
print(msg.content[0].text)

Note the base URLs differ: the OpenAI SDK wants /v1, the Anthropic SDK does not — it appends the path itself. This is the single most common source of 404s during setup.

Node.js

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://ai.roibest.com/v1",
  apiKey: process.env.ROIBEST_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "ping" }],
});
console.log(resp.choices[0].message.content);

Other OpenAI-protocol clients

OpenCode, Cline, Roo Code and similar tools generally support a custom OpenAI-compatible endpoint. The field names differ, but there are only two values to supply:

  • Base URL: https://ai.roibest.com/v1
  • API key: from the OpenAI-compatible group

If the client calls the setting "OpenAI Base URL" or "Custom endpoint", that is the one. Check each client's own documentation for where the fields live. As with everything else here, run the curl check first so you know the gateway side is clean before debugging the client.

Listing available models

curl https://ai.roibest.com/v1/models \
  -H "Authorization: Bearer $ROIBEST_API_KEY"

This returns the models actually available to your account and group. Query it once before hard-coding a model name.

Where usage shows up

Whichever protocol and SDK you use, every request is recorded in the console's usage records: model, protocol group, input and output tokens, cache tokens, billing mode, cost and latency. Failed requests go into a separate error log, so they do not pollute your usage figures.