Skip to content
teleproto

Introduction

teleproto is a Telegram MTProto API client library written in TypeScript. It gives your code the same surface Telegram's own apps have — userbots, multi-account automation, raw TL invocation, anything the protocol exposes.

What is teleproto?#

Most Telegram libraries on npm wrap the official Bot API — the HTTP surface available to @-named bot accounts. teleproto is different: it implements MTProto, Telegram's own binary protocol — the same one Telegram Desktop and Telegram for iOS speak.

That difference matters in practice:

  • Full account access. Drive a real user account, not just a bot. Read history, manage dialogs, edit your own profile, join private channels, all of it.
  • Userbots. Automate your account the same way the official client does — schedule messages, auto-react, monitor channels.
  • No webhook server. teleproto opens a persistent MTProto connection. Updates push to you over that single socket — no inbound HTTP endpoint, no SSL cert, no public URL.
  • Schema-level API surface. Every method in Telegram's TL definitions is callable through Api.*, even ones the Bot API never exposed.

Install in 30 seconds#

teleproto is pure JavaScript. No native build step, no postinstall, no Python in your container. Installs cleanly on Alpine, ARM, and serverless.

Terminal
npm install teleproto

TypeScript types ship in the package itself — no @types/teleproto to install. Run tsc --noEmit after import and you'll get full autocomplete on every method, event, and TL object.

Your first connection#

Grab an api_id and api_hash from my.telegram.org, then:

login.ts
import { TelegramClient } from "teleproto";
import { StringSession } from "teleproto/sessions";
import { createInterface } from "node:readline/promises";

const rl = createInterface({ input: process.stdin, output: process.stdout });
const apiId = 0;
const apiHash = "";
const session = new StringSession("");

const client = new TelegramClient(session, apiId, apiHash, {
  connectionRetries: 5,
});

await client.start({
  phoneNumber: () => rl.question("Phone: "),
  password:    () => rl.question("2FA password: "),
  phoneCode:   () => rl.question("Code: "),
  onError: console.error,
});

console.log(await client.getMe());
console.log("Session string:", client.session.save());

rl.close();

Save the session string and pass it back into new StringSession(saved) next time — that's your login, no more SMS-code dances. See Sessions for the full story on persistence and the three session types.

Architecture at a glance#

teleproto has four moving parts you'll touch directly:

Where to next#