1. How the pieces fit
n8n is the orchestrator, NormaHub is the model backend. A typical workflow: trigger (webhook, schedule, message) → HTTP Request to NormaHub → response handling → action (user reply, spreadsheet row, ticket). The key lives in n8n credentials, the model and max_tokens live in the request body, and the spend cap lives on the key in the dashboard.
Create a dedicated key for automations: background workflows run unattended, and a looping node with a shared key is the fastest way to zero the balance. Neither cloud nor self-hosted n8n needs a VPN. Russian version of this guide: Подключение n8n.
2. HTTP Request node
Create an HTTP Request node and configure it as follows. The auth type is Header Auth with the Authorization: Bearer YOUR_KEY header (store the value in credentials, not as plain text in the workflow). The body is JSON with model, messages, and max_tokens; inject text from the previous node with the {{ $json.text }} expression.
Method: POST
URL: https://api.normahub.cc/v1/chat/completions
Auth: Header Auth → Authorization: Bearer YOUR_API_KEY
Body JSON:
{
"model": "MODEL_ID",
"messages": [
{ "role": "system", "content": "Answer briefly and to the point." },
{ "role": "user", "content": "={{ $json.text }}" }
],
"max_tokens": 512
}Take the model ID exactly from the catalog: small cheap models for classification and drafts, flagships for hard reasoning. A system prompt sets the answer format and saves more tokens than long pleas in every message.
3. Reading the response and usage
The answer sits in choices[0].message.content, the spend in the same JSON's usage. Save usage to your own accounting table (Google Sheets, Postgres, a file): it is the only way to see what each workflow costs before the bill, not after.
// Model response in the next node:
{{ $json.choices[0].message.content }}
// Usage for cost tracking:
{{ $json.usage.prompt_tokens }} / {{ $json.usage.completion_tokens }}For dialogs, store history outside (a table, Redis, workflow memory) and pass a trimmed context in messages: n8n will not do it for you, and resending the full chat log on every call is the biggest cost driver. The pricing formula is in the token cost guide.
4. Errors and reliability
In the HTTP node settings, enable error handling and retries only for transient failures (429, 5xx): exponential backoff, 3–4 attempts max. Route permanent 400, 401, 402, and 403 into a separate branch that notifies you instead of an endless retry. The full code table is in the errors guide.
Typical failure causes: 401 — the credential key expired or was revoked; 402 — balance or spend limit; 413 — a huge log landed in messages; 503 — the model is temporarily unavailable, where a fallback to a spare model via a second HTTP node fits.
5. Self-hosting and security
On your own server, keep the key in the container's environment variables and reference it with an expression — then a workflow export carries no secret. Restrict access to the n8n editor (any editor otherwise sees credentials), enable credential encryption with an env key, and back up workflows to git without secrets.
# Self-hosted n8n: keep the key in n8n credentials, not in workflow code
# Container environment variables:
NORMAHUB_API_KEY=your_api_key
# In the HTTP node, use Header Auth with the expression:
# Bearer {{ $env.NORMAHUB_API_KEY }}Final checklist before enabling the schedule: a dedicated key with a limit, max_tokens everywhere, input deduplication, an error branch with alerts, usage accounting. When errors appear, check the balance and available models in the dashboard.