Heartbeat Secret
What the clb_live_… secret is, where to find it, how to rotate it, and how it's stored.
The heartbeat secret is what proves your bot's heartbeats are actually from your bot and not from someone else pretending to be you. It looks like:
clb_live_a8f3k2x9p1m7q4r6t5v8w2y4z6c8e1f3You pass it as a Bearer token on every heartbeat POST. Without the right secret, CloudLine rejects the heartbeat with a 401 Unauthorized and your dashboard status stays grey.
IMPORTANT
This is NOT your Discord bot token. CloudLine never sees, stores, or asks for your Discord bot token — that lives only in your bot's environment variables and travels only between your bot and Discord. The clb_live_… secret is a separate credential that exists solely to authenticate heartbeat traffic from your bot to CloudLine. The two are independent: rotating one doesn't affect the other.
Where to find it
The secret lives in your dashboard under Settings → Heartbeat secret on each bot's detail page. It's visible once after creation; if you lose it, regenerate rather than try to recover the old one (CloudLine itself does not store it in plaintext after first issue).
The SDK quick-paste snippets on the Heartbeat tab already include the current secret inline — copy from there if you just created the bot.
How it's stored
- Server-side: in your D1 database, on the bot's row. Not exposed via any read endpoint after creation.
- Bot-side: you put it in an environment variable (e.g.
CLOUDLINE_SECRET) and pass it to the SDK at runtime. Never commit it to a public repo.
The dashboard also stores other secrets per-user (Discord webhook URLs, etc.) — those use AES-256-GCM at rest with a per-user encryption key.
CAUTION
Treat the secret like a password. Anyone who has it can post heartbeats as your bot. They can't read your data with it — but they could send fake heartbeats to make CloudLine think your bot is online when it isn't.
Storing it safely
- Local development: use a
.envfile that is in your.gitignore. - Production: use your host's secrets manager (Railway / Fly.io / Heroku environment variables; AWS Secrets Manager; Doppler; 1Password; etc.). Do not check secrets into source control.
- Docker: pass via
--envor a secret-mount, not viaARG(which lands in the image layer). - PM2 / systemd: load from a
.envnext to the service unit, with file permissions restricted to the service user.
Rotation
If you suspect the secret has leaked (committed to a public repo, shared in a screenshot, etc.), rotate it:
- Go to the bot's Settings → Heartbeat secret page.
- Click Regenerate secret.
- Copy the new
clb_live_…value. - Update your bot's environment variable.
- Restart your bot.
The old secret is invalidated immediately server-side. Heartbeats from the old secret start returning 401 within a few seconds (the BotMonitor cache is force-invalidated on rotation; the next heartbeat lazy-loads the new value from D1).
IMPORTANT
There is a 60-second cooldown between regenerations on the same bot. If you click Regenerate twice in quick succession, the second call returns 429 Too soon with a Retry-After header. This prevents a hijacked session from rapidly cycling secrets and locking you out.
What happens if you use a wrong secret
The heartbeat POST returns 401 Unauthorized. The SDK does not retry on 401 — retrying a bad credential just burns rate-limit quota without ever succeeding. Instead, it logs an error once:
CloudLine: heartbeat rejected (401) — check botId/secret…and the heartbeat loop continues at the normal interval, each one failing with 401 until you fix it. Your dashboard status will stay grey because no successful heartbeat is landing.
If you see this in your logs, the four most common causes are:
- You rotated the secret on the dashboard and didn't redeploy your bot.
- The env var name is wrong (e.g.
CLOUDLINE_TOKENvsCLOUDLINE_SECRET). - You pasted the bot ID into the secret slot, or vice versa.
- Your
.envisn't being loaded by your runtime (PM2 / Docker / systemd often strip it). Set the env var explicitly in your process manager.
Multiple bots, multiple secrets
Each bot has its own secret. If you monitor several bots from one CloudLine account, generate one secret per bot — don't reuse. The secrets are 32-byte cryptographic randoms and there's no operational reason to share them across bots.
Programmatic rotation
The endpoint is:
POST /api/bots/{botId}/heartbeat/regenerate
Cookie: <your session cookie>Returns { "secret": "clb_live_..." } on success, 429 Too Soon during the 60-second cooldown. Session-authenticated only — there is no API-token equivalent for the rotation flow. Rotation from CI / scripts would require a logged-in browser session.