> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ninjachat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Go live

> A compact production checklist for reliable, observable, and cost-bounded NinjaChat integrations.

Use this checklist after your first successful request and before sending customer traffic.

## Production baseline

<CardGroup cols={2}>
  <Card title="Keep keys server-side" icon="key" href="/authentication">
    Store `NINJACHAT_API_KEY` in your deployment platform or secret manager. Never ship it to a browser or mobile client.
  </Card>

  <Card title="Set timeouts and retries" icon="rotate" href="/rate-limits">
    Use the SDK defaults or configure bounded retries. The SDK honors `Retry-After` and safely replays billed requests with idempotency keys.
  </Card>

  <Card title="Design a fallback" icon="route" href="/fallback-chains">
    Use `ninja/auto` or an ordered `models` list so one provider incident does not become your incident.
  </Card>

  <Card title="Bound spend" icon="gauge-high" href="/budget-routing">
    Set `routing.max_cost_usd`, project limits, and balance alerts before traffic grows.
  </Card>
</CardGroup>

## Recommended client

The SDK is the shortest production-safe path because it includes typed errors, streaming helpers, retry handling, and idempotency behavior.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { NinjaChat } from "@ninjachat/sdk";

  const client = new NinjaChat({
    apiKey: process.env.NINJACHAT_API_KEY!,
    maxRetries: 3,
    timeoutMs: 120_000,
  });
  ```

  ```python Python theme={null}
  import os
  from ninjachat import NinjaChat

  client = NinjaChat(
      api_key=os.environ["NINJACHAT_API_KEY"],
      max_retries=3,
      timeout=120,
  )
  ```
</CodeGroup>

## A resilient request

Use an ordered model set when you need predictable model families, or replace `models` with `model: "ninja/auto"` when NinjaChat should choose.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await client.responses.create({
    models: ["gpt-5.6-luna", "claude-sonnet-5", "gemini-3.7-flash"],
    input: "Classify this support request and explain the decision.",
    max_output_tokens: 300,
    routing: {
      strategy: "balanced",
      data_policy: "no_training",
      max_cost_usd: 0.05,
    },
  });

  console.log(response.output_text);
  console.log(response.request_id, response.cost_usd);
  ```

  ```python Python theme={null}
  response = client.responses.create(
      models=["gpt-5.6-luna", "claude-sonnet-5", "gemini-3.7-flash"],
      input="Classify this support request and explain the decision.",
      max_output_tokens=300,
      routing={
          "strategy": "balanced",
          "data_policy": "no_training",
          "max_cost_usd": 0.05,
      },
  )

  print(response["output_text"])
  print(response["request_id"], response["cost_usd"])
  ```
</CodeGroup>

## Before customer traffic

* Pin an SDK version and review release notes before upgrades.
* Send a stable end-user identifier in `user` for your own abuse and support workflows; do not put secrets or personal data in it.
* Bound concurrency with a worker pool instead of unbounded fan-out.
* Cancel abandoned streams and long-running client requests.
* Store the returned `request_id` beside your application trace or job record.
* Monitor usage, balance, latency, errors, and resolved providers.
* Use signed webhooks for completed or failed video jobs and spend alerts.
* Test `401`, `402`, `429`, timeout, and provider-failure paths before launch.

## Release gate

| Check          | Pass condition                                                     |
| -------------- | ------------------------------------------------------------------ |
| Authentication | Keys are server-side, scoped, and rotatable                        |
| Reliability    | Retries are bounded and at least one fallback is configured        |
| Cost           | Per-request and project limits match the product plan              |
| Observability  | Request IDs reach logs and a trace lookup is available             |
| Async work     | Video completion uses signed webhooks or bounded polling           |
| Failure UX     | Users receive a useful retry or fallback state for `429` and `5xx` |

Next: wire the [observability loop](/observability) and run the [quickstart](/quickstart) once from your deployment environment.
