Note: I’ve replaced my NyxID host with
<your-nyxid-host>throughout this post — the forum’s link scanner rejects the actual hosted domain. If you self-host, it’s your own URL. If you want the hosted early-access URL, it’s in the GitHub README linked at the bottom.
Four APIs (Gemini, TwitterAPI, Google Sheets, Telegram Bot), four different auth styles, one Header Auth credential in n8n. An open-source gateway called NyxID (I used their hosted early-access — invite code below) sits in front and injects the right auth per call. The setup took ~15 min because I had Claude Code run the commands — I just approved.
n8n ─┐
Claude─┼──(one key: X-API-Key: nyx_xxx)──► NyxID Proxy ──► Gemini / Twitter / Sheets / Telegram
curl ─┘ (injects correct auth per service)
Bonus: the same NyxID key works unchanged in Claude Code, Cursor, or a curl script — configure auth once, reuse everywhere.
The problem
My workflow pulls AI news from a dozen RSS feeds, fetches tweets from ~15 Chinese AI influencers, scores/translates/classifies everything with Gemini, writes the result to a Google Sheet, and sends daily digests to a Telegram group. Four APIs, four auth patterns:
-
Gemini — header
x-goog-api-key: <key> -
TwitterAPI — header
x-api-key: <key> -
Google Sheets — OAuth2 bearer token (refresh_token dance)
-
Telegram Bot — path-based auth (token goes into the URL:
/bot<token>/sendMessage)
In n8n that’s four separate credentials, four rotation paths. Sheets is worst — every teammate who touches the workflow has to re-do OAuth into their own n8n credential. Telegram sits in a different node class with its own credential type. And if I also want to call the same APIs from Claude Code or curl, I have to set up auth all over again in each place.
What NyxID is
I used NyxID — an open-source agent connectivity gateway (link at the bottom). It has a hosted early-access offer (invite code below) and a self-host docker-compose option; I went with hosted because I didn’t need anything running on my own box and wanted to be using it in minutes. Two properties matter for this setup: it injects per-service auth at proxy time (so n8n only holds one key), and its CLI is built for AI agents to drive, so Claude Code wired the whole thing up end-to-end without me copy-pasting tokens into chat.
Token handling: I kept each downstream token in a local file (
chmod 600) and had Claude Code read them via--credential-env VAR_NAME— raw values never hit the chat transcript, shell history, or command line.
Setup (what I actually did)
1. Registered for NyxID (hosted) and logged the CLI in
Signed up on the hosted NyxID console (URL in the GitHub README at the bottom), entered the invite code, signed in with Google.
Once logged in, the Dashboard → AI Setup tab gives you a paste-ready install snippet for each coding agent (Claude Code, Cursor, Codex, etc.). I picked the Claude Code tab, copied the one-liner, and pasted it into Claude Code. It installed the nyxid CLI (handles Rust toolchain + PATH automatically), logged me in against the hosted instance, and loaded the NyxID skill so Claude Code knows how to use NyxID’s commands in every future session:
# install snippet (from the NyxID dashboard's AI Setup tab)
bash -c "$(curl -fsSL <install-script-url-from-dashboard>)"
# then in a new terminal:
nyxid login --base-url https://<your-nyxid-host>
nyxid ai-setup install --tool claude-code
~3 minutes total. From here on, every nyxid ... command below (the ones Claude Code ran on my approval) talks to the hosted NyxID at <your-nyxid-host>.
2. Register the 3 API-key services (Gemini, TwitterAPI, Telegram)
Rather than reading NyxID’s catalog myself, I just asked Claude Code: “I’m building a workflow that uses Gemini, Twitter data, and Telegram — what do I need to register in NyxID?” It checked the catalog, came back with two catalog slugs (llm-google-ai and api-telegram-bot) and one that wasn’t in the catalog: TwitterAPI is a third-party scraper API, so it needs to be registered as a custom endpoint with --custom. It told me exactly which chmod 600 file to put each token in.
I dropped each token into its file in my own terminal (~/.gemini_key, ~/.twitterapi_key, ~/.tg_token), then told Claude Code “done.” From there it ran the whole loop on its own: nyxid service add for each (reading values from env vars so raw tokens never hit the command line), a quick proxy test call per service to confirm each one responded 2xx, and only after all three tests passed did it shred -u the local token files.
# Gemini — catalog service
GEMINI_KEY="$(cat ~/.gemini_key)" \
nyxid service add llm-google-ai --credential-env GEMINI_KEY --label "Gemini AI"
# TwitterAPI — custom endpoint (not in catalog)
TWAPI_KEY="$(cat ~/.twitterapi_key)" \
nyxid service add --custom \
--label "TwitterAPI" \
--endpoint-url "<twitterapi-endpoint>" \
--auth-method header \
--auth-key-name "x-api-key" \
--credential-env TWAPI_KEY
# Telegram Bot — catalog service
TELEGRAM_BOT_TOKEN="$(cat ~/.tg_token)" \
nyxid service add api-telegram-bot --credential-env TELEGRAM_BOT_TOKEN --label "Telegram Bot"
Got back 3 service identifiers (gemini-ai-6yd7, twitterapi-io-jb13, api-telegram-bot) — the twitterapi-io-jb13 is an auto-generated slug for the custom endpoint. Claude Code sed-replaced all three into my workflow JSON placeholders automatically.
3. Register Google Sheets (OAuth2 — the hard one)
OAuth needed a Google Cloud OAuth client. The Cloud Console steps Claude Code couldn’t do for me:
-
Create an OAuth 2.0 Client ID (Web application)
-
Add
https://<your-nyxid-host>/api/v1/providers/callbackto Authorized redirect URIs -
Enable Google Sheets API + Google Drive API
-
On OAuth consent screen → Data access → ADD OR REMOVE SCOPES, add the Google Sheets scope (
auth/spreadsheets). Do not skip this. If you pass scope only on the CLI, Google silently drops it and your token comes back without Sheets permission — you getACCESS_TOKEN_SCOPE_INSUFFICIENTat runtime and spend an hour wondering why. -
Add your gmail to Test Users
Put client_id / client_secret in ~/.gc_id / ~/.gc_secret. Claude Code then ran:
GC_ID="$(cat ~/.gc_id)" GC_SECRET="$(cat ~/.gc_secret)" \
nyxid service credentials api-google --client-id-env GC_ID --client-secret-env GC_SECRET
nyxid service add api-google --oauth \
--scope "<google-sheets-scope-url>"
--label "Google Sheets"
# CLI prints a URL; I opened it, logged in, clicked Allow
Catalog default for Google points at the generic googleapis host, but Sheets lives on the sheets. subdomain. Claude Code caught the 404 on the first test call and ran nyxid service update <id> --endpoint-url <sheets-subdomain>. It verified an end-to-end write through the proxy before touching n8n — row appeared in the sheet.
4. Create the n8n credential
Asked Claude Code to create a per-workflow scoped NyxID API key (scope proxy only, allowed services = the 4 above). It wrote the new key to ~/.nyx_key (chmod 600) without printing the value to chat. I read it into clipboard from my own Terminal:
cat ~/.nyx_key | pbcopy # macOS
# or: xclip -sel c < ~/.nyx_key # Linux
# or: Get-Content ~/.nyx_key | Set-Clipboard # Windows PowerShell
Then n8n → Credentials → New → Header Auth (Name NyxID API Key, Header Name X-API-Key), paste, save, shred -u ~/.nyx_key.
Per-workflow scope matters: if this key leaks, it can only hit the 4 APIs this workflow uses. Can’t touch the other services I have in NyxID.
5. Import the patched workflow JSON
Because Claude Code had been sed-replacing slugs and the Sheet ID into the workflow JSON as it went, every URL already had the right NyxID host, slugs, and Sheet ID baked in. Inside n8n I only clicked one HTTP node’s credential dropdown and picked “NyxID API Key” — every other HTTP node auto-matched by credential name.
Total hands-on time: ~15 min, mostly waiting for OAuth browser redirects.
How the URLs look in n8n HTTP nodes
Proxy path template (hosted — if you self-host, replace the host with yours):
https://<your-nyxid-host>/api/v1/proxy/s/{service-slug}/{downstream-api-path}
Same X-API-Key: nyx_xxx header on every call. Different slugs route to different downstream APIs, NyxID injects the right auth for each:
# Gemini — no x-goog-api-key needed; NyxID injects it
POST https://<your-nyxid-host>/api/v1/proxy/s/gemini-ai-6yd7/models/gemini-2.5-flash:generateContent
# TwitterAPI — no x-api-key needed; NyxID injects it
GET https://<your-nyxid-host>/api/v1/proxy/s/twitterapi-io-jb13/twitter/user/last_tweets?userName=someone
# Google Sheets — no Authorization header; NyxID refreshes + injects OAuth token
POST https://<your-nyxid-host>/api/v1/proxy/s/api-google-3/v4/spreadsheets/<sheet-id>/values/ai_briefing!A:H:append
# Telegram — note: no bot<token>/ in the path; NyxID prepends it before forwarding.
POST https://<your-nyxid-host>/api/v1/proxy/s/api-telegram-bot/sendMessage
Four URLs, one n8n credential. Four auth patterns handled transparently.
Before vs After
| Before | After | |
|---|---|---|
| Credentials in n8n | 4 (Sheets via OAuth2, Telegram via native node) | 1 (NyxID Header Auth) |
| Google Sheets authorization | Each teammate re-does OAuth in their own n8n | NyxID authorizes once, every workflow reuses the token |
| Telegram Bot token | Lives in n8n’s Telegram credential | Lives in NyxID; n8n never sees it |
| Key rotation | Update each credential manually | Rotate the credential once in NyxID; every workflow keeps working |
| Auth complexity | 4 different patterns (2 headers + OAuth bearer + URL-path token) | One X-API-Key, NyxID handles the rest |
| Reuse outside n8n | No (locked in n8n’s DB) | Same NyxID key works in Claude Code, Cursor, curl |
| Credential leak blast radius | Full API account | Per-workflow scoped — only the 4 APIs this workflow uses |
What the workflow actually does
Daily at 08:00:
-
Pull 13 RSS feeds (The Verge, TechCrunch, OpenAI Blog, DeepMind, WIRED, 404 Media, MIT Tech Review, etc.) via n8n’s RSS node
-
Pull last 24h of tweets from ~15 Chinese AI influencers via TwitterAPI (through NyxID)
-
Gemini translates/summarizes (if English), classifies into
Product Launch/Research & Blog/Other, extracts a Chinese title (through NyxID) -
Global dedup by content signature
-
Pick top-10 most valuable tweets with another Gemini call
-
Append every processed row to a Google Sheet (through NyxID, scoped to
ai_briefing!A:H) -
Send three formatted digests (general news / deep-dives / Top-10 tweets) to a Telegram group (through NyxID, each split into ≤3800-char chunks to stay under Telegram’s 4096 limit)
71 nodes, 4 NyxID services, 1 credential. First run wrote ~150 rows and pushed three Telegram messages.
If you want to try this
Hosted (what I used, recommended): invite code NYX-FASQWSID, capped at 20 users. Sign-up URL is in the GitHub README below. Sign in with Google / GitHub / Apple, install the CLI (or just use the web console), and you can run through the exact flow above. No Docker, no local setup — you’re usable in minutes.
Self-host if you prefer: NyxID (search: ChronoAIProject/NyxID on GitHub) — open-source, ~2 min with docker-compose. The AI-assisted install prompt in the README drives the whole thing end-to-end if you’re in Claude Code / Cursor. Better if you want everything on your own box or need to reach services on a private network.
A few other things I haven’t covered here but NyxID also supports, in case they’re useful to you: wrapping the same registered services as an MCP server so a coding agent can hit them directly, and letting a cloud-hosted agent reach localhost services through the gateway (via credential nodes). Happy to write those up as follow-ups if there’s interest.
Happy to share the full workflow JSON (71 nodes, all 4 APIs wired through NyxID) if anyone wants it — drop a comment.
Questions / critiques welcome — especially if you try it and hit something weird, or if you’ve solved the “4 credentials → 1” problem a different way.
