# AI client

The `azion/ai` module of the `azion` package is the Azion Lib client for the Azion AI API, an assistant that answers questions about Azion products and services. You send it a conversation, and it returns the answer in one piece with `chat` or in chunks, as the model writes it, with `streamChat`.

Install the package:

```bash
npm install azion
```

The `azion` package receives bug fixes only, and its maintenance ends in December 2026.

Every sample on this page is a TypeScript ES module that runs in Node.js and uses top-level `await`. Types come in through `import type`, so the samples still load when a tool strips the type annotations before running them.

---

## Authentication

The `chat` and `streamChat` functions take your [personal token](/en/documentation/fundamentals/personal-tokens/) from the `AZION_TOKEN` environment variable. A client from [createClient](#createclient) holds its own token, passed in the `token` field.

A `.env` file with both variables looks like this:

```bash
AZION_TOKEN=[TOKEN VALUE]
AZION_DEBUG=true
```

| Variable      | Description                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------------- |
| `AZION_TOKEN` | Your Azion personal token.                                                                                          |
| `AZION_DEBUG` | With `true`, `chat` prints the whole response object before the answer, and `streamChat` prints every chunk object. |

For how the Azion Lib packages resolve the token and the debug setting, refer to [How Azion Lib works](/en/documentation/devtools/azion-lib/how-it-works/).

---

## Response envelope

Every call returns an [AzionAIResult](#azionairesult) object, `{ data, error }`. On success, `data` holds the response and `error` is `null`. On failure, `data` is `null` and `error` is a JavaScript `Error`. A refused call does not throw.

Read the failure from `error.message`. The `message` property of an `Error` is not enumerable, so `JSON.stringify(error)` prints `{}` and hides the reason.

---

## createClient

Creates a client that holds a token and request options and exposes `chat` and `streamChat` as methods. `createClient` is also the default export of `azion/ai`.

```typescript
function createClient(config?: Partial<{
  token: string;
  options?: AzionClientOptions;
}>): AzionAIClient;
```

| Parameter | Type                                        | Required | Description                                      |
| --------- | ------------------------------------------- | -------- | ------------------------------------------------ |
| `token`   | `string`                                    | No       | Your Azion personal token.                       |
| `options` | [`AzionClientOptions`](#azionclientoptions) | No       | Request options for every call the client makes. |

Returns an [AzionAIClient](#azionaiclient). Its methods take the same arguments as the [chat](#chat) and [streamChat](#streamchat) functions.

This sample creates a client and asks it one question:

```typescript
import { createClient } from 'azion/ai';
import type { AzionAIClient } from 'azion/ai';

const client: AzionAIClient = createClient({
  token: process.env.AZION_TOKEN, // Replace with your actual token
  options: {
    // Add any additional options here
  },
});

const { data, error } = await client.chat({ messages: [{ role: 'user', content: 'What is Azion Object Storage? One sentence.' }] });
console.log(data ? data.choices[0].message.content : error);
```

The model writes a different answer on every run. This output is cut after the answer, before the list of documentation pages:

```text
Azion Object Storage is a globally distributed, S3-compatible storage solution that organizes data into buckets, supports granular permissions, and integrates seamlessly with Azion's Edge Network for efficient data management and processing.
…
```

---

## chat

Sends a conversation to the Azion AI API and returns the whole answer when the model finishes it. The function takes two positional arguments, not one object.

```typescript
function chat(
  request: AzionAIRequest,
  options?: AzionClientOptions,
): Promise<AzionAIResult<AzionAIResponse>>;
```

| Parameter | Type                                        | Required | Description               |
| --------- | ------------------------------------------- | -------- | ------------------------- |
| `request` | [`AzionAIRequest`](#azionairequest)         | Yes      | The conversation to send. |
| `options` | [`AzionClientOptions`](#azionclientoptions) | No       | Request options.          |

Returns `data` as an [AzionAIResponse](#azionairesponse). The answer is in `choices[0].message.content`.

```typescript
import { chat } from 'azion/ai';
import type { AzionAIRequest, AzionAIResponse, AzionAIResult } from 'azion/ai';

const request: AzionAIRequest = {
  messages: [{ role: 'user', content: 'Explain what the Azion Web Platform is.' }],
};
const { data: response, error }: AzionAIResult<AzionAIResponse> = await chat(request, { debug: false });
if (response) {
  console.log('AI response:', response.choices[0].message.content);
} else {
  console.error('Chat failed', error);
}
```

On success, the sample prints `AI response:` followed by the answer.

---

## streamChat

Sends a conversation to the Azion AI API and yields the answer in chunks while the model writes it. Use it to show the answer as it arrives.

```typescript
function streamChat(
  request: AzionAIRequest,
  options?: AzionClientOptions,
): AsyncGenerator<AzionAIResult<AzionAIStreamResponse>>;
```

| Parameter | Type                                        | Required | Description               |
| --------- | ------------------------------------------- | -------- | ------------------------- |
| `request` | [`AzionAIRequest`](#azionairequest)         | Yes      | The conversation to send. |
| `options` | [`AzionClientOptions`](#azionclientoptions) | No       | Request options.          |

Returns an async generator, not a promise: read it with `for await`. Each chunk is its own envelope, with `data` as an [AzionAIStreamResponse](#azionaistreamresponse). The text of the chunk is in `choices[0].delta.content`, which a chunk can leave out.

```typescript
import { streamChat } from 'azion/ai';
import type { AzionAIRequest, AzionAIStreamResponse, AzionAIResult } from 'azion/ai';

const request: AzionAIRequest = {
  messages: [{ role: 'user', content: 'List 5 use cases for Azion Functions.' }],
};
const stream: AsyncGenerator<AzionAIResult<AzionAIStreamResponse>> = streamChat(request, { debug: false });
for await (const chunk of stream) {
  if (chunk.data) {
    process.stdout.write(chunk.data.choices[0]?.delta.content || '');
  } else {
    console.error('Error:', chunk.error);
  }
}
process.stdout.write('\n');
```

The model writes a different answer on every run. This output is cut after the first use case:

```text
Sure, let me look into the documentation for use cases related to Azion Functions. I'll find some relevant examples for you...

  



  



  Here are 5 use cases for Azion Functions:

1. **Event-Driven Applications**: Create serverless applications that respond to events in real time, enabling ultra-low latency and high scalability. Functions can be reused across different applications and configured with environment variables.
…
```

---

## Errors

A failed call returns an `Error` in `error`. Read its text from `error.message`.

| Message                   | Cause                               | What to do                                                                                                               |
| ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `HTTP error! status: 403` | The Azion AI API refused the token. | Use a valid [personal token](/en/documentation/fundamentals/personal-tokens/) in `AZION_TOKEN` or in the client `token`. |

---

## Types

The module exports these types. Import them with `import type`.

### AzionAIClient

The client that [createClient](#createclient) returns.

| Method       | Arguments                                                 | Returns                                                |
| ------------ | --------------------------------------------------------- | ------------------------------------------------------ |
| `chat`       | `request: AzionAIRequest`, `options?: AzionClientOptions` | `Promise<AzionAIResult<AzionAIResponse>>`              |
| `streamChat` | `request: AzionAIRequest`, `options?: AzionClientOptions` | `AsyncGenerator<AzionAIResult<AzionAIStreamResponse>>` |

### AzionClientOptions

Request options that `chat` and `streamChat` take in `options`, and [createClient](#createclient) takes for all its calls.

| Property | Type      | Required | Description                                                                             |
| -------- | --------- | -------- | --------------------------------------------------------------------------------------- |
| `debug`  | `boolean` | No       | Prints the whole response object, or every chunk object of a stream, before the answer. |
| `force`  | `boolean` | No       | —                                                                                       |

### AzionAIRequest

The conversation that `chat` and `streamChat` send.

| Property   | Type                                  | Required | Description                                 |
| ---------- | ------------------------------------- | -------- | ------------------------------------------- |
| `messages` | [`AzionAIMessage[]`](#azionaimessage) | Yes      | The messages of the conversation, in order. |
| `azion`    | [`AzionAIConfig`](#azionaiconfig)     | No       | —                                           |
| `stream`   | `boolean`                             | No       | —                                           |

### AzionAIMessage

One message of the conversation.

| Property  | Type                                | Required | Description                |
| --------- | ----------------------------------- | -------- | -------------------------- |
| `role`    | `'system' \| 'user' \| 'assistant'` | Yes      | The author of the message. |
| `content` | `string`                            | Yes      | The text of the message.   |

### AzionAIConfig

The settings a request carries in `azion`. Every field is an optional string.

```typescript
interface AzionAIConfig {
  session_id?: string;
  url?: string;
  app?: string;
  user_name?: string;
  client_id?: string;
  system_prompt?: string;
  user_prompt?: string;
}
```

### AzionAIResult

The envelope every call returns, and every chunk of a stream. For how to read it, refer to [Response envelope](#response-envelope).

| Property | Type            | Required | Description                                  |
| -------- | --------------- | -------- | -------------------------------------------- |
| `data`   | `T \| null`     | Yes      | The response, or `null` when the call fails. |
| `error`  | `Error \| null` | Yes      | The error, or `null` when the call succeeds. |

### AzionAIResponse

The response of [chat](#chat). The answer is in `choices[0].message.content`.

```typescript
interface AzionAIResponse {
  choices: {
    finish_reason: string;
    index: number;
    message: {
      content: string;
      role: string;
    };
    logprobs: null;
  }[];
  created: number;
  id: string;
  model: string;
  object: string;
  usage: {
    completion_tokens: number;
    prompt_tokens: number;
    total_tokens: number;
    completion_tokens_details: {
      reasoning_tokens: number;
    };
  };
}
```

### AzionAIStreamResponse

One chunk of [streamChat](#streamchat). The text of the chunk is in `choices[0].delta.content`.

```typescript
interface AzionAIStreamResponse {
  choices: {
    delta: {
      content?: string;
    };
    finish_reason: string | null;
    index: number;
    logprobs: null;
  }[];
  created: number;
  id: string;
  model: string;
  object: string;
  system_fingerprint: string;
}
```

---

## Related resources

- [Azion Lib](/en/documentation/devtools/azion-lib.md): The libraries Azion Lib ships and the package each one comes from.
- [Client](/en/documentation/devtools/azion-lib/client.md): One client that reaches the AI functions next to Storage, SQL, Purge, Domains, and Applications.
- [How Azion Lib works](/en/documentation/devtools/azion-lib/how-it-works.md): How the packages find your token, switch on debug output, and return their envelopes.
- [Personal tokens](/en/documentation/fundamentals/personal-tokens.md): Create the token that the AI functions send with each request.
