# OpenAI JavaScript / TypeScript

Use the official `openai` package in Node.js or server-side TypeScript. The SDK's
`chat.completions` API works with Aurora's base URL and token.

> Available Inference endpoint: `https://ai.aur.lu/v1` (Aurora).

## Install and prepare

In a Node.js project, install the SDK and set an [Aurora token](https://docs.aur.lu/docs/inference/getting-started):

```bash
npm install openai
export AURORA_API_TOKEN="<your-token>"
```

Use a Node.js version supported by the installed SDK. The example is an ES module
(`.mjs`), so no `package.json` module setting is required. Run this on the server;
do not expose the token in a browser bundle or a public environment variable.

## Send a request

Save as `aurora-chat.mjs` (the same code can be used in a TypeScript project):

```javascript
import OpenAI from 'openai';

const apiKey = process.env.AURORA_API_TOKEN;
if (!apiKey) throw new Error('Set AURORA_API_TOKEN before running this script');

const client = new OpenAI({
  baseURL: 'https://ai.aur.lu/v1',
  apiKey,
});

const response = await client.chat.completions.create({
  model: 'deepseek/deepseek-v4-flash',
  messages: [{ role: 'user', content: 'Say hello in one sentence.' }],
});

console.log(response.choices[0].message.content);
console.log(response.usage);
```

```bash
node aurora-chat.mjs
```

Expect a greeting and token usage. The SDK appends `/chat/completions` to the
base URL, which already includes `/v1`. Use the exact ID from the
[model catalog](https://docs.aur.lu/docs/inference/models-and-pricing), with no extra `openai/` prefix.

## Stream a response

Replace the request and output statements with:

```javascript
const stream = await client.chat.completions.create({
  model: 'deepseek/deepseek-v4-flash',
  messages: [{ role: 'user', content: 'Explain streaming in three sentences.' }],
  stream: true,
  stream_options: { include_usage: true },
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
  if (chunk.usage) console.log('\nUsage:', chunk.usage);
}
console.log();
```

Optional chaining handles chunks without a choice, including the final usage
chunk. In a web application, forward the text from your server to the browser
using your framework's streaming response support.

## Troubleshooting

- **Missing token:** Export it in the launching shell or set it as a server-side
  deployment secret. The example fails early instead of falling back to another key.
- **`404` on `/responses`:** Use `client.chat.completions.create`, not the
  Responses API shown in some OpenAI quick starts.
- **HTTP errors:** SDK errors extending `OpenAI.APIError` expose a `status` and
  error message. Inspect these without logging credentials.
- **Empty streamed chunks:** Some chunks contain metadata rather than text;
  keep the optional checks in the example.

See [shared troubleshooting](https://docs.aur.lu/docs/inference/integrations#troubleshooting) and the
[OpenAI Node SDK reference](https://github.com/openai/openai-node).
