Telegram supports E2E-encrypted group and one-to-one calls.
This page describes the API methods used to work with calls.
phoneCallProtocol#fc878fc8 flags:# udp_p2p:flags.0?true udp_reflector:flags.1?true min_layer:int max_layer:int library_versions:Vector<string> = PhoneCallProtocol;
phoneConnectionWebrtc#635fe375 flags:# turn:flags.0?true stun:flags.1?true id:long ip:string ipv6:string port:int username:string password:string = PhoneConnection;
phoneCallWaiting#c5226f17 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
phoneCallRequested#14b0ed0c flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCallAccepted#3660c311 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCall#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true conference_supported:flags.8?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int custom_parameters:flags.7?DataJSON = PhoneCall;
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
phone.phoneCall#ec82e140 phone_call:PhoneCall users:Vector<User> = phone.PhoneCall;
updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
phoneCallDiscardReasonMigrateConferenceCall#9fbbf1f7 slug:string = PhoneCallDiscardReason;
---functions---
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
See here » for a detailed description of the end-to-end encryption used for one-to-one calls, briefly re-explained below with some additional, API-level details:
video flag to request a video call, otherwise an audio call is requested.video flag if at least one of the two sides of the discarded call has a video stream enabled (regardless of whether initially the call was a video call or a voice call), or when migrating to a conference call.need_rating flag is set, the client must invite the user to rate the call » when it ends.user_initiative flag must be set when invoking phone.setCallRating.phoneCallProtocolphoneCallProtocol#fc878fc8 flags:# udp_p2p:flags.0?true udp_reflector:flags.1?true min_layer:int max_layer:int library_versions:Vector<string> = PhoneCallProtocol;
phoneCallProtocol describes the tgcalls protocol versions supported by the local build of tgcalls, populated as follows:
library_versions with the ordered list of supported tgcalls protocol versions (order matters, the preferred tgcalls protocol version must come first)udp_p2p and udp_reflector to true (deprecated, previously used to allow or disallow the use of direct peer-to-peer networking for libtgvoip calls)min_layer to 65 (deprecated, was previously used to describe the oldest supported libtgvoip protocol)max_layer to 92 (deprecated, was previously used to describe the oldest supported libtgvoip protocol)u2p_p2p, udp_reflector, min_layer and max_layer were previously used by the deprecated libtgvoip library, and should not be passed to tgcalls: the values listed here are hardcoded and immutable, fixed to the last values supported by libtgvoip and are only used if the other end still uses libtgvoip.
The use of peer-to-peer networking is now controlled by the the privacyKeyPhoneP2P privacy setting », which is used by the server to choose whether to also return P2P STUN phoneConnectionWebrtc connection options, along with the usual reflector TURN phoneConnectionWebrtc connection options.
The same local capability set is re-sent in all three outbound handshake methods: the protocol embedded in phoneCallWaiting, phoneCallRequested and phoneCallAccepted does not stop either client from advertising its own local capabilities again in the next outgoing RPC.
updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update;
---functions---
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
phone.sendSignalingData is only used after the DH handshake is over and both sides have the final phoneCall with verified key material and connection info: at this point, tgcalls should be initialized from the final phoneCall constructor's protocol and connections fields, and only then tgcalls's signaling callback can be wired to invoke phone.sendSignalingData.
Invoke this method whenever the tgcalls emits an opaque signaling packet that must be delivered to the peer: this will emit an updatePhoneCallSignalingData for the other peer in the call, who should then pass updatePhoneCallSignalingData.data to their own instance of tgcalls.
---functions---
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
Invoke phone.setCallRating after the call ends to rate the call (sending a message to the official VoIP rating bot), passing the following parameters:
peer: The inputPhoneCall generated from the phoneCallDiscarded
user_initiative: Set this flag if the rating was initiated by the user by right-clicking on the call service message; must NOT be set if rating was requested by the server with phoneCallDiscarded.need_rating.
rating: A score from 1 to 5, chosen by the user.
comment: A user-specified comment (only for ratings not equal to 5).
The user may also choose to report additional problems from the following fixed list, in the form of #hashtags appended to the comment.
These hashtags may be appended even for ratings equal to 5, using this algorithm:
#echo)echoThe user heard their own voice (echo).
noiseThe user heard background noise.
interruptionsThe other side kept disappearing.
distorted_speechThe speech was distorted.
silent_localThe user couldn't hear the other side.
silent_remoteThe other side couldn't hear the user.
droppedThe call ended unexpectedly.
distorted_videoThe video was distorted.
pixelated_videoThe video was pixelated.
---functions---
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
If the final phoneCallDiscarded.need_debug flag is set, the client should upload implementation-specific debug information for the finished call, by calling phone.saveCallDebug with the JSON string returned by the active tgcalls instance.