NinjaChat Python SDK
Typed client for the clean NinjaChat API v1.
pip install ninjachat
import os
from ninjachat import NinjaChat
client = NinjaChat(api_key=os.environ["NINJACHAT_API_KEY"])
response = client.responses.create(
model="ninja/auto",
input="Write one sentence about clean APIs.",
max_output_tokens=64,
routing={"strategy": "balanced", "data_policy": "no_training"},
)
print(response["output_text"], response["cost_usd"], response["request_id"])
Ordered fallbacks and provider constraints are explicit:
completion = client.chat.completions.create(
models=["gpt-5", "claude-sonnet-4.6"],
messages=[{"role": "user", "content": "Hello"}],
max_completion_tokens=100,
routing={"strategy": "latency", "allow_fallbacks": True, "caching": "auto", "max_cost_usd": 0.10},
)
Streaming responses are iterators of event dictionaries:
for event in client.responses.create(model="ninja/auto", input="Hello", stream=True):
if event.get("type") == "response.output_text.delta":
print(event.get("delta", ""), end="")
Async client
Use AsyncNinjaChat with async with to close connections when finished:
import asyncio
import os
from ninjachat import AsyncNinjaChat
async def main():
async with AsyncNinjaChat(api_key=os.environ["NINJACHAT_API_KEY"]) as client:
response = await client.responses.create(model="ninja/auto", input="Hello")
print(response["output_text"])
asyncio.run(main())
Beyond one completion
Run one prompt across several models and get them back ranked by quality, speed
and cost — one hold, one settlement, one request id. A model that fails costs
nothing and lands in failed:
comparison = client.compare.create(
messages=[{"role": "user", "content": "Explain CRDTs in three sentences."}],
models=["gpt-5", "claude-sonnet-4.6", "gemini-3.1-pro"],
rank_by="balanced",
)
print(comparison["winner"]["model"], comparison["total_cost_cents"])
Streaming interleaves per-model deltas and closes with the rankings. A
model_error is one model's problem, not the stream's — the rest keep going:
for event in client.compare.create(messages=messages, models=models, stream=True):
if event["type"] == "delta":
print(event["model"], event["delta"]["content"])
Fan out independent requests with client.batch.create(), and chain modalities
with client.pipelines.create() / client.pipelines.wait_for():
batch = client.batch.create(
requests=[
{"model": "gpt-5", "messages": [{"role": "user", "content": "Headline A"}]},
{"model": "gemini-3-flash", "messages": [{"role": "user", "content": "Headline B"}]},
],
)
pipeline = client.pipelines.create(
steps=[
{"id": "script", "type": "chat", "model": "gpt-5-mini", "input": "One line about a paper crane."},
{"id": "art", "type": "image", "prompt": "{{script.output}}"},
],
)
finished = client.pipelines.wait_for(pipeline["id"])
Price a request before running it with client.estimate.create(), and read the
rate sheet billing itself uses with client.pricing.retrieve(). Both are public
endpoints — the key is ignored, and nothing is deducted.
Saved presets carry the model chain, routing and system prompt server-side, so configuration ships without a redeploy:
reply = client.presets.run("support-agent", messages=[{"role": "user", "content": "Where is my order?"}])
Models and prices come from client.models.list(). Images use client.images.generate(), videos use client.videos.generate() and client.videos.wait_for(), and observability is available through client.usage(), client.balance(), client.health(), and client.requests.get().
The image storage parameter is optional. It defaults to storage="durable" and returns a permanent NinjaChat URL. Use storage="provider" for the lowest latency; depending on the provider, the response contains a temporary URL or inline b64_json plus mime_type.
Signed webhooks replace video polling and fire spend alerts: client.webhooks.create(...) or the console. Verify deliveries with verify_webhook_signature.
The base URL is https://www.ninjachat.ai/api/v1. Chat and Responses are billed by actual token usage. See docs.ninjachat.ai.
Official package
ninjachat is the official Python client for NinjaChat,
published and maintained by Helium Technologies, Inc., the company that operates
NinjaChat. The source lives in the bloon-ai/ninjachat-sdk repository — that
organization is ours; the package is first-party, not a community wrapper.
Requires Python 3.10 or newer.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ninjachat-0.1.3.tar.gz.
File metadata
- Download URL: ninjachat-0.1.3.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf327b27e72c31903c6696b904a3f03b6e40709f1fbfcc3ba8e3e877062f18b3
|
|
| MD5 |
b94314cc185541a7e106ce60f9d3e9f0
|
|
| BLAKE2b-256 |
1a487e8fe7ef9f3a1f15aa7bcb3b240c214117968460b7347e16c2231c081e5f
|
Provenance
The following attestation bundles were made for ninjachat-0.1.3.tar.gz:
Publisher:
release.yml on bloon-ai/ninjachat-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ninjachat-0.1.3.tar.gz -
Subject digest:
bf327b27e72c31903c6696b904a3f03b6e40709f1fbfcc3ba8e3e877062f18b3 - Sigstore transparency entry: 2737440991
- Sigstore integration time:
-
Permalink:
bloon-ai/ninjachat-sdk@c43f1aa6776600447132d85ccbaadb7aadc4190b -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/bloon-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c43f1aa6776600447132d85ccbaadb7aadc4190b -
Trigger Event:
push
-
Statement type:
File details
Details for the file ninjachat-0.1.3-py3-none-any.whl.
File metadata
- Download URL: ninjachat-0.1.3-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e15e091e67412ec90be53a26d9eea6b62ddf03566ebfecb78edc77fbfb6b89dd
|
|
| MD5 |
670beb3d16132774accd1279536db6f9
|
|
| BLAKE2b-256 |
9ff02a1c9faeea217d753efd767afbed270cdd58b4efd73d5f8a44e5f4fd82d2
|
Provenance
The following attestation bundles were made for ninjachat-0.1.3-py3-none-any.whl:
Publisher:
release.yml on bloon-ai/ninjachat-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ninjachat-0.1.3-py3-none-any.whl -
Subject digest:
e15e091e67412ec90be53a26d9eea6b62ddf03566ebfecb78edc77fbfb6b89dd - Sigstore transparency entry: 2737441335
- Sigstore integration time:
-
Permalink:
bloon-ai/ninjachat-sdk@c43f1aa6776600447132d85ccbaadb7aadc4190b -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/bloon-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c43f1aa6776600447132d85ccbaadb7aadc4190b -
Trigger Event:
push
-
Statement type: