OpenAI SDK
Set base_url to https://api.kotoba.cloud/v1 and api_key to your connection token. chat.completions works unchanged.
from openai import OpenAI
client = OpenAI(base_url="https://api.kotoba.cloud/v1", api_key=os.environ["KOTOBA_API_TOKEN"])
r = client.chat.completions.create(
model="qwen3.8-flash-next-whitehacker",
max_tokens=2048,
messages=[{"role": "user", "content": "Review this login handler for auth bypasses: ..."}],
)
print(r.choices[0].message.content)
print(r.model_extra["billing"], r.usage) # "free" or "paid"; usage on paid answers
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.kotoba.cloud/v1", apiKey: process.env.KOTOBA_API_TOKEN });
const r = await client.chat.completions.create({
model: "qwen3.8-flash-next-whitehacker",
max_tokens: 2048,
messages: [{ role: "user", content: "Review this login handler for auth bypasses: ..." }],
});
console.log(r.choices[0].message.content);
What passes
- messages (one leading system turn; user / assistant / tool turns; up to 256 turns; 524,288 input characters in total)
- max_tokens or max_completion_tokens (1..32,768), stream (one-chunk SSE), n (must be 1)
- tools (up to 128 function definitions) and tool_choice — native tool_calls come back
- Accepted and dropped: temperature, top_p, presence/frequency_penalty, stop, response_format, parallel_tool_calls, stream_options, user, seed, logit_bias, logprobs, top_logprobs, metadata, store, service_tier, reasoning_effort, reasoning, prompt_cache_key, safety_identifier, modalities
- Any other key is a 400 invalid-research-request whose message names it
Extra fields on the answer
The OpenAI shape plus billing ("free" / "paid"), receiptId, and on paid answers usage and chargedMicroUSD. SDKs keep unknown fields (model_extra in Python; as-is in TypeScript).
Other wires (/v1/responses, /v1/embeddings, /v1/images) are not served (405). SDK settings that default to the Responses API must go back to chat.completions.