NinjaChat
ModelsPricingToolsBlog
Sign inDashboard→
ModelsPricingToolsBlog
Dashboard →
Coming from OpenAI

Keep OpenAI. Add every other lab.

Keep the OpenAI SDK, keep GPT — and get Claude, Gemini, Grok, image, and video on the same key. The migration is a base URL and an API key.

api.openai.com→ninjachat.ai/api/v1
The only two lines

base_url and api_key. GPT keeps its name.

api.openai.com/v1→ninjachat.ai/api/v1
OPENAI_API_KEY→nj_sk_…
gpt-5→gpt-5
before· openai
from openai import OpenAI

client = OpenAI()  # key from OPENAI_API_KEY

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
→becomes
after· ninjachat
from openai import OpenAI

client = OpenAI(
    base_url="https://www.ninjachat.ai/api/v1",   # ← changed
    api_key="nj_sk_YOUR_KEY",                    # ← changed
)

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
Get API Key →API docs ↗
You keep

Your OpenAI models still have names.

GPT Image
GPT-5.4
Same key, new catalog

What joining NinjaChat actually adds.

FLUX 2Imagen 4Nano Banana
Veo 3.1
Kling 2.6
Seedance 2
Claude OpusGemini 3.1Grok 4
The rest

Then these.

  1. 01

    Create a key and add credits

    Get an nj_sk_ key at /developers, add a credit pack. Prepaid; failed gens refund.

    verify your key works
    # Sanity check: list every model your key can call (no auth needed)
    curl https://www.ninjachat.ai/api/v1/models
    
    # First authenticated request
    curl https://www.ninjachat.ai/api/v1/chat/completions \
      -H "Authorization: Bearer nj_sk_YOUR_KEY" \
      -H "Content-Type: application/json" \
      -d '{"model": "gpt-5", "messages": [{"role": "user", "content": "Say hi"}]}'
  2. 02

    Verify streaming and tool calling

    Same SDK code. SSE deltas; tool_calls round-trip with role:"tool".

    streaming + tools, unchanged sdk
    # Streaming
    stream = client.chat.completions.create(
        model="claude-sonnet-4.6",
        messages=[{"role": "user", "content": "Write a haiku about ninjas"}],
        stream=True,
    )
    for chunk in stream:
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="", flush=True)
    
    # Tool calling
    resp = client.chat.completions.create(
        model="gpt-5",
        messages=[{"role": "user", "content": "Weather in Tokyo?"}],
        tools=[{
            "type": "function",
            "function": {
                "name": "get_weather",
                "parameters": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        }],
    )
    call = resp.choices[0].message.tool_calls[0]
    # ...run your function, then send the result back:
    followup = client.chat.completions.create(
        model="gpt-5",
        messages=[
            {"role": "user", "content": "Weather in Tokyo?"},
            resp.choices[0].message,
            {"role": "tool", "tool_call_id": call.id, "content": "22°C, clear"},
        ],
    )
  3. 03

    Move image generation to /v1/images/generations

    If you use OpenAI's Images API, the equivalent here is POST /v1/images/generations — synchronous JSON with hosted URLs instead of base64 by default. gpt-image-2 is available directly, alongside FLUX, Imagen 4, and Nano Banana on the same key.

    before· openai
    # Before — OpenAI Images API
    img = client.images.generate(
        model="gpt-image-1",
        prompt="a ninja cat, studio lighting",
    )
    →becomes
    after· ninjachat
    import requests
    
    r = requests.post(
        "https://www.ninjachat.ai/api/v1/images/generations",
        headers={"Authorization": "Bearer nj_sk_YOUR_KEY"},
        json={"model": "gpt-image-2", "prompt": "a ninja cat, studio lighting", "n": 1},
    )
    print(r.json()["data"][0]["url"])  # hosted URL, ready to use

    This endpoint is OpenAI-shaped: POST /images/generations returns { data: [{url}], model, usage, cost_usd, request_id }.

Model mapping — OpenAI ids to NinjaChat slugs

GPT models keep their names. Prices shown are typical per-request (5K-in/1K-out) at the published $/MTok rates.

OpenAI modelNinjaChat slugPrice / request
gpt-5.4gpt-5.4$0.031
gpt-5.4-progpt-5.4-protypical request — this model bills $33.60/$201.60 per MTok≈$0.37
gpt-5gpt-5$0.026
gpt-5-minigpt-5-minitemporarily unavailable$0.004
o3-minio3-mini$0.011
gpt-image-1 / gpt-image-2gpt-image-2 (POST /v1/images/generations)$0.16 / image
— (not on OpenAI)claude-opus-4.6, gemini-3.1-pro, grok-4…the reason to switch: every frontier lab on one key$0.01–$0.056
The honest part

What doesn't come along.

No /v1/embeddings and no moderations endpoint

NinjaChat's v1 API covers chat, images, video, and search. If your pipeline embeds documents or calls a moderation endpoint, keep those calls on your current provider — only the completion traffic needs to move.

60 requests/min default rate limit

Every API key gets 60 requests per minute (video submissions are throttled harder because each one is a long-running job). 429 responses include Retry-After. Need more? Contact us from the console.

Prepaid credits, not postpaid billing

You buy a credit pack up front instead of getting a surprise invoice. Failed generations are automatically refunded, and you can set monthly spend limits per account, key, or project.

Metered $/MTok chat pricing

Chat bills per token — published $/MTok input and output rates for every model on GET /v1/models (cache-read and long-context tiers included). Requests preauthorize an estimated maximum and settle to actual usage; a typical request runs from ≈$0.002 on open models to ≈$0.056 on Claude Opus (gpt-5.4-pro ≈$0.37). No length guard — long context just needs balance.

Chat Completions only — no Assistants, Responses, or Realtime API

NinjaChat implements the Chat Completions surface (plus native images/video/search). Code built on the Assistants API, the Responses API, fine-tuning, or audio/realtime endpoints won't port — chat.completions code ports unchanged.

FAQ

Do I have to change my openai SDK code to migrate?

No. Change base_url to https://www.ninjachat.ai/api/v1 and api_key to an nj_sk_ key. chat.completions.create, streaming loops, tool-calling round-trips, and models.list all keep working with the official openai package in Python and Node.

Can I still call GPT models after leaving the OpenAI API?

Yes — gpt-5.4, gpt-5.4-pro, gpt-5, gpt-5-mini, and o3-mini are all served under their own names, alongside Claude, Gemini, Grok, Llama, and DeepSeek on the same key.

What happens to my JSON mode / structured outputs?

response_format {type: "json_object"} and {type: "json_schema"} are both enforced server-side. One caveat: json_schema combined with stream: true returns a 400 — use non-streaming for strict-schema outputs.

Is there an equivalent of the OpenAI embeddings endpoint?

No. There is no /v1/embeddings — keep embedding calls on OpenAI (or any embeddings provider) and move only completion traffic. Mixing providers is exactly what the OpenAI SDK's base_url parameter is for.

How does billing differ from OpenAI's?

OpenAI meters tokens and invoices you. NinjaChat is prepaid credits with the same per-token billing model — published $/MTok rates for every lab's models on one balance, holds that settle to actual usage, and automatic refunds on failed requests.

Ready for every lab?

Get API Key →All guides →
NinjaChat

Every AI. One app.

Download on the App Store

Product

  • Dashboard
  • ninja for iMessage
  • Pricing
  • Free AI Tools
  • Affiliate Program
  • iOS App

Developers

  • API
  • API Models
  • MCP / Agents
  • API Docs

Models

  • Model Council
  • Seed 1.8
  • Gemini 2.5 Flash
  • Gemini 2.5 Pro
  • Gemini 3 Flash Preview
  • View All Models

Company

  • Blog
  • Uncensored AI
  • Community
  • Careers
  • Support
  • Privacy Policy
  • Terms of Service

Copyright © 2026 NinjaChat AI. Product of Bloon All Rights Reserved.