Bot: Registrations
Section titled “Bot: Registrations”Register a channel bot into a container, start and stop its long-polling worker, manage its channel surface (commands and profile), read and set its admission policy, audit what it has done, and revoke chat-user sessions or every token lineage at once.
Every operation on this page is a management-class endpoint. Calls require Authorization: Bearer <your own Hoody token>, and the calling account must own the container the kit runs in. The channel bot token is sent once in the register body over HTTPS, verified with the channel, stored encrypted on the container, and never echoed back or logged. A new registration is created stopped; run hoody bot start <registration> to begin polling.
Registration lifecycle
Section titled “Registration lifecycle”Use these four endpoints to create a registration, list what you have, read one, and delete it. The channel bot token is sent once in the register body; what comes back is the registration without its token.
GET /api/v1/bot/registrations
Section titled “GET /api/v1/bot/registrations”List the registrations owned by the calling account.
This endpoint takes no parameters.
curl -X GET \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.list();hoody bot list{ "registrations": [ { "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "running", "created_at": 1700000000000, "updated_at": 1700000001000, "last_error_code": null, "last_error_at": null } ]}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
POST /api/v1/bot/registrations
Section titled “POST /api/v1/bot/registrations”The channel bot token is read on the client side and sent in this body over HTTPS. It is verified with the channel, stored encrypted and never echoed. What comes back is the registration without its token.
Request body
Section titled “Request body”| Name | Type | Required | Description |
|---|---|---|---|
channel | string | Yes | The channel the bot is registered with. The only supported value is telegram. |
token | string | Yes | The channel bot token. Read on the client side and sent over HTTPS; the kit verifies it with the channel, encrypts it on the container, and never echoes it. |
label | string | No | A short operator label (up to 64 characters). |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations" \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "channel": "telegram", "token": "7123456789:AAF-AAaBcDeFgHiJkLmNoPqRsTuVwXyZ", "label": "AcmeBot" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.create({ channel: 'telegram', token: '7123456789:AAF-AAaBcDeFgHiJkLmNoPqRsTuVwXyZ', label: 'AcmeBot'});hoody bot create --channel telegram --token "7123456789:AAF-AAaBcDeFgHiJkLmNoPqRsTuVwXyZ" --label "AcmeBot"{ "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "stopped", "created_at": 1700000000000, "updated_at": 1700000000000, "last_error_code": null, "last_error_at": null}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
invalid_body | 400 | Invalid body | The request body could not be parsed or fails schema validation. | Compare the body with the documented schema and resend. |
unsupported_channel | 400 | Unsupported channel | The supplied channel is not supported at this time. | Use a supported channel value (for example, telegram). |
invalid_token | 400 | Invalid token | The supplied token is missing, not a string, or empty. | Pass the bot token through the CLI’s required --token flag. |
invalid_label | 400 | Invalid label | The supplied label is too long or otherwise invalid. | Use a label of 64 characters or fewer, or omit the field. |
channel_token_rejected | 400 | Channel token rejected | The channel rejected the stored token. On register, nothing was stored. | Verify the token is correct and not revoked at the channel, then re-register with hoody bot create --token <token> --channel telegram. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_duplicate | 409 | Duplicate registration | A registration already exists for this channel bot token. | List registrations and reuse the existing one, or supply a different token. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
channel_unavailable | 503 | Channel unavailable | The channel API is not reachable. | Verify the channel is up and retry the request. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
GET /api/v1/bot/registrations/{registrationId}
Section titled “GET /api/v1/bot/registrations/{registrationId}”Read one registration.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X GET \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.get(registrationId);hoody bot get {registrationId}{ "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "running", "created_at": 1700000000000, "updated_at": 1700000001000, "last_error_code": null, "last_error_at": null}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
DELETE /api/v1/bot/registrations/{registrationId}
Section titled “DELETE /api/v1/bot/registrations/{registrationId}”Deletes the registration and its stored channel token, and stops its poller.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X DELETE \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.delete(registrationId);hoody bot delete {registrationId}The response has no body.
| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
Polling
Section titled “Polling”The registration state is stored as running or stopped, so a started registration comes back up at the next start of the kit. The long-polling worker is brought up here.
POST /api/v1/bot/registrations/{registrationId}/start
Section titled “POST /api/v1/bot/registrations/{registrationId}/start”Records the intent to poll and starts the worker. The registration state is stored, so a started registration is brought back up at the next start of the kit.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/start" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.start(registrationId);hoody bot start {registrationId}{ "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "running", "created_at": 1700000000000, "updated_at": 1700000003000, "last_error_code": null, "last_error_at": null}The intent is recorded, but this build wired no poller, so nothing is polling and health reports polling.active: 0.
{ "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "running", "created_at": 1700000000000, "updated_at": 1700000003000, "last_error_code": null, "last_error_at": null, "polling": "unavailable"}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
POST /api/v1/bot/registrations/{registrationId}/stop
Section titled “POST /api/v1/bot/registrations/{registrationId}/stop”Stop long-polling for a registration. The registration and its stored channel token are kept.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/stop" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.stop(registrationId);hoody bot stop {registrationId}{ "id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel": "telegram", "label": "AcmeBot", "channel_bot_id": "7123456789", "channel_username": "@acme_bot", "state": "stopped", "created_at": 1700000000000, "updated_at": 1700000004000, "last_error_code": null, "last_error_at": null}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
Channel surface
Section titled “Channel surface”Two operations publish the bot’s surface to the channel: the registered commands and the bot profile (name, descriptions, default admin rights). The profile is stored before it is published, so a channel failure leaves the stored value ready to be republished by repeating the request.
POST /api/v1/bot/registrations/{registrationId}/commands/sync
Section titled “POST /api/v1/bot/registrations/{registrationId}/commands/sync”Runs the bot’s one publication reconciliation, the same one an activation runs, and answers with the readback diff: commands per scope, obsolete scopes deleted, the menu button, and the stored profile. Idempotent: a second run reports changed: false.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/commands/sync" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.syncCommands(registrationId);hoody bot commands sync {registrationId}{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "changed": true, "written": ["default|en"], "unchanged": [], "deleted": [], "trimmed": [], "rejected": [], "menu_button_changed": false, "profile_changed": false}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
channel_token_rejected | 400 | Channel token rejected | The registration’s stored channel token was rejected by the channel. The registration is preserved. | Rotate the token at the channel and re-register, or repeat the call to retry once the stored token is accepted again. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
channel_sync_failed | 502 | Channel sync failed | The channel rejected the publication. | Inspect the registration’s last_error_code and correct the input. |
channel_unavailable | 503 | Channel unavailable | The channel API is not reachable. | Verify the channel is up and retry the request. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
PUT /api/v1/bot/registrations/{registrationId}/profile
Section titled “PUT /api/v1/bot/registrations/{registrationId}/profile”Stores the bot profile and publishes it to the channel. An absent key leaves the stored value unchanged, null stops the kit managing that field, and an empty string clears it at the channel. The three are different operations. The profile is stored before it is published, so a channel failure leaves the stored value ready to be republished by repeating the request.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
Request body
Section titled “Request body”| Name | Type | Required | Description |
|---|---|---|---|
name | string | No | The bot name to publish (up to 64 characters). |
description | string | No | The bot description to publish (up to 512 characters). |
short_description | string | No | The bot short description to publish (up to 120 characters). |
language_code | string | No | The IETF tag the three texts belong to. |
administrator_rights | object | No | Default administrator rights to publish for groups and channels. Each sub-object maps capability names to booleans. |
curl -X PUT \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/profile" \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Bot", "description": "Acme operations bot.", "short_description": "Acme ops", "language_code": "en" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.updateProfile(registrationId, { name: 'Acme Bot', description: 'Acme operations bot.', short_description: 'Acme ops', language_code: 'en'});hoody bot profile update {registrationId} \ --name "Acme Bot" \ --description "Acme operations bot." \ --short-description "Acme ops" \ --language-code en{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "profile": { "name": "Acme Bot", "description": "Acme operations bot.", "short_description": "Acme ops", "language_code": "en" }, "changed": true, "written": ["name", "description", "short_description"], "unchanged": [], "refused": []}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
invalid_body | 400 | Invalid body | The request body could not be parsed or fails schema validation. | Compare the body with the documented schema and resend. |
invalid_profile | 400 | Invalid profile | The supplied profile is not acceptable. | Ensure each field is within its length limit and resend. |
channel_token_rejected | 400 | Channel token rejected | The registration’s stored channel token was rejected by the channel. The registration and any profile already sent are preserved. | Rotate the token at the channel and re-register, or repeat the call to retry once the stored token is accepted again. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
channel_sync_failed | 502 | Channel sync failed | The channel rejected the publication. | Inspect the registration’s last_error_code and correct the input. |
channel_unavailable | 503 | Channel unavailable | The channel API is not reachable. | Verify the channel is up and retry the request. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
Policy
Section titled “Policy”Each registration stores a mode (a stored label, single or multi) and two allowlists (users and chats). Admission is decided by the allowlists; mode is a label the kit records, not a constraint on the number of signed-in accounts.
GET /api/v1/bot/registrations/{registrationId}/policy
Section titled “GET /api/v1/bot/registrations/{registrationId}/policy”Returns the registration’s mode and allowlists as the gate enforces them. A null users allowlist admits every user; a null chats allowlist means direct messages only, so a group is admitted only when the chats list names it; an empty array admits nobody.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X GET \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/policy" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.getPolicy(registrationId);hoody bot policy get {registrationId}{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "mode": "single", "allowlists": { "users": null, "chats": null }}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
PUT /api/v1/bot/registrations/{registrationId}/policy
Section titled “PUT /api/v1/bot/registrations/{registrationId}/policy”Sets the mode and allowlists. mode is required; an absent allowlist key is left alone, an explicit null takes that list out of force, and an empty array admits nobody. The answer is the policy read back from the store. The allowlists take effect on the next update the bot receives: an unadmitted actor or chat is refused before the chat user is looked up, and the refusal is written to the audit log.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
Request body
Section titled “Request body”| Name | Type | Required | Description |
|---|---|---|---|
mode | string | Yes | The stored mode label, single or multi. |
allowlists | object | No | The allowlists to apply. An absent key leaves the stored list alone; an explicit null takes it out of force; an empty array admits nobody. |
allowlists.users | array | No | Channel user ids this bot serves. null admits every user; an empty array admits nobody. |
allowlists.chats | array | No | Chat ids this bot serves. null means direct messages only; a non-empty list is exhaustive and includes direct messages; an empty array admits no chat. |
curl -X PUT \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/policy" \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "mode": "single", "allowlists": { "users": null, "chats": null } }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.updatePolicy(registrationId, { mode: 'single', allowlists: { users: null, chats: null }});hoody bot policy update {registrationId} --mode single --allowlists null{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "mode": "single", "allowlists": { "users": null, "chats": null }}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
invalid_body | 400 | Invalid body | The request body could not be parsed or fails schema validation. | Compare the body with the documented schema and resend. |
invalid_policy | 400 | Invalid policy | The supplied policy is not acceptable. | Ensure mode is one of single or multi and that each allowlist is an array of strings (or null), with at most 1000 entries. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
Audit log
Section titled “Audit log”Every action the kit takes on behalf of a registration lands in a per-registration log. The log is redacted on write and paged by cursor. A 90-day retention window applies; purging inside the window is refused unless waived.
GET /api/v1/bot/registrations/{registrationId}/logs
Section titled “GET /api/v1/bot/registrations/{registrationId}/logs”Returns the redacted audit log, newest first. Paging is by cursor (next_before_id), not by offset, so a cursor stays valid across the retention sweep.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
actor | query | string | No | Narrow the page to one chat user. Matched exactly against the stored actor value, which carries the channel prefix, for Telegram telegram:<user id>, not the bare id the revoke path takes. |
since | query | integer | No | Drop entries older than this epoch-millisecond timestamp. A filter on the page, not a cursor: paging continues past it. |
limit | query | integer | No | Page size; capped by the store at 500. The answer reports the size actually used. |
before_id | query | integer | No | The cursor: the next_before_id of the previous page. Omit for the newest page. |
curl -X GET \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/logs?actor=telegram%3A7123456789&limit=100" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.listLogs(registrationId, { actor: 'telegram:7123456789', limit: 100});hoody bot logs list {registrationId} --actor "telegram:7123456789" --limit 100{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "entries": [ { "id": 1001, "at": 1700000123000, "actor": "telegram:7123456789", "user_id": "usr_01HF7XK3MRW2P6G8N5Y4Z0VDEF", "action": "login", "outcome": "allowed", "target": null, "detail": null } ], "next_before_id": null, "limit": 100}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
invalid_query | 400 | Invalid query | A query parameter was malformed. | Re-check the named parameter and supply a valid value. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
DELETE /api/v1/bot/registrations/{registrationId}/logs
Section titled “DELETE /api/v1/bot/registrations/{registrationId}/logs”Deletes this registration’s audit entries at or below a cutoff. A cutoff inside the 90-day retention window is refused rather than clamped; all=true waives the floor.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
older_than | query | integer | No | Delete entries at or below this epoch-millisecond timestamp. Defaults to the 90-day retention boundary. |
all | query | string | No | Waive the 90-day retention floor. Without it a cutoff inside the retention window is refused, never clamped. Literal values: true, false. |
curl -X DELETE \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/logs?older_than=1700000000000&all=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.purgeLogs(registrationId, { older_than: 1700000000000, all: 'true'});hoody bot logs purge {registrationId} --older-than 1700000000000 --all true -y{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "deleted": 12, "cutoff": 1700000000000, "retention_floor": 1697400000000, "all": false}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
invalid_query | 400 | Invalid query | A query parameter was malformed. | Re-check the named parameter and supply a valid value. |
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
logs_purge_refused | 409 | Log purge refused | The cutoff falls inside the 90-day retention window. | Pass all=true to waive the floor, or supply an older cutoff. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
Sessions and tokens
Section titled “Sessions and tokens”Revoke a single chat user’s lineage, or every chat user of the registration at once. The leaf is deleted through the parent, the parent is forgotten, and any intents, wizards and subscriptions bound to that lineage are invalidated.
POST /api/v1/bot/registrations/{registrationId}/sessions/{channelUserId}/revoke
Section titled “POST /api/v1/bot/registrations/{registrationId}/sessions/{channelUserId}/revoke”Revokes one chat user’s login as the operator: the leaf is deleted through the parent, the parent is forgotten, and the intents, wizards and subscriptions bound to that lineage are invalidated. A parent the platform refused to delete is reported by id for hoody auth tokens delete.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
channelUserId | path | string | Yes | The channel’s own id for the chat user (the Telegram user id), without a channel prefix. The audit log’s actor column spells the same user differently, telegram:<user id>, so a value copied from there is not accepted here. |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/sessions/7123456789/revoke" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.revokeSession(registrationId, '7123456789');hoody bot sessions revoke {registrationId} 7123456789{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "channel_user_id": "7123456789", "user_id": "usr_01HF7XK3MRW2P6G8N5Y4Z0VDEF", "revoked": true, "kind": "lineage", "parent_token_id": "tok_01HF7XK3MRW2P6G8N5Y4Z0VGHI", "leaf_token_id": "tok_01HF7XK3MRW2P6G8N5Y4Z0VJKL", "pasted_token_id": null, "leaf_deleted": true, "invalidated": { "intents": 0, "wizards": 0, "subscriptions": 0 }, "manual_deletes": ["tok_01HF7XK3MRW2P6G8N5Y4Z0VGHI"], "sessions_deleted": 1, "browser_sessions_revoked": 0}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
session_not_found | 404 | Session not found | No session exists for the supplied channel user id. | Confirm the channel user id (the bare Telegram id, not the audit log’s actor value). |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |
POST /api/v1/bot/registrations/{registrationId}/tokens/revoke-all
Section titled “POST /api/v1/bot/registrations/{registrationId}/tokens/revoke-all”Revokes every chat user of this registration. A failure does not stop the sweep: each one is recorded and the rest are still revoked.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
registrationId | path | string | Yes | Registration id returned by register or list. |
curl -X POST \ "https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com/api/v1/bot/registrations/{registrationId}/tokens/revoke-all" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-bot-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN});
await client.bot.registrations.revokeAllTokens(registrationId);hoody bot tokens revoke {registrationId} --all{ "registration_id": "reg_01HF7XK3MRW2P6G8N5Y4Z0VABC", "users": 2, "revoked": 2, "skipped": 0, "sessions_deleted": 2, "browser_sessions_revoked": 0, "failed": [], "manual_deletes": [ "tok_01HF7XK3MRW2P6G8N5Y4Z0VGHI", "tok_01HF7XK3MRW2P6G8N5Y4Z0VMNO" ]}| Error Code | Status | Title | Description | Resolution |
|---|---|---|---|---|
query_ambiguous | 400 | Ambiguous query | The request could not be parsed. | Re-check the request shape and resend. |
registration_not_found | 404 | Registration not found | No registration exists at the supplied id. | List registrations to find the correct id. |
internal_error | 500 | Internal server error | An unexpected error occurred while processing the request. | Retry the request. If it persists, capture the response and contact support. |
admission_unavailable | 503 | Admission unavailable | The kit cannot currently admit the request. | Retry the request after a short delay. |