Issue a one-time code that links a Telegram chat to this tenant
const url = 'https://api.flotera.com/api/v1/notifications/telegram/link';const options = { method: 'POST', headers: {cookie: '__Host-erm_session=<__Host-erm_session>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.flotera.com/api/v1/notifications/telegram/link \ --cookie __Host-erm_session=<__Host-erm_session>Returns a short-lived code the owner sends to the bot. Whoever redeems the code receives the tenant’s whole alert stream, so the code is a bearer credential: it is stored only as a peppered hash, it is never logged, and it is issued to a signed-in session only. An API token is rejected with 403 on purpose — a token holder must not be able to redirect notifications. 503 means the bot is not configured, so a code would have nobody to redeem it.
Authorizations
Section titled “Authorizations”Responses
Section titled “Responses”Code issued. This is the only place the plaintext exists.
A one-time link code. The plaintext exists only in this response — the server keeps a peppered hash. Ten body characters over a 32-symbol alphabet give 2^50 combinations; the bot stays silent on a wrong code so it cannot be used as a brute-force oracle.
object
Alphabet excludes I/O/0/1 — the code is read off a screen and dictated aloud.
RFC 3339 UTC with microsecond precision.
Bot handle without @. Served by the API rather than baked into the panel bundle: staging and production use different bots.
Opens the bot with the code already filled in.
Example
{ "code": "ERM-K3M7Q-XB29T", "expires_at": "2026-07-25T10:15:30.123456Z", "bot_username": "ErmeonBot", "deep_link": "https://t.me/ErmeonBot?start=ERMK3M7QXB29T"}Missing/invalid credentials (code=unauthorized).
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}Authenticated but not permitted. code=forbidden — role/scope mismatch; code=feature_not_entitled — the plan does not include the capability; code=account_frozen — the account is frozen and this operation is declared x-ermeon-frozen: deny. The three are deliberately distinct: only the last one is fixed by a top-up (13 §5.6).
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}Rate limit exceeded (code=rate_limited).
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}Headers
Section titled “Headers”Seconds to wait before retrying.
A dependency the endpoint needs is not configured or is temporarily unavailable (code=unavailable). The rest of the API keeps working — an absent external integration must not take the service down.
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}