Skip to content

Bot API

Telegram Bot API documentation

Bot API is a high-level HTTP interface to the Telegram API that makes it easy to develop bots. Under the hood, Bot API uses TDLib (which in turn uses MTProto API).

While the Bot API can only be used to work with bot accounts, the MTProto API can be used to work with both bot and user accounts. If you need to work with MTProto, we recommend you the MtCute Logomtcute library.

Calling the Bot API

You can call Telegram Bot API methods via bot.api or via the shorthand methods of contexts (for example, context.send is sendMessage shorthand)

ts
const 
response
= await
bot
.
api
.
sendMessage
({
// //
chat_id
: "@gramio_forum",
text
: "some text",
});
ts
bot
.
on
("message", (
context
) =>
context
.
send
("This message will be sent to the current chat")
);

Suppressing errors

It can be convenient to handle an error on the spot without using try/catch blocks. That's why the suppress argument was created, which you can use in any API method.

ts
const 
response
= await
bot
.
api
.
sendMessage
({
// //
suppress
: true,
chat_id
: "@not_found",
text
: "Suppressed method",
}); if (
response
instanceof
TelegramError
)
console
.
error
("sendMessage returns an error...");
else
console
.
log
("Message has been sent successfully");

Handling Rate Limits

Built-in utility for 429 errors:

ts
import { 
withRetries
} from "gramio/utils";
const
response
= await
withRetries
(() =>
bot
.
api
.
sendMessage
({
chat_id
: "@gramio_forum",
text
: "message text",
}) );
response
;

withRetries handles both thrown and returned errors with automatic retry logic.

Types

GramIO re-exports @gramio/types (Code-generated and Auto-published Telegram Bot API types).

Read more

ts
import type { 
APIMethodParams
,
APIMethodReturn
} from "gramio";
type
SendMessageParams
=
APIMethodParams
<"sendMessage">;
// type
GetMeReturn
=
APIMethodReturn
<"getMe">;
//

For example you can use it in your custom function.

ts
function 
myCustomSend
(
params
:
APIMethodParams
<"sendMessage">) {
params
;
}

Types for suppressed method

ts
import type {
    
SuppressedAPIMethodParams
,
SuppressedAPIMethodReturn
,
} from "gramio"; type
SendMessageParams
=
SuppressedAPIMethodParams
<"sendMessage">;
// type
GetMeReturn
=
SuppressedAPIMethodReturn
<"getMe">;
//

Calling API Methods Not Present in Types

First, check if they exist in @gramio/types.

If they exist there but aren't visible in GramIO, you can override the dependency version in your package.json:

json
{
    "overrides": {
        "@gramio/types": "10.0.0"
    }
}

If they don't exist (e.g., when using a custom Telegram Bot API server), you can use declaration merging:

ts
declare module "@gramio/types" {
    export interface APIMethods {
        myCustomMethod: (params: {
            chat_id: string;
            text: string;
        }) => Promise<"some return type">;
    }
}

Now you can use myCustomMethod as a regular API method:

ts
bot.api.myCustomMethod({
    chat_id: "123",
    text: "Hello",
});

Debugging

In order to debug which requests GramIO sends, you can set the environment variable to DEBUG=gramio:api:*

bash
npx cross-env DEBUG=gramio:api:* node index.js

And you will see something like in the console:

bash
gramio:api:getUpdates options: {"method":"POST","headers":{"Content-Type":"application/json"},"body":"{\"offset\":0,\"suppress\":true}"} +0ms
gramio:api:getUpdates response: {"ok":true,"result":[]} +49ms

also if you use Bun you can use BUN_CONFIG_VERBOSE_FETCH environment variable to log network requests. Read more.

sh
BUN_CONFIG_VERBOSE_FETCH=curl bun src/index.ts

And logs will looks like:

curl
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.14
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256

Bun startup optimization: --fetch-preconnect

If you are running your bot with Bun, you can use the CLI flag --fetch-preconnect=<url> to speed up the first network request to Telegram servers. This flag tells Bun to start establishing the connection (DNS, TCP, TLS) to the specified host before your code runs, so the first API call is faster.

Example:

bash
bun --fetch-preconnect=https://api.telegram.org:443/ ./src/bot.ts

This is especially useful for bots where the first thing you do is call the Telegram API. With this flag, Bun will "warm up" the connection at startup, so your bot will be ready to send requests with less delay. The overall startup time may increase slightly, but the time to first successful API call will decrease. In most cases this is not an issue, but the benefit is less noticeable if the first request is sent immediately after the process starts.

See more in the Bun documentation.

const response: TelegramMessage
const response: TelegramMessage | TelegramError<"sendMessage">
const response: TelegramMessage
type SendMessageParams = SendMessageParams
type GetMeReturn = TelegramUser
params: SendMessageParams
type SendMessageParams = SendMessageParams & Suppress<true>
type GetMeReturn = TelegramUser | TelegramError<"getMe">