Gramophone exposes Telegram Bot API-style HTTP endpoints. If your bot framework lets you set a custom API root, point it at Gramophone and keep the usual method calls.
Base URL:
https://api.gramophone.dev
https://api.gramophone.dev/bot<TOKEN>/<METHOD>
Methods follow the Telegram Bot API: getMe, getUpdates, sendMessage, sendPhoto, setWebhook, etc.
export BOT_TOKEN='123:example'
curl "https://api.gramophone.dev/bot$BOT_TOKEN/getMe"
curl -X POST "https://api.gramophone.dev/bot$BOT_TOKEN/getUpdates" \
-H 'content-type: application/json' \
-d '{"offset":0,"limit":10,"timeout":0}'
curl -X POST "https://api.gramophone.dev/bot$BOT_TOKEN/sendMessage" \
-H 'content-type: application/json' \
-d '{"chat_id":123,"text":"hello from Gramophone"}'
import { Bot } from "grammy";
const bot = new Bot(process.env.BOT_TOKEN, {
client: { apiRoot: "https://api.gramophone.dev" },
});
bot.command("start", (ctx) => ctx.reply("Hello from Gramophone"));
bot.start();
Most libraries only need the API root (https://api.gramophone.dev), not the full /bot<TOKEN> prefix.
Bot management uses /admin/* routes. These are for the server operator. Every request needs the server's admin token:
export ADMIN_TOKEN='your-server-admin-token'
export AUTH="authorization: Bearer $ADMIN_TOKEN"
Usernames must be 3–32 characters: ASCII letters, numbers, or underscores.
curl -X POST "https://api.gramophone.dev/admin/bots" \
-H "$AUTH" \
-H 'content-type: application/json' \
-d '{"username":"echo_bot","display_name":"Echo Bot"}'
The response includes the bot token:
{
"id": 1,
"username": "echo_bot",
"display_name": "Echo Bot",
"global_address": "echo_bot@<server>",
"token": "<uuid>:<uuid>"
}
Use that token with /bot<TOKEN>/....
curl "https://api.gramophone.dev/admin/bots" -H "$AUTH"
curl "https://api.gramophone.dev/admin/bots/echo_bot" -H "$AUTH"
This returns the bot id, username, display name, global address, and token counts.
Revoking disables the bot's active tokens but keeps the bot record and related data.
curl -X POST "https://api.gramophone.dev/admin/bots/echo_bot/revoke" -H "$AUTH"
{
"username": "echo_bot",
"revoked_token_count": 1
}
Delete removes the bot record plus bot-specific state such as tokens, queued updates, offsets, webhooks, commands, and menu buttons.
Deletion is conservative: if the bot is still referenced by chats, messages, stickers, or other history, the server returns 409 Conflict. In that case, revoke the bot instead.
curl -X DELETE "https://api.gramophone.dev/admin/bots/echo_bot" -H "$AUTH"
{
"username": "echo_bot",
"deleted": true,
"deleted_bot_tokens": 1,
"deleted_bot_updates": 0,
"deleted_update_offsets": 0,
"deleted_webhooks": 0,
"deleted_commands": 0,
"deleted_menu_buttons": 0
}
The Gramophone Android app can open bot chats directly:
gramophone://bot?username=bot_a
gramophone://bot?username=bot_a%40api.gramophone.dev
gramophone://bot?username=bot_b%40api-b.gramophone.dev
Short usernames resolve on the app's currently configured server. For example, on api.gramophone.dev, both bot_a and bot_a@api.gramophone.dev open the local bot_a. Full username@server addresses resolve exact Gramophone identities and are useful for federated bots. If a target cannot be resolved, Android shows Could not find X.
curl "https://api.gramophone.dev/compat"
Gramophone tracks Bot API 10.0 compatibility.