API reference
A small, strict HTTP surface
Base URL and authentication
There are two base URLs. The dedicated API endpoint is https://api.nordai.id/v1 — use this for external clients and SDKs. The website alias https://nordai.id/api is identical (it proxies to the same service) and exists so the site and CLI always work even if the dedicated hostname is blocked by a network.
https://api.nordai.id/v1Send a customer API key as a bearer token. Browser sessions use cookies and are handled by the website.
Authorization: Bearer nord_sk_…Keys are shown once at creation and stored as a SHA-256 hash. A key can be restricted to specific model ids and given its own per-minute and monthly limits.
The dedicated endpoint runs behind Cloudflare (proxied) with a Let's Encrypt certificate and SSE support, so streaming responses work as-is. Model ids come from GET /v1/me/models (for your account) or the public GET /v1/models catalogue.
Connect your client
curl
curl -N https://api.nordai.id/v1/chat/completions \
-H "Authorization: Bearer $NORDAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"nordai-deepsek-4-1-flash","messages":[{"role":"user","content":"hi"}]}'Vercel AI SDK
import { createOpenAI } from "@ai-sdk/openai";
const nordai = createOpenAI({
baseURL: "https://api.nordai.id/v1",
apiKey: process.env.NORDAI_API_KEY,
});
const result = await streamText({
model: nordai("nordai-deepsek-4-1-flash"),
prompt: "Explain this error",
});Cursor / Cline / any OpenAI-compatible client
Set Base URL to https://api.nordai.id/v1, API key to your nord_sk_… key, and pick a model id from the catalogue.
Base URL: https://api.nordai.id/v1 API Key: nord_sk_… Model: nordai-deepsek-4-1-flash
Chat completions
The endpoint is OpenAI-compatible. Set stream: true for SSE. The gateway rewrites model to an approved id, caps max_tokens to your plan, and forwards tool definitions unchanged.
curl -N https://api.nordai.id/v1/chat/completions \
-H "Authorization: Bearer $NORDAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<id from /v1/me/models>",
"stream": true,
"messages": [{"role": "user", "content": "Explain this error"}]
}'Response headers include X-NordAI-Request-Id, X-NordAI-Model (the model that actually served the request) and your current rate-limit counters.
Idempotency
Send Idempotency-Key to make retries safe. A repeated key returns 409 duplicate_request and is not counted twice.
Errors
{
"error": {
"code": "daily_limit_reached",
"message": "Daily allowance reached (25 of 25 requests on NordAI Free). Access resets on 2 Nov 2026 00:00 WIB.",
"request_id": "b1f0c6a2d3e4f5a6",
"details": { "reset_at": "2026-11-01T17:00:00Z", "limit": 25, "used": 25 }
}
}401invalid or revoked credential.403model not allowed for the plan or key, unverified email, support-only action.409duplicate idempotency key or illegal state transition.429rate, concurrency or quota limit — checkdetails.reset_at.502/503/504upstream router failure, timeout or maintenance.
Usage data
GET /v1/usage/summary returns a zero-filled daily series, per-model aggregates and your recent requests. Token counts appear only when the upstream reported them; they are never estimated.
GET /v1/gateway/limits returns the exact plan values and remaining allowance, which is what the CLI prints for /usage.