Getting started
From the API key to the model's first response, with ready-to-run code in three languages.
Updated on Aug 09, 2026
From the key to a model's first response. If you already use the OpenAI API, it is a two-line change; if you are starting from scratch, you can be done in five minutes.
- An account at platform.hinow.ai and an API key
- Node.js 18+, Python 3.9+, PHP 8+ or any HTTP client
- Nothing else: there is no dedicated SDK to install
Set up your access
Generate an API key or sign in to the platform to create your account.
The HiNow API speaks the same protocol as the OpenAI API. Its official SDKs work without adaptation — you only change the base URL and the key:
| Value | |
|---|---|
| Base URL | https://api.hinow.ai/v1 |
| Header | Authorization: Bearer hi_... |
| Chat endpoint | POST https://api.hinow.ai/v1/chat/completions |
| Model name | hinow/himax, hinow/hinova or hinow/higenesis |
The hinow/ prefix is part of the name
Sending higenesis instead of hinow/higenesis returns 404 model_not_found. It is the most common mistake when starting out, and the message does not make it obvious what is missing.
# Nada a instalar: o fetch já vem no Node 18+.
mkdir meu-app && cd meu-app
echo '{ "type": "module" }' > package.json
# Se preferir o SDK da OpenAI, ele também funciona:
# npm install openaimkdir meu-app && cd meu-app
python3 -m venv .venv && source .venv/bin/activate
# O SDK oficial da OpenAI: você só aponta o base_url para a HiNow.
pip install openaimkdir meu-app && cd meu-app
# Nada a instalar: usamos a extensão cURL, habilitada por padrão.
php -m | grep curlExport the key and run the file. It is complete — nothing is missing except your key.
export HINOW_API_KEY="hi_sua_chave_aqui"const API = 'https://api.hinow.ai/v1/chat/completions';
const KEY = process.env.HINOW_API_KEY;
async function call(body) {
const response = await fetch(API, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${KEY}` },
body: JSON.stringify(body),
});
// Always read the status before touching the payload. Without this, a 401
// shows up later as "cannot read properties of undefined".
if (!response.ok) {
throw new Error(`HiNow ${response.status}: ${await response.text()}`);
}
return response.json();
}
const data = await call({
model: 'hinow/higenesis',
messages: [{ role: 'user', content: 'Say hello in one short sentence.' }],
});
console.log(data.choices[0].message.content);import os
from openai import OpenAI
# The HiNow API speaks the OpenAI protocol, so the official SDK works as is.
# The only change is base_url.
client = OpenAI(
api_key=os.environ["HINOW_API_KEY"],
base_url="https://api.hinow.ai/v1",
)
response = client.chat.completions.create(
model="hinow/higenesis",
messages=[{"role": "user", "content": "Say hello in one short sentence."}],
)
print(response.choices[0].message.content)<?php
$API = 'https://api.hinow.ai/v1/chat/completions';
$KEY = getenv('HINOW_API_KEY');
function call(array $body): array {
global $API, $KEY;
$ch = curl_init($API);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', "Authorization: Bearer $KEY"],
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_TIMEOUT => 180,
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Check the status before decoding. Without this, a 401 shows up later as
// "trying to access array offset on null".
if ($status !== 200) {
throw new RuntimeException("HiNow $status: $raw");
}
return json_decode($raw, true);
}
$data = call([
'model' => 'hinow/higenesis',
'messages' => [['role' => 'user', 'content' => 'Say hello in one short sentence.']],
]);
echo $data['choices'][0]['message']['content'], PHP_EOL;If it worked, you get a short sentence like this one:
Hello! How can I help you today?The errors the API returns, what each one means and what to do.
| Code | What the API responds | What fixes it |
|---|---|---|
401 | AUTH_MISSING | The request went out without the Authorization header |
401 | AUTH_INVALID_FORMAT | The header exists but is empty or malformed. Use Bearer followed by the key |
401 | AUTH_TOKEN_INVALID | The key does not exist or was revoked. Generate another one in the dashboard |
404 | model_not_found | Check the prefix: it is hinow/higenesis, not higenesis |
400 | messages is required | The body was sent without the messages array, or it came in empty |
429 | usage limit | Reduce the call frequency, or wait a few seconds and try again |
Check the status before reading the response
If your code jumps straight to choices[0], a 401 error shows up as "cannot read properties of undefined" and you will look for the problem in the wrong place. The examples above check the status first — keep it that way.
In a chat interface, waiting for the whole response feels slow even when it is not. With stream: true the first words appear in a fraction of the total time, and the perception changes completely.
The response arrives as data: lines, each carrying a piece of the text, until a final data: [DONE].
const response = await fetch('https://api.hinow.ai/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.HINOW_API_KEY}`,
},
body: JSON.stringify({
model: 'hinow/hinova',
messages: [{ role: 'user', content: 'List three uses for an LLM, one line each.' }],
stream: true,
}),
});
if (!response.ok) throw new Error(`HiNow ${response.status}: ${await response.text()}`);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop(); // the last piece may be an incomplete line
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const payload = line.slice(6).trim();
if (payload === '[DONE]') continue;
const chunk = JSON.parse(payload);
const piece = chunk.choices[0]?.delta?.content;
if (piece) process.stdout.write(piece);
}
}
console.log();import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["HINOW_API_KEY"], base_url="https://api.hinow.ai/v1")
stream = client.chat.completions.create(
model="hinow/hinova",
messages=[{"role": "user", "content": "List three uses for an LLM, one line each."}],
stream=True,
)
for chunk in stream:
piece = chunk.choices[0].delta.content
if piece:
print(piece, end="", flush=True)
print()<?php
$ch = curl_init('https://api.hinow.ai/v1/chat/completions');
$buffer = '';
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . getenv('HINOW_API_KEY'),
],
CURLOPT_POSTFIELDS => json_encode([
'model' => 'hinow/hinova',
'messages' => [['role' => 'user', 'content' => 'List three uses for an LLM, one line each.']],
'stream' => true,
]),
// cURL hands you whatever arrived, which may cut a line in half — so keep
// the leftover in a buffer and only parse complete lines.
CURLOPT_WRITEFUNCTION => function ($ch, $data) use (&$buffer) {
$buffer .= $data;
while (($pos = strpos($buffer, "\n")) !== false) {
$line = trim(substr($buffer, 0, $pos));
$buffer = substr($buffer, $pos + 1);
if (!str_starts_with($line, 'data: ')) continue;
$payload = trim(substr($line, 6));
if ($payload === '[DONE]') continue;
$chunk = json_decode($payload, true);
echo $chunk['choices'][0]['delta']['content'] ?? '';
}
return strlen($data);
},
]);
curl_exec($ch);
curl_close($ch);
echo PHP_EOL;Watch out for the line cut in half
Each chunk that arrives from the network can end in the middle of a line. The Node and PHP examples keep the leftover in a buffer and only process complete lines — without that, JSON.parse breaks intermittently, and it is the kind of bug that only shows up in production.

