markdown
1. Environment
## 1. Environment Store the AR24 API key on the server only. ```env AR24_API_KEY=sk_live_... AR24_BASE_URL=https://www.ar24.studio/v1 ``` Do not expose `AR24_API_KEY` in browser/client code.
Full copy-ready markdown for developers connecting a chatbot to AR24. Use this for apps, websites, backend routes, and OpenAI-compatible SDKs.
## 1. Environment Store the AR24 API key on the server only. ```env AR24_API_KEY=sk_live_... AR24_BASE_URL=https://www.ar24.studio/v1 ``` Do not expose `AR24_API_KEY` in browser/client code.
## 2. Smoke test with cURL
```bash
curl -X POST https://www.ar24.studio/v1/chat/completions \
-H "Authorization: Bearer $AR24_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [
{ "role": "user", "content": "Reply with exactly: AR24_CHATBOT_OK" }
]
}'
```
If the response contains `AR24_CHATBOT_OK`, the API key and model are working.## 3. JavaScript / Node.js
```ts
const response = await fetch("https://www.ar24.studio/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AR24_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-5.5",
messages: [
{ role: "system", content: "You are a helpful chatbot." },
{ role: "user", content: "Write a short welcome message." },
],
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error?.message ?? "AR24 request failed");
}
const data = await response.json();
const text = data.choices?.[0]?.message?.content ?? "";
console.log(text);
```## 4. Next.js API route
Use this when your frontend chatbot needs to call AR24 through your own backend.
```ts
// src/app/api/chat/route.ts
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const { message } = await request.json();
const response = await fetch("https://www.ar24.studio/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AR24_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-5.5",
messages: [
{ role: "system", content: "You are a helpful product support chatbot." },
{ role: "user", content: message },
],
}),
});
const payload = await response.json();
if (!response.ok) {
return NextResponse.json(payload, { status: response.status });
}
return NextResponse.json({
answer: payload.choices?.[0]?.message?.content ?? "",
usage: payload.usage,
});
}
```
Frontend calls your own route:
```ts
await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: "How does pricing work?" }),
});
```## 5. Python
```py
import os
import requests
response = requests.post(
"https://www.ar24.studio/v1/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['AR24_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "gpt-5.5",
"messages": [
{"role": "system", "content": "You are a helpful chatbot."},
{"role": "user", "content": "Write a short welcome message."},
],
},
timeout=120,
)
response.raise_for_status()
data = response.json()
print(data["choices"][0]["message"]["content"])
```## 6. OpenAI-compatible SDK
Use this if your framework already supports an OpenAI-compatible client with a custom base URL.
```ts
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AR24_API_KEY,
baseURL: "https://www.ar24.studio/v1",
});
const completion = await client.chat.completions.create({
model: "gpt-5.5",
messages: [
{ role: "system", content: "You are a helpful chatbot." },
{ role: "user", content: "Create a product launch checklist." },
],
});
console.log(completion.choices[0]?.message?.content);
```
If your SDK has a different base URL option name, set it to `https://www.ar24.studio/v1`.## 7. Errors
AR24 returns errors in this shape:
```json
{
"error": {
"code": "invalid_request",
"message": "Invalid request",
"request_id": "optional-debug-id"
}
}
```
Important codes:
- `unauthorized`: missing or invalid API key.
- `forbidden`: inactive API key or customer.
- `invalid_request`: invalid JSON, unsupported model, or streaming requested before it is enabled.
- `rate_limited`: upstream or customer rate limit reached. Respect `Retry-After`.
- `insufficient_credit`: prepaid balance is too low.
- `upstream_error`: provider failed or timed out.## 8. Usage and billing
Current model: `gpt-5.5`
Pricing:
- Input: 20.000 VND per 1M tokens.
- Output: 80.000 VND per 1M tokens.
Formula:
```txt
cost = input_tokens / 1,000,000 * input_price
+ output_tokens / 1,000,000 * output_price
```
Read usage from the response:
```json
{
"usage": {
"prompt_tokens": 318,
"completion_tokens": 41,
"total_tokens": 359
}
}
```