Overview
Benty is a messaging platform for Russia and CIS markets, built around a Rust backend and a compact binary protocol called Type Benty. This documentation site is the public, readable layer: what the protocol is, how compatibility works, and how developers can reason about clients and forks.
Type Benty is the source of truth for entities, RPCs, layers, and compatibility rules.
The server implementation is Rust-based and validates protocol drift before client rollout.
Production clients use one stable public entrypoint while routing remains infrastructure-side.
Type Benty protocol
Type Benty is Benty's own schema format. It is not Telegram TL. The goal is the same class of transparency: a protocol that can be inspected, tested, and implemented by serious developers.
Namespaces
Published schema
The first public artifact is the current Type Benty schema draft. Developers can download it directly or inspect the opening section below.
// Type Benty Protocol Schema
// File: protocol/benty.tb
// Status: draft v0 approved product scope
// Owner: Benty
// Note: TB is Benty's own protocol schema format. It is not Telegram TL.
protocol Benty {
name = "benty"
schema = "TB"
schema_name = "Type Benty"
current_layer = 1
min_supported_layer = 1
byte_order = "little_endian"
id_width = "u32"
}
// ═══════════════════════════════════════════════════════════════
// Core
// ═══════════════════════════════════════════════════════════════
namespace core {
type BoolFalse #00000001 = {}
type BoolTrue #00000002 = {}
type Error #00000003 = {
code: i32
message: string
}
type Null #00000004 = {}
}
// ═══════════════════════════════════════════════════════════════
// Session / layer negotiation
// ═══════════════════════════════════════════════════════════════
namespace session {
rpc clientHello #10000010 = {
app_version: string
engine_version: string
platform: string
device_id: string
protocol_layer: i32
supported_layers: vector<i32>
feature_flags: vector<string>
} -> serverHello
type serverHello #20000010 = {
selected_layer: i32
min_supported_layer: i32
max_supported_layer: i32
server_time: i64
feature_flags: vector<string>
}
}
// ═══════════════════════════════════════════════════════════════
// Auth / profile / devices / security / privacy
// ═══════════════════════════════════════════════════════════════
namespace auth {
rpc registerDevice #10000001 = {
device_id: string
platform: string
push_token: optional<string>
} -> profile.User
rpc getMe #10000002 = {} -> profile.User
rpc listDevices #10000003 = {} -> devices.DeviceList
rpc updateProfile #10000004 = {
display_name: optional<string>
bio: optional<string>
avatar_media_id: optional<string>
} -> profile.User
rpc requestCode #19000001 = {
email: string
} -> core.BoolTrue
rpc verifyCode #19000002 = {
email: string
code: string
device_id: string
} -> AuthSession
type AuthSession #01000003 = {
account_id: i64
token: string
expires_at: i64
}
}
namespace profile {
type User #01000001 = {
account_id: i64
display_name: string
username: optional<string>
bio: optional<string>
avatar_url: optional<string>
premium: bool
verified: bool
}
rpc getUser #11010010 = {
account_id: i64
} -> User
rpc searchUsers #17000020 = {
query: string
offset: i32
limit: i32
} -> UserSearchResult
rpc setUsername #11010004 = {
username: string
} -> User
rpc setBio #11010005 = {
bio: string
} -> User
type UserSearchResult #27000020 = {
users: vector<User>
}
}
namespace devices {
type Device #01000002 = {
id: i64
device_id: string
platform: string
name: optional<string>
last_active_at: i64
trusted: bool
}
type DeviceList #01000020 = {
devices: vector<Device>
}
rpc list #11020001 = {} -> DeviceList
rpc revoke #11020002 = { device_id: string } -> core.BoolTrue
rpc revokeAllExceptCurrent #11020003 = {} -> core.BoolTrue
rpc rename #11020004 = { device_id: string name: string } -> Device
rpc setTrusted #11020005 = { device_id: string trusted: bool } -> Device
}
namespace security {
rpc listSessions #11030001 = {} -> AuthSessionList
rpc terminateSession #11030002 = { session_id: i64 } -> core.BoolTrue
rpc terminateAllSessions #11030003 = {} -> core.BoolTrue
rpc setPassword #11030004 = { password_hash: bytes } -> core.BoolTrue
rpc changePassword #11030005 = { old_password_hash: bytes new_password_hash: bytes } -> core.BoolTrue
rpc disablePassword #11030006 = {} -> core.BoolTrue
rpc set2fa #11030007 = { enabled: bool } -> core.BoolTrue
type AuthSessionList #11031001 = {
sessions: vector<auth.AuthSession>
}
}
namespace privacy {
rpc getSettings #11040001 = {} -> PrivacySettings
rpc setLastSeen #11040002 = { mode: PrivacyMode } -> PrivacySettings
rpc setProfilePhoto #11040003 = { mode: PrivacyMode } -> PrivacySettings
rpc setCalls #11040004 = { mode: PrivacyMode } -> PrivacySettings
rpc setGroupInvites #11040005 = { mode: PrivacyMode } -> PrivacySettings
rpc setStories #11040006 = { mode: PrivacyMode } -> PrivacySettings
rpc blockUser #11040007 = { account_id: i64 } -> core.BoolTrue
rpc unblockUser #11040008 = { account_id: i64 } -> core.BoolTrue
rpc getBlocked #11040009 = { offset: i32 limit: i32 } -> BlockedUsers
enum PrivacyMode { everyone contacts nobody custom }
type PrivacySettings #11041001 = {
last_seen: PrivacyMode
profile_photo: PrivacyMode
calls: PrivacyMode
group_invites: PrivacyMode
stories: PrivacyMode
}
type BlockedUsers #11041002 = {
users: vector<profile.User>
}
}
// ═══════════════════════════════════════════════════════════════
// Contacts / dialogs / archive / folders
// ═══════════════════════════════════════════════════════════════
namespace contacts {
type Contact #02000001 = {
account_id: i64
display_name: string
username: optional<string>
avatar_url: optional<string>
}
rpc list #17000010 = { offset: i32 limit: i32 } -> ContactList
rpc add #17000001 = { account_id: i64 message: optional<string> } -> ContactRequest
rpc accept #17000002 = { request_id: i64 } -> core.BoolTrue
rpc decline #17000003 = { request_id: i64 } -> core.BoolTrue
rpc delete #17000004 = { account_id: i64 } -> core.BoolTrue
rpc createInvite #17000005 = { expires_at: optional<i64> max_uses: optional<i32> } -> ContactInvite
rpc redeemInvite #17000006 = { code: string } -> Contact
rpc importPhonebook #17000030 = { contacts: vector<PhonebookContact> } -> ImportResult
rpc deleteImported #17000031 = {} -> core.BoolTrue
rpc getImportStatus #17000032 = {} -> ImportStatus
type ContactList #28000003 = { contacts: vector<Contact> }
type ContactRequest #02000002 = { request_id: i64 from_account_id: i64 to_account_id: i64 message: optional<string> }
type ContactInvite #02000003 = { code: string url: string expires_at: optional<i64> }
type PhonebookContact #17001001 = { phone: optional<string> email: optional<string> name: optional<string> }
type ImportResult #17001002 = { imported: i32 matched: i32 }
type ImportStatus #17001003 = { imported_count: i32 last_import_at: optional<i64> }
}
namespace dialogs {
type Dialog #03000001 = {Server model
The backend is responsible for authentication, sessions, dialogs, messages, media metadata, delivery/read acknowledgements, SDUI banner payloads, and protocol compatibility. Infrastructure routing is kept behind the stable public entrypoint rather than pushed into clients.
Core HTTP/WSS engine and binary codec live server-side.
Persistent accounts, devices, dialogs, messages, sessions, and metadata.
Server-managed media paths and metadata with client-safe references.
Clients
Clients should implement Type Benty commands and events, keep transport abstract, and preserve protocol layer compatibility. Mobile, desktop, and web clients can share the same schema while using platform-native UI.
Security and privacy
Benty documentation will describe the security model at a level that helps developers and auditors: auth flows, sessions, device trust, encrypted payload concepts, media access, abuse prevention, and responsible disclosure.
Forking and self-hosting
The long-term goal is to make it possible for qualified developers to inspect the protocol, build compatible clients, and run independent forks where technically and legally appropriate.
Transparency
We publish what helps users and developers verify Benty: protocol shape, compatibility rules, public schemas, and high-level architecture. We do not publish production secrets or internal operational routes.