# Chat
Source: https://docs.kitefishai.com/api-reference/chat
API reference for client.chat
## `client.chat.complete()`
Send a chat completion request and return the full response.
```python theme={null}
response = client.chat.complete(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "Hello"}],
)
```
### Parameters
Model ID. Example: `"kf-reasoning-10b"`.
Conversation history as a list of `{"role": ..., "content": ...}` dicts.
Roles: `"user"`, `"assistant"`, `"system"`.
System prompt. Prepended automatically as a `system` message.
Maximum tokens to generate. Default `1024`.
Sampling temperature between `0.0` and `2.0`. Default `0.7`.
Nucleus sampling probability. Default `1.0`.
Any additional parameters passed through to the API.
### Returns: `ChatCompletion`
| Field | Type | Description |
| --------- | --------------- | ------------------- |
| `id` | `str` | Request ID |
| `model` | `str` | Model used |
| `choices` | `List[Choice]` | Generated responses |
| `usage` | `Usage` or None | Token usage |
Each `Choice`:
| Field | Type | Description |
| --------------- | --------- | ---------------------- |
| `index` | `int` | Index in choices list |
| `message` | `Message` | The generated message |
| `finish_reason` | `str` | Why generation stopped |
`Message` has `role` and `content` fields.
***
## `client.chat.stream()`
Send a streaming chat request. Returns a `ChatStream` context manager.
```python theme={null}
with client.chat.stream(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "Hello"}],
) as stream:
for chunk in stream:
print(chunk.delta, end="", flush=True)
```
### Parameters
Same as `complete()`.
### Returns: `ChatStream`
Use as a context manager and iterate over `StreamChunk` objects.
| Method | Returns | Description |
| ------------------ | ------- | -------------------------------------- |
| `__iter__` | chunks | Yields `StreamChunk` objects |
| `get_final_text()` | `str` | Full concatenated text after iteration |
Each `StreamChunk`:
| Field | Type | Description |
| --------------- | ------------- | --------------------------- |
| `id` | `str` | Request ID |
| `model` | `str` | Model used |
| `delta` | `str` | Text content of this chunk |
| `finish_reason` | `str` or None | `"stop"` on the final chunk |
# Client
Source: https://docs.kitefishai.com/api-reference/client
The main KiteFishAI client class.
## Import
```python theme={null}
import kitefishai
client = kitefishai.Client(api_key="kf-...")
```
## Constructor
```python theme={null}
kitefishai.Client(
api_key=None,
base_url=None,
timeout=60.0,
max_retries=2,
http_client=None,
)
```
### Parameters
Your KiteFishAI API key. Falls back to the `KITEFISH_API_KEY` environment variable. Raises `AuthenticationError` if neither is set.
API base URL. Defaults to `https://api.kitefishai.com/v1`. Falls back to `KITEFISH_BASE_URL` env var. Override for on-prem deployments.
Request timeout in seconds. Default `60.0`.
Number of retries on network errors and timeouts. Default `2`. Set to `0` to disable.
Bring your own `httpx.Client` for custom TLS, proxies, or connection pooling.
## Resources
| Attribute | Type | Description |
| ------------------- | ------------ | ---------------- |
| `client.chat` | `Chat` | Chat completions |
| `client.embeddings` | `Embeddings` | Text embeddings |
## Context manager
The client can be used as a context manager — the underlying HTTP connection is closed automatically:
```python theme={null}
with kitefishai.Client(api_key="kf-...") as client:
response = client.chat.complete(...)
```
## Manual close
```python theme={null}
client = kitefishai.Client(api_key="kf-...")
# ... use client ...
client.close()
```
# Embeddings
Source: https://docs.kitefishai.com/api-reference/embeddings
API reference for client.embeddings
## `client.embeddings.create()`
Generate embeddings for one or more input strings.
```python theme={null}
result = client.embeddings.create(
model="minnow-em-v1",
input="query: what is DPDP?",
)
```
### Parameters
Embedding model ID. Example: `"minnow-em-v1"`.
A single string or a list of strings to embed.
Request a specific MRL dimension. Supported values: `896`, `512`, `256`, `128`, `64`.
Defaults to the model's native dimension (`896` for `minnow-em-v1`).
`"float"` (default) or `"base64"`.
Any additional parameters passed through to the API.
### Returns: `EmbeddingResponse`
| Field | Type | Description |
| ------- | ----------------- | ------------------------- |
| `model` | `str` | Model used |
| `data` | `List[Embedding]` | One item per input string |
| `usage` | `Usage` or None | Token counts |
Each `Embedding`:
| Field | Type | Description |
| ----------- | ------------- | -------------------------- |
| `index` | `int` | Position in the input list |
| `embedding` | `List[float]` | The dense embedding vector |
| `object` | `str` | Always `"embedding"` |
### Example — batch with MRL
```python theme={null}
result = client.embeddings.create(
model="minnow-em-v1",
input=[
"query: insurance claim process",
"passage: Claims must be filed within 30 days...",
],
dimensions=256,
)
for item in result.data:
print(f"[{item.index}] dim={len(item.embedding)}")
```
# Authentication
Source: https://docs.kitefishai.com/guides/authentication
How to authenticate with the KiteFishAI API.
## API Keys
All requests require an API key. Keys are prefixed with `kf-` and can be created from the [dashboard](https://kitefishai.com/dashboard).
## Option 1 — Pass directly
```python theme={null}
import kitefishai
client = kitefishai.Client(api_key="kf-...")
```
## Option 2 — Environment variable (recommended)
Set `KITEFISH_API_KEY` in your environment and the client picks it up automatically:
```bash theme={null}
export KITEFISH_API_KEY="kf-..."
```
```python theme={null}
client = kitefishai.Client()
```
This is the recommended approach. It keeps credentials out of source code.
## Option 3 — `.env` file
Use a library like [`python-dotenv`](https://pypi.org/project/python-dotenv/):
```bash theme={null}
# .env
KITEFISH_API_KEY=kf-...
```
```python theme={null}
from dotenv import load_dotenv
load_dotenv()
import kitefishai
client = kitefishai.Client()
```
Never commit API keys to source control. Add `.env` to your `.gitignore`.
## On-prem deployments
For air-gapped enterprise deployments, override the base URL:
```python theme={null}
client = kitefishai.Client(
api_key="kf-...",
base_url="https://your-internal-host/v1",
)
```
Or via environment:
```bash theme={null}
export KITEFISH_BASE_URL="https://your-internal-host/v1"
```
# Embeddings
Source: https://docs.kitefishai.com/guides/embeddings
API reference for client.embeddings
## `client.embeddings.create()`
Generate embeddings for one or more input strings.
```python theme={null}
result = client.embeddings.create(
model="minnow-em-v1",
input="query: what is DPDP?",
)
```
### Parameters
Embedding model ID. Example: `"minnow-em-v1"`.
A single string or a list of strings to embed.
Request a specific MRL dimension. Supported values: `896`, `512`, `256`, `128`, `64`.
Defaults to the model's native dimension (`896` for `minnow-em-v1`).
`"float"` (default) or `"base64"`.
Any additional parameters passed through to the API.
### Returns: `EmbeddingResponse`
| Field | Type | Description |
| ------- | ----------------- | ------------------------- |
| `model` | `str` | Model used |
| `data` | `List[Embedding]` | One item per input string |
| `usage` | `Usage` or None | Token counts |
Each `Embedding`:
| Field | Type | Description |
| ----------- | ------------- | -------------------------- |
| `index` | `int` | Position in the input list |
| `embedding` | `List[float]` | The dense embedding vector |
| `object` | `str` | Always `"embedding"` |
### Example — batch with MRL
```python theme={null}
result = client.embeddings.create(
model="minnow-em-v1",
input=[
"query: insurance claim process",
"passage: Claims must be filed within 30 days...",
],
dimensions=256,
)
for item in result.data:
print(f"[{item.index}] dim={len(item.embedding)}")
```
# Error Handling
Source: https://docs.kitefishai.com/guides/error-handling
Handle errors gracefully in the KiteFishAI Python SDK.
## Exception hierarchy
```
KiteFishAIError
├── AuthenticationError # 401 — invalid or missing API key
├── RateLimitError # 429 — too many requests
├── NotFoundError # 404 — model or resource not found
└── APIError # any other non-2xx response
```
## Basic pattern
```python theme={null}
import kitefishai
client = kitefishai.Client(api_key="kf-...")
try:
response = client.chat.complete(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "Hello"}],
)
except kitefishai.AuthenticationError:
print("Invalid API key — check KITEFISH_API_KEY")
except kitefishai.RateLimitError:
print("Rate limit hit — back off and retry")
except kitefishai.NotFoundError as e:
print(f"Model not found: {e}")
except kitefishai.APIError as e:
print(f"API error {e.status_code}: {e.message}")
except kitefishai.KiteFishAIError as e:
print(f"SDK error: {e}")
```
## Timeouts
The default timeout is 60 seconds. Increase it for long completions:
```python theme={null}
client = kitefishai.Client(
api_key="kf-...",
timeout=120.0,
)
```
If a request times out, a `KiteFishAIError` is raised with a descriptive message.
## Retries
The SDK automatically retries on timeout and network errors. Default is 2 retries:
```python theme={null}
client = kitefishai.Client(
api_key="kf-...",
max_retries=3,
)
```
To disable retries:
```python theme={null}
client = kitefishai.Client(api_key="kf-...", max_retries=0)
```
Retries are only attempted on network-level failures and timeouts — not on API errors like 401 or 429.
# Installation
Source: https://docs.kitefishai.com/guides/installation
Install and set up the KiteFishAI Python SDK.
## Requirements
* Python 3.12 or higher
* pip or poetry
## pip
```bash theme={null}
pip install kitefishai
```
## poetry
```bash theme={null}
poetry add kitefishai
```
## Verify installation
```python theme={null}
import kitefishai
print(kitefishai.__version__)
```
## Optional: set your API key globally
Rather than passing `api_key` every time, export it as an environment variable:
```bash theme={null}
export KITEFISH_API_KEY="kf-..."
```
Then the client picks it up automatically:
```python theme={null}
client = kitefishai.Client() # reads KITEFISH_API_KEY
```
For on-prem deployments you can also set the base URL:
```bash theme={null}
export KITEFISH_API_KEY="kf-..."
export KITEFISH_BASE_URL="https://your-internal-host/v1"
```
# On-Prem Deployment
Source: https://docs.kitefishai.com/guides/on-prem
Use the SDK with air-gapped, on-premise KiteFishAI deployments.
## Overview
KiteFishAI is designed for regulated enterprises that cannot send data to external APIs. The Python SDK works identically against an on-prem deployment — just point it at your internal host.
## Configuration
```python theme={null}
import kitefishai
client = kitefishai.Client(
api_key="kf-...",
base_url="https://your-internal-host/v1",
)
```
Or via environment variables:
```bash theme={null}
export KITEFISH_API_KEY="kf-..."
export KITEFISH_BASE_URL="https://your-internal-host/v1"
```
```python theme={null}
client = kitefishai.Client() # picks up both env vars
```
## Timeout tuning
On-prem hardware may have different latency characteristics. Tune accordingly:
```python theme={null}
client = kitefishai.Client(
api_key="kf-...",
base_url="https://your-internal-host/v1",
timeout=120.0,
max_retries=3,
)
```
## TLS / self-signed certificates
If your internal deployment uses a self-signed certificate, pass a custom `httpx` client:
```python theme={null}
import httpx
import kitefishai
http_client = httpx.Client(verify="/path/to/internal-ca.crt")
client = kitefishai.Client(
api_key="kf-...",
base_url="https://your-internal-host/v1",
http_client=http_client,
)
```
Do not set `verify=False` in production. Always use a proper CA bundle.
## Data residency
All data stays within your premises. No telemetry or usage data is sent to KiteFishAI servers when running on-prem. This satisfies requirements under RBI, IRDAI, and India's DPDP Act 2023.
# Quickstart
Source: https://docs.kitefishai.com/guides/quickstart
Get up and running with the KiteFishAI Python SDK in under 5 minutes.
## Install
```bash theme={null}
pip install kitefishai
```
## Get an API key
Sign in at [platform.kitefishai.com/dashboard](https://platform.kitefishai.com/login) and create an API key. Keys start with `kf-`.
## Your first request
```python theme={null}
import kitefishai
client = kitefishai.Client(api_key="kf-...")
response = client.chat.complete(
model="kf-reasoning-10b",
messages=[
{"role": "user", "content": "Summarise the DPDP Act 2023."}
],
)
print(response.choices[0].message.content)
```
## Streaming
```python theme={null}
with client.chat.stream(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "Explain claim settlement."}],
) as stream:
for chunk in stream:
print(chunk.delta, end="", flush=True)
```
## Embeddings
```python theme={null}
result = client.embeddings.create(
model="minnow-em-v1",
input=["query: what is KYC?"],
)
print(result.data[0].embedding[:5])
```
## Next steps
API keys and environment variables
Stream chat responses token by token
Generate embeddings with Minnow-Em
Use the SDK with air-gapped deployments
# Streaming
Source: https://docs.kitefishai.com/guides/streaming
Stream chat responses token by token.
## Overview
Streaming returns tokens as they are generated rather than waiting for the full response. This gives users a faster perceived experience — important for long outputs like document summaries or policy analysis.
## Basic streaming
```python theme={null}
import kitefishai
client = kitefishai.Client(api_key="kf-...")
with client.chat.stream(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "Summarise the RBI Master Directions on KYC."}],
) as stream:
for chunk in stream:
print(chunk.delta, end="", flush=True)
print() # newline after stream ends
```
## Get the full text after streaming
```python theme={null}
with client.chat.stream(
model="kf-reasoning-10b",
messages=[{"role": "user", "content": "List IRDAI compliance requirements."}],
) as stream:
for chunk in stream:
print(chunk.delta, end="", flush=True)
full_text = stream.get_final_text()
print(f"\nTotal characters: {len(full_text)}")
```
## StreamChunk fields
Each chunk yielded by the iterator has:
| Field | Type | Description |
| --------------- | --------------- | ------------------------------ |
| `id` | `str` | Request ID |
| `model` | `str` | Model that generated the chunk |
| `delta` | `str` | The text content of this chunk |
| `finish_reason` | `str` or `None` | `"stop"` on the final chunk |
## With a system prompt
```python theme={null}
with client.chat.stream(
model="kf-reasoning-10b",
system="You are a BFSI compliance assistant. Be concise and cite regulations.",
messages=[{"role": "user", "content": "What is Form 60?"}],
) as stream:
for chunk in stream:
print(chunk.delta, end="", flush=True)
```
## Collecting chunks manually
```python theme={null}
chunks = []
with client.chat.stream(model="kf-reasoning-10b", messages=[...]) as stream:
for chunk in stream:
chunks.append(chunk)
print(f"Received {len(chunks)} chunks")
print("".join(c.delta for c in chunks))
```