2025-04-15 15:22:31 +03:00
/ *
* Copyright 2020 - 2022 Signal Messenger , LLC
* SPDX - License - Identifier : AGPL - 3.0 - only
2023-04-21 10:49:54 -04:00
* /
2025-04-15 15:22:31 +03:00
2023-04-21 10:49:54 -04:00
syntax = "proto2" ;
package signalservice ;
2025-04-15 15:22:31 +03:00
option java_package = "org.whispersystems.signalservice.internal.push" ;
2023-04-21 10:49:54 -04:00
option java_outer_classname = "SignalServiceProtos" ;
message Envelope {
enum Type {
2025-04-15 15:22:31 +03:00
UNKNOWN = 0 ;
2026-04-13 16:32:10 +03:00
/ * *
* A double - ratchet message represents a "normal," "unsealed-sender" message
* encrypted using the Double Ratchet within an established Signal session.
* Double - ratchet messages include sender information in the plaintext
* portion of the ` Envelope ` .
* /
DOUBLE_RATCHET = 1 ; // content => (version byte | SignalMessage{Content})
2025-04-15 15:22:31 +03:00
reserved 2 ;
reserved "KEY_EXCHANGE" ;
2026-04-13 16:32:10 +03:00
/ * *
* A prekey message begins a new Signal session. The ` content ` of a prekey
* message is a superset of a double - ratchet message ' s ` content ` and
* contains the sender ' s identity public key and information identifying the
* pre - keys used in the message ' s ciphertext. Like double - ratchet messages ,
* prekey messages contain sender information in the plaintext portion of
* the ` Envelope ` .
* /
PREKEY_MESSAGE = 3 ; // content => (version byte | PreKeySignalMessage{Content})
/ * *
* Server delivery receipts are generated by the server when
* "unsealed-sender" messages are delivered to and acknowledged by the
* destination device. Server delivery receipts identify the sender in the
* plaintext portion of the ` Envelope ` and have no ` content ` . Note that
* receipts for sealed - sender messages are generated by clients as
* ` UNIDENTIFIED_SENDER ` messages.
*
* Note that , with server delivery receipts , the "client timestamp" on
* the envelope refers to the timestamp of the original message ( i.e. the
* message the server just delivered ) and not to the time of delivery. The
* "server timestamp" refers to the time of delivery.
* /
SERVER_DELIVERY_RECEIPT = 5 ; // content => []
/ * *
* An unidentified sender message represents a message with no sender
* information in the plaintext portion of the ` Envelope ` . Unidentified
* sender messages always contain an additional ` subtype ` in their
* ` content ` . They may or may not be part of an existing Signal session
* ( i.e. an unidentified sender message may have a "prekey message"
* subtype or may indicate an encryption error ) .
* /
UNIDENTIFIED_SENDER = 6 ; // content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format))
reserved 7 ;
reserved "SENDERKEY_MESSAGE" ;
/ * *
* A plaintext message is used solely to convey encryption error receipts
* and never contains encrypted message content . Encryption error receipts
* must be delivered in plaintext because , encryption / decryption of a prior
* message failed and there is no reason to believe that
* encryption / decryption of subsequent messages with the same key material
* would succeed.
*
* Critically , plaintext messages never have "real" message content
* generated by users. Plaintext messages include sender information.
* /
PLAINTEXT_CONTENT = 8 ; // content => (marker byte | Content)
// next: 9
2025-04-15 15:22:31 +03:00
}
optional Type type = 1 ;
reserved 2 ; // formerly optional string sourceE164 = 2;
optional string sourceServiceId = 11 ;
2026-04-13 16:32:10 +03:00
optional uint32 sourceDeviceId = 7 ;
2023-12-21 18:06:58 +02:00
optional string destinationServiceId = 13 ;
2025-04-15 15:22:31 +03:00
reserved 3 ; // formerly optional string relay = 3;
2026-04-13 16:32:10 +03:00
optional uint64 clientTimestamp = 5 ;
2025-04-15 15:22:31 +03:00
reserved 6 ; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use
optional bytes content = 8 ; // Contains an encrypted Content
optional string serverGuid = 9 ;
optional uint64 serverTimestamp = 10 ;
optional bool ephemeral = 12 ; // indicates that the message should not be persisted if the recipient is offline
optional bool urgent = 14 [ default = true ] ; // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical
optional string updatedPni = 15 ; // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number
optional bool story = 16 ; // indicates that the content is a story.
optional bytes report_spam_token = 17 ; // token sent when reporting spam
reserved 18 ; // internal server use
2026-02-09 14:13:18 +02:00
optional bytes sourceServiceIdBinary = 19 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
optional bytes destinationServiceIdBinary = 20 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
optional bytes serverGuidBinary = 21 ; // 16-byte UUID
optional bytes updatedPniBinary = 22 ; // 16-byte UUID
// next: 22
2023-04-21 10:49:54 -04:00
}
message Content {
2026-04-13 16:32:10 +03:00
oneof content {
DataMessage dataMessage = 1 ;
SyncMessage syncMessage = 2 ;
CallMessage callMessage = 3 ;
NullMessage nullMessage = 4 ;
ReceiptMessage receiptMessage = 5 ;
TypingMessage typingMessage = 6 ;
bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8 ;
StoryMessage storyMessage = 9 ;
EditMessage editMessage = 11 ;
}
2025-04-15 15:22:31 +03:00
optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7 ;
optional PniSignatureMessage pniSignatureMessage = 10 ;
2023-04-21 10:49:54 -04:00
}
message CallMessage {
message Offer {
enum Type {
2025-04-15 15:22:31 +03:00
OFFER_AUDIO_CALL = 0 ;
OFFER_VIDEO_CALL = 1 ;
reserved /* OFFER_NEED_PERMISSION */ 2 ; // removed
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional uint64 id = 1 ;
reserved /* sdp */ 2 ;
optional Type type = 3 ;
optional bytes opaque = 4 ;
2023-04-21 10:49:54 -04:00
}
message Answer {
2025-04-15 15:22:31 +03:00
optional uint64 id = 1 ;
reserved /* sdp */ 2 ;
optional bytes opaque = 3 ;
2023-04-21 10:49:54 -04:00
}
message IceUpdate {
2025-04-15 15:22:31 +03:00
optional uint64 id = 1 ;
reserved /* mid */ 2 ;
reserved /* line */ 3 ;
reserved /* sdp */ 4 ;
optional bytes opaque = 5 ;
2023-04-21 10:49:54 -04:00
}
message Busy {
optional uint64 id = 1 ;
}
message Hangup {
enum Type {
2025-04-15 15:22:31 +03:00
HANGUP_NORMAL = 0 ;
HANGUP_ACCEPTED = 1 ;
HANGUP_DECLINED = 2 ;
HANGUP_BUSY = 3 ;
2023-04-21 10:49:54 -04:00
HANGUP_NEED_PERMISSION = 4 ;
}
2025-04-15 15:22:31 +03:00
optional uint64 id = 1 ;
optional Type type = 2 ;
2023-04-21 10:49:54 -04:00
optional uint32 deviceId = 3 ;
}
message Opaque {
enum Urgency {
2025-04-15 15:22:31 +03:00
DROPPABLE = 0 ;
2023-04-21 10:49:54 -04:00
HANDLE_IMMEDIATELY = 1 ;
}
2025-04-15 15:22:31 +03:00
optional bytes data = 1 ;
optional Urgency urgency = 2 ; // If missing, treat as DROPPABLE.
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional Offer offer = 1 ;
optional Answer answer = 2 ;
repeated IceUpdate iceUpdate = 3 ;
reserved /* legacyHangup */ 4 ;
optional Busy busy = 5 ;
reserved /* profileKey */ 6 ;
optional Hangup hangup = 7 ;
reserved /* multiRing */ 8 ;
optional uint32 destinationDeviceId = 9 ;
optional Opaque opaque = 10 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
message DataMessage {
enum Flags {
2026-06-05 00:07:51 +03:00
reserved /*END_SESSION*/ 1 ;
2025-04-15 15:22:31 +03:00
EXPIRATION_TIMER_UPDATE = 2 ;
PROFILE_KEY_UPDATE = 4 ;
FORWARD = 8 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
message Payment {
message Amount {
message MobileCoin {
optional uint64 picoMob = 1 ; // 1,000,000,000,000 picoMob per Mob
}
2023-04-21 10:49:54 -04:00
2025-04-15 15:22:31 +03:00
oneof Amount {
MobileCoin mobileCoin = 1 ;
}
}
2023-04-21 10:49:54 -04:00
2025-04-15 15:22:31 +03:00
message Notification {
message MobileCoin {
optional bytes receipt = 1 ;
}
oneof Transaction {
MobileCoin mobileCoin = 1 ;
}
// Optional, Refers to the PaymentRequest message, if any.
optional string note = 2 ;
reserved /*requestId*/ 1003 ;
}
message Activation {
enum Type {
REQUEST = 0 ;
ACTIVATED = 1 ;
}
optional Type type = 1 ;
}
oneof Item {
Notification notification = 1 ;
Activation activation = 2 ;
}
reserved /*request*/ 1002 ;
reserved /*cancellation*/ 1003 ;
2023-04-21 10:49:54 -04:00
}
message Quote {
enum Type {
2025-04-15 15:22:31 +03:00
NORMAL = 0 ;
2023-04-21 10:49:54 -04:00
GIFT_BADGE = 1 ;
2025-10-29 14:10:25 +02:00
POLL = 2 ;
2023-04-21 10:49:54 -04:00
}
message QuotedAttachment {
2025-04-15 15:22:31 +03:00
optional string contentType = 1 ;
optional string fileName = 2 ;
optional AttachmentPointer thumbnail = 3 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional uint64 id = 1 ;
reserved /*authorE164*/ 2 ;
optional string authorAci = 5 ;
optional string text = 3 ;
2023-04-21 10:49:54 -04:00
repeated QuotedAttachment attachments = 4 ;
2025-04-15 15:22:31 +03:00
repeated BodyRange bodyRanges = 6 ;
optional Type type = 7 ;
2026-02-09 14:13:18 +02:00
optional bytes authorAciBinary = 8 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message Contact {
message Name {
2025-04-15 15:22:31 +03:00
optional string givenName = 1 ;
optional string familyName = 2 ;
optional string prefix = 3 ;
optional string suffix = 4 ;
optional string middleName = 5 ;
reserved /*displayName*/ 6 ;
optional string nickname = 7 ;
2023-04-21 10:49:54 -04:00
}
message Phone {
enum Type {
2025-04-15 15:22:31 +03:00
HOME = 1 ;
2023-04-21 10:49:54 -04:00
MOBILE = 2 ;
2025-04-15 15:22:31 +03:00
WORK = 3 ;
2023-04-21 10:49:54 -04:00
CUSTOM = 4 ;
}
optional string value = 1 ;
2025-04-15 15:22:31 +03:00
optional Type type = 2 ;
2023-04-21 10:49:54 -04:00
optional string label = 3 ;
}
message Email {
enum Type {
2025-04-15 15:22:31 +03:00
HOME = 1 ;
2023-04-21 10:49:54 -04:00
MOBILE = 2 ;
2025-04-15 15:22:31 +03:00
WORK = 3 ;
2023-04-21 10:49:54 -04:00
CUSTOM = 4 ;
}
optional string value = 1 ;
2025-04-15 15:22:31 +03:00
optional Type type = 2 ;
2023-04-21 10:49:54 -04:00
optional string label = 3 ;
}
message PostalAddress {
enum Type {
2025-04-15 15:22:31 +03:00
HOME = 1 ;
WORK = 2 ;
2023-04-21 10:49:54 -04:00
CUSTOM = 3 ;
}
2025-04-15 15:22:31 +03:00
optional Type type = 1 ;
optional string label = 2 ;
optional string street = 3 ;
optional string pobox = 4 ;
2023-04-21 10:49:54 -04:00
optional string neighborhood = 5 ;
2025-04-15 15:22:31 +03:00
optional string city = 6 ;
optional string region = 7 ;
optional string postcode = 8 ;
optional string country = 9 ;
2023-04-21 10:49:54 -04:00
}
message Avatar {
2025-04-15 15:22:31 +03:00
optional AttachmentPointer avatar = 1 ;
optional bool isProfile = 2 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional Name name = 1 ;
repeated Phone number = 3 ;
repeated Email email = 4 ;
repeated PostalAddress address = 5 ;
optional Avatar avatar = 6 ;
optional string organization = 7 ;
2023-04-21 10:49:54 -04:00
}
message Sticker {
2025-04-15 15:22:31 +03:00
optional bytes packId = 1 ;
optional bytes packKey = 2 ;
optional uint32 stickerId = 3 ;
optional AttachmentPointer data = 4 ;
optional string emoji = 5 ;
2023-04-21 10:49:54 -04:00
}
message Reaction {
2025-04-15 15:22:31 +03:00
optional string emoji = 1 ;
optional bool remove = 2 ;
reserved /* targetAuthorE164 */ 3 ;
optional string targetAuthorAci = 4 ;
2023-04-21 10:49:54 -04:00
optional uint64 targetSentTimestamp = 5 ;
2026-02-09 14:13:18 +02:00
optional bytes targetAuthorAciBinary = 6 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message Delete {
optional uint64 targetSentTimestamp = 1 ;
}
message GroupCallUpdate {
optional string eraId = 1 ;
}
message StoryContext {
2025-04-15 15:22:31 +03:00
optional string authorAci = 1 ;
2023-04-21 10:49:54 -04:00
optional uint64 sentTimestamp = 2 ;
2026-02-09 14:13:18 +02:00
optional bytes authorAciBinary = 3 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
enum ProtocolVersion {
option allow_alias = true ;
2023-12-21 18:06:58 +02:00
2025-04-15 15:22:31 +03:00
INITIAL = 0 ;
MESSAGE_TIMERS = 1 ;
VIEW_ONCE = 2 ;
VIEW_ONCE_VIDEO = 3 ;
REACTIONS = 4 ;
CDN_SELECTOR_ATTACHMENTS = 5 ;
MENTIONS = 6 ;
PAYMENTS = 7 ;
2025-10-29 14:10:25 +02:00
POLLS = 8 ;
2026-02-09 14:13:18 +02:00
CURRENT = 8 ;
2023-04-21 10:49:54 -04:00
}
message GiftBadge {
optional bytes receiptCredentialPresentation = 1 ;
}
2025-10-29 14:10:25 +02:00
message PollCreate {
optional string question = 1 ;
optional bool allowMultiple = 2 ;
repeated string options = 3 ;
}
message PollTerminate {
optional uint64 targetSentTimestamp = 1 ;
}
message PollVote {
optional bytes targetAuthorAciBinary = 1 ;
optional uint64 targetSentTimestamp = 2 ;
2026-04-13 16:32:10 +03:00
repeated uint32 optionIndexes = 3 ;
optional uint32 voteCount = 4 ;
2025-10-29 14:10:25 +02:00
}
2026-02-09 14:13:18 +02:00
message PinMessage {
optional bytes targetAuthorAciBinary = 1 ; // 16-byte UUID
optional uint64 targetSentTimestamp = 2 ;
oneof pinDuration {
uint32 pinDurationSeconds = 3 ;
bool pinDurationForever = 4 ;
}
}
message UnpinMessage {
optional bytes targetAuthorAciBinary = 1 ; // 16-byte UUID
optional uint64 targetSentTimestamp = 2 ;
}
2026-04-13 16:32:10 +03:00
message AdminDelete {
optional bytes targetAuthorAciBinary = 1 ; // 16-byte UUID
optional uint64 targetSentTimestamp = 2 ;
}
2025-04-15 15:22:31 +03:00
optional string body = 1 ;
repeated AttachmentPointer attachments = 2 ;
reserved /*groupV1*/ 3 ;
optional GroupContextV2 groupV2 = 15 ;
optional uint32 flags = 4 ;
optional uint32 expireTimer = 5 ;
optional uint32 expireTimerVersion = 23 ;
optional bytes profileKey = 6 ;
optional uint64 timestamp = 7 ;
optional Quote quote = 8 ;
repeated Contact contact = 9 ;
repeated Preview preview = 10 ;
optional Sticker sticker = 11 ;
optional uint32 requiredProtocolVersion = 12 ;
optional bool isViewOnce = 14 ;
optional Reaction reaction = 16 ;
optional Delete delete = 17 ;
repeated BodyRange bodyRanges = 18 ;
optional GroupCallUpdate groupCallUpdate = 19 ;
optional Payment payment = 20 ;
optional StoryContext storyContext = 21 ;
optional GiftBadge giftBadge = 22 ;
2025-10-29 14:10:25 +02:00
optional PollCreate pollCreate = 24 ;
optional PollTerminate pollTerminate = 25 ;
optional PollVote pollVote = 26 ;
2026-02-09 14:13:18 +02:00
optional PinMessage pinMessage = 27 ;
optional UnpinMessage unpinMessage = 28 ;
2026-04-13 16:32:10 +03:00
optional AdminDelete adminDelete = 29 ;
// NEXT ID: 30
2023-04-21 10:49:54 -04:00
}
message NullMessage {
optional bytes padding = 1 ;
}
message ReceiptMessage {
enum Type {
DELIVERY = 0 ;
2025-04-15 15:22:31 +03:00
READ = 1 ;
VIEWED = 2 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional Type type = 1 ;
2023-04-21 10:49:54 -04:00
repeated uint64 timestamp = 2 ;
}
message TypingMessage {
2025-04-15 15:22:31 +03:00
enum Action {
STARTED = 0 ;
STOPPED = 1 ;
}
2023-04-21 10:49:54 -04:00
2025-04-15 15:22:31 +03:00
optional uint64 timestamp = 1 ;
optional Action action = 2 ;
optional bytes groupId = 3 ;
2023-04-21 10:49:54 -04:00
}
message StoryMessage {
2025-04-15 15:22:31 +03:00
optional bytes profileKey = 1 ;
optional GroupContextV2 group = 2 ;
2023-04-21 10:49:54 -04:00
oneof attachment {
AttachmentPointer fileAttachment = 3 ;
2025-04-15 15:22:31 +03:00
TextAttachment textAttachment = 4 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional bool allowsReplies = 5 ;
repeated BodyRange bodyRanges = 6 ;
2023-04-21 10:49:54 -04:00
}
message Preview {
2025-04-15 15:22:31 +03:00
optional string url = 1 ;
optional string title = 2 ;
optional AttachmentPointer image = 3 ;
optional string description = 4 ;
optional uint64 date = 5 ;
2023-04-21 10:49:54 -04:00
}
message TextAttachment {
enum Style {
2025-04-15 15:22:31 +03:00
DEFAULT = 0 ;
REGULAR = 1 ;
BOLD = 2 ;
SERIF = 3 ;
SCRIPT = 4 ;
2023-04-21 10:49:54 -04:00
CONDENSED = 5 ;
}
message Gradient {
2026-04-13 16:32:10 +03:00
// Color ordering:
// 0 degrees: bottom-to-top
// 90 degrees: left-to-right
// 180 degrees: top-to-bottom
// 270 degrees: right-to-left
2023-04-21 10:49:54 -04:00
optional uint32 startColor = 1 ; // deprecated: this field will be removed in a future release.
2025-04-15 15:22:31 +03:00
optional uint32 endColor = 2 ; // deprecated: this field will be removed in a future release.
optional uint32 angle = 3 ; // degrees
repeated uint32 colors = 4 ;
repeated float positions = 5 ; // percent from 0 to 1
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional string text = 1 ;
optional Style textStyle = 2 ;
optional uint32 textForegroundColor = 3 ; // integer representation of hex color
optional uint32 textBackgroundColor = 4 ;
optional Preview preview = 5 ;
2023-04-21 10:49:54 -04:00
oneof background {
Gradient gradient = 6 ;
2025-04-15 15:22:31 +03:00
uint32 color = 7 ;
2023-04-21 10:49:54 -04:00
}
}
message Verified {
enum State {
2025-04-15 15:22:31 +03:00
DEFAULT = 0 ;
VERIFIED = 1 ;
2023-04-21 10:49:54 -04:00
UNVERIFIED = 2 ;
}
2025-04-15 15:22:31 +03:00
reserved /*destinationE164*/ 1 ;
optional string destinationAci = 5 ;
optional bytes identityKey = 2 ;
optional State state = 3 ;
optional bytes nullMessage = 4 ;
2026-02-09 14:13:18 +02:00
optional bytes destinationAciBinary = 6 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message SyncMessage {
message Sent {
message UnidentifiedDeliveryStatus {
2025-04-15 15:22:31 +03:00
reserved /*destinationE164*/ 1 ;
optional string destinationServiceId = 3 ;
optional bool unidentified = 2 ;
reserved /*destinationPni */ 4 ;
optional bytes destinationPniIdentityKey = 5 ; // Only set for PNI destinations
2026-02-09 14:13:18 +02:00
optional bytes destinationServiceIdBinary = 6 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
2023-04-21 10:49:54 -04:00
}
message StoryMessageRecipient {
2023-12-21 18:06:58 +02:00
optional string destinationServiceId = 1 ;
2025-04-15 15:22:31 +03:00
repeated string distributionListIds = 2 ;
optional bool isAllowedToReply = 3 ;
reserved /*destinationPni */ 4 ;
2026-02-09 14:13:18 +02:00
optional bytes destinationServiceIdBinary = 5 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional string destinationE164 = 1 ;
optional string destinationServiceId = 7 ;
optional uint64 timestamp = 2 ;
optional DataMessage message = 3 ;
optional uint64 expirationStartTimestamp = 4 ;
repeated UnidentifiedDeliveryStatus unidentifiedStatus = 5 ;
optional bool isRecipientUpdate = 6 [ default = false ] ;
optional StoryMessage storyMessage = 8 ;
repeated StoryMessageRecipient storyMessageRecipients = 9 ;
optional EditMessage editMessage = 10 ;
reserved /*destinationPni */ 11 ;
2026-02-09 14:13:18 +02:00
optional bytes destinationServiceIdBinary = 12 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
// Next ID: 13
2023-04-21 10:49:54 -04:00
}
message Contacts {
2025-04-15 15:22:31 +03:00
optional AttachmentPointer blob = 1 ;
optional bool complete = 2 [ default = false ] ;
2023-04-21 10:49:54 -04:00
}
message Blocked {
2025-04-15 15:22:31 +03:00
repeated string numbers = 1 ;
repeated string acis = 3 ;
repeated bytes groupIds = 2 ;
2026-02-09 14:13:18 +02:00
repeated bytes acisBinary = 4 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message Request {
enum Type {
2025-04-15 15:22:31 +03:00
UNKNOWN = 0 ;
CONTACTS = 1 ;
reserved /*GROUPS*/ 2 ;
BLOCKED = 3 ;
2023-04-21 10:49:54 -04:00
CONFIGURATION = 4 ;
2025-04-15 15:22:31 +03:00
KEYS = 5 ;
reserved /*PNI_IDENTITY*/ 6 ;
2023-04-21 10:49:54 -04:00
}
optional Type type = 1 ;
}
message Read {
2025-04-15 15:22:31 +03:00
reserved /*senderE164*/ 1 ;
optional string senderAci = 3 ;
optional uint64 timestamp = 2 ;
2026-02-09 14:13:18 +02:00
optional bytes senderAciBinary = 4 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message Viewed {
2025-04-15 15:22:31 +03:00
reserved /*senderE164*/ 1 ;
optional string senderAci = 3 ;
optional uint64 timestamp = 2 ;
2026-02-09 14:13:18 +02:00
optional bytes senderAciBinary = 4 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message Configuration {
2025-04-15 15:22:31 +03:00
optional bool readReceipts = 1 ;
optional bool unidentifiedDeliveryIndicators = 2 ;
optional bool typingIndicators = 3 ;
reserved /* linkPreviews */ 4 ;
2026-04-13 16:32:10 +03:00
reserved /* provisioningVersion */ 5 ;
2025-04-15 15:22:31 +03:00
optional bool linkPreviews = 6 ;
2023-04-21 10:49:54 -04:00
}
message StickerPackOperation {
enum Type {
INSTALL = 0 ;
2025-04-15 15:22:31 +03:00
REMOVE = 1 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
optional bytes packId = 1 ;
2023-04-21 10:49:54 -04:00
optional bytes packKey = 2 ;
2025-04-15 15:22:31 +03:00
optional Type type = 3 ;
2023-04-21 10:49:54 -04:00
}
message ViewOnceOpen {
2025-04-15 15:22:31 +03:00
reserved /*senderE164*/ 1 ;
optional string senderAci = 3 ;
optional uint64 timestamp = 2 ;
2026-02-09 14:13:18 +02:00
optional bytes senderAciBinary = 4 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message FetchLatest {
enum Type {
2025-04-15 15:22:31 +03:00
UNKNOWN = 0 ;
LOCAL_PROFILE = 1 ;
STORAGE_MANIFEST = 2 ;
2023-04-21 10:49:54 -04:00
SUBSCRIPTION_STATUS = 3 ;
}
optional Type type = 1 ;
}
message Keys {
2025-04-15 15:22:31 +03:00
reserved /* storageService */ 1 ;
2026-04-13 16:32:10 +03:00
reserved /* master */ 2 ;
2024-12-02 13:14:44 +02:00
optional string accountEntropyPool = 3 ;
optional bytes mediaRootBackupKey = 4 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
message PniIdentity {
optional bytes publicKey = 1 ;
optional bytes privateKey = 2 ;
}
2023-04-21 10:49:54 -04:00
message MessageRequestResponse {
enum Type {
2025-04-15 15:22:31 +03:00
UNKNOWN = 0 ;
ACCEPT = 1 ;
DELETE = 2 ;
BLOCK = 3 ;
2023-04-21 10:49:54 -04:00
BLOCK_AND_DELETE = 4 ;
2025-04-15 15:22:31 +03:00
SPAM = 5 ;
BLOCK_AND_SPAM = 6 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
reserved /*threadE164*/ 1 ;
optional string threadAci = 2 ;
optional bytes groupId = 3 ;
optional Type type = 4 ;
2026-02-09 14:13:18 +02:00
optional bytes threadAciBinary = 5 ; // 16-byte UUID
2023-04-21 10:49:54 -04:00
}
message OutgoingPayment {
message MobileCoin {
2025-04-15 15:22:31 +03:00
optional bytes recipientAddress = 1 ;
optional uint64 amountPicoMob = 2 ;
optional uint64 feePicoMob = 3 ;
optional bytes receipt = 4 ;
2023-04-21 10:49:54 -04:00
optional uint64 ledgerBlockTimestamp = 5 ;
2025-04-15 15:22:31 +03:00
optional uint64 ledgerBlockIndex = 6 ;
repeated bytes spentKeyImages = 7 ;
repeated bytes outputPublicKeys = 8 ;
2023-04-21 10:49:54 -04:00
}
2023-12-21 18:06:58 +02:00
optional string recipientServiceId = 1 ;
2025-04-15 15:22:31 +03:00
optional string note = 2 ;
oneof attachment_identifier {
2023-04-21 10:49:54 -04:00
MobileCoin mobileCoin = 3 ;
}
}
message PniChangeNumber {
2025-04-15 15:22:31 +03:00
optional bytes identityKeyPair = 1 ; // Serialized libsignal-client IdentityKeyPair
optional bytes signedPreKey = 2 ; // Serialized libsignal-client SignedPreKeyRecord
optional bytes lastResortKyberPreKey = 5 ; // Serialized libsignal-client KyberPreKeyRecord
optional uint32 registrationId = 3 ;
optional string newE164 = 4 ; // The e164 we have changed our number to
2023-12-21 18:06:58 +02:00
// Next ID: 6
2023-04-21 10:49:54 -04:00
}
message CallEvent {
enum Type {
UNKNOWN_TYPE = 0 ;
2025-04-15 15:22:31 +03:00
AUDIO_CALL = 1 ;
VIDEO_CALL = 2 ;
GROUP_CALL = 3 ;
AD_HOC_CALL = 4 ;
2023-04-21 10:49:54 -04:00
}
enum Direction {
UNKNOWN_DIRECTION = 0 ;
2025-04-15 15:22:31 +03:00
INCOMING = 1 ;
OUTGOING = 2 ;
2023-04-21 10:49:54 -04:00
}
enum Event {
2025-04-15 15:22:31 +03:00
UNKNOWN_EVENT = 0 ;
ACCEPTED = 1 ;
NOT_ACCEPTED = 2 ;
DELETE = 3 ;
OBSERVED = 4 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
/ * Data identifying a conversation. The service ID for 1 : 1 , the group ID for
* group , or the room ID for an ad - hoc call. See also
* ` CallLogEvent / conversationId ` . * /
optional bytes conversationId = 1 ;
/ * An identifier for a call. Generated directly for 1 : 1 , or derived from
* the era ID for group and ad - hoc calls. See also ` CallLogEvent / callId ` . * /
optional uint64 callId = 2 ;
optional uint64 timestamp = 3 ;
optional Type type = 4 ;
optional Direction direction = 5 ;
optional Event event = 6 ;
2023-12-21 18:06:58 +02:00
}
message CallLinkUpdate {
2024-03-08 23:26:16 +02:00
enum Type {
UPDATE = 0 ;
2024-10-02 21:24:47 +03:00
reserved 1 ; // was DELETE, superseded by storage service
2024-03-08 23:26:16 +02:00
}
2025-04-15 15:22:31 +03:00
optional bytes rootKey = 1 ;
optional bytes adminPasskey = 2 ;
optional Type type = 3 ; // defaults to UPDATE
2026-04-13 16:32:10 +03:00
reserved /*epoch*/ 4 ;
2023-12-21 18:06:58 +02:00
}
message CallLogEvent {
enum Type {
2025-04-15 15:22:31 +03:00
CLEAR = 0 ;
MARKED_AS_READ = 1 ;
2024-06-14 15:43:59 +03:00
MARKED_AS_READ_IN_CONVERSATION = 2 ;
2025-04-15 15:22:31 +03:00
CLEAR_IN_CONVERSATION = 3 ;
2023-12-21 18:06:58 +02:00
}
2025-04-15 15:22:31 +03:00
optional Type type = 1 ;
optional uint64 timestamp = 2 ;
2024-06-14 15:43:59 +03:00
/ * Data identifying a conversation. The service ID for 1 : 1 , the group ID for
* group , or the room ID for an ad - hoc call. See also
* ` CallEvent / conversationId ` . * /
optional bytes conversationId = 3 ;
/ * An identifier for a call. Generated directly for 1 : 1 , or derived from
* the era ID for group and ad - hoc calls. See also ` CallEvent / callId ` . * /
2025-04-15 15:22:31 +03:00
optional uint64 callId = 4 ;
2024-06-14 15:43:59 +03:00
}
message DeleteForMe {
message MessageDeletes {
optional ConversationIdentifier conversation = 1 ;
repeated AddressableMessage messages = 2 ;
}
2024-07-10 20:40:07 +03:00
message AttachmentDelete {
optional ConversationIdentifier conversation = 1 ;
optional AddressableMessage targetMessage = 2 ;
2025-04-15 15:22:31 +03:00
// The `clientUuid` from `AttachmentPointer`.
optional bytes clientUuid = 3 ;
// SHA256 hash of the (encrypted, padded, etc.) attachment blob on the CDN.
2024-07-10 20:40:07 +03:00
optional bytes fallbackDigest = 4 ;
2025-04-15 15:22:31 +03:00
// SHA256 hash of the plaintext content of the attachment.
2024-07-10 20:40:07 +03:00
optional bytes fallbackPlaintextHash = 5 ;
}
2024-06-14 15:43:59 +03:00
message ConversationDelete {
optional ConversationIdentifier conversation = 1 ;
repeated AddressableMessage mostRecentMessages = 2 ;
optional bool isFullDelete = 3 ;
2025-04-15 15:22:31 +03:00
repeated AddressableMessage mostRecentNonExpiringMessages = 4 ;
2024-06-14 15:43:59 +03:00
}
message LocalOnlyConversationDelete {
optional ConversationIdentifier conversation = 1 ;
}
repeated MessageDeletes messageDeletes = 1 ;
repeated ConversationDelete conversationDeletes = 2 ;
repeated LocalOnlyConversationDelete localOnlyConversationDeletes = 3 ;
2024-07-10 20:40:07 +03:00
repeated AttachmentDelete attachmentDeletes = 4 ;
2023-04-21 10:49:54 -04:00
}
2024-12-11 19:57:03 +02:00
message DeviceNameChange {
2025-04-15 15:22:31 +03:00
reserved /*name*/ 1 ;
2024-12-11 19:57:03 +02:00
optional uint32 deviceId = 2 ;
}
2025-04-15 15:22:31 +03:00
message AttachmentBackfillRequest {
optional AddressableMessage targetMessage = 1 ;
optional ConversationIdentifier targetConversation = 2 ;
}
message AttachmentBackfillResponse {
message AttachmentData {
enum Status {
PENDING = 0 ;
TERMINAL_ERROR = 1 ;
}
oneof data {
AttachmentPointer attachment = 1 ;
Status status = 2 ;
}
}
enum Error {
MESSAGE_NOT_FOUND = 0 ;
}
message AttachmentDataList {
repeated AttachmentData attachments = 1 ;
optional AttachmentData longText = 2 ;
}
optional AddressableMessage targetMessage = 1 ;
optional ConversationIdentifier targetConversation = 2 ;
oneof data {
AttachmentDataList attachments = 3 ;
Error error = 4 ;
}
}
2026-06-05 00:07:51 +03:00
message UsernameChange { }
2026-04-13 16:32:10 +03:00
oneof content {
Sent sent = 1 ;
Contacts contacts = 2 ;
Request request = 4 ;
Blocked blocked = 6 ;
Verified verified = 7 ;
Configuration configuration = 9 ;
ViewOnceOpen viewOnceOpen = 11 ;
FetchLatest fetchLatest = 12 ;
Keys keys = 13 ;
MessageRequestResponse messageRequestResponse = 14 ;
OutgoingPayment outgoingPayment = 15 ;
PniChangeNumber pniChangeNumber = 18 ;
CallEvent callEvent = 19 ;
CallLinkUpdate callLinkUpdate = 20 ;
CallLogEvent callLogEvent = 21 ;
DeleteForMe deleteForMe = 22 ;
DeviceNameChange deviceNameChange = 23 ;
AttachmentBackfillRequest attachmentBackfillRequest = 24 ;
AttachmentBackfillResponse attachmentBackfillResponse = 25 ;
2026-06-05 00:07:51 +03:00
UsernameChange usernameChange = 26 ;
2026-04-13 16:32:10 +03:00
}
2025-04-15 15:22:31 +03:00
reserved /*groups*/ 3 ;
2026-04-13 16:32:10 +03:00
// Protobufs don't allow `repeated` fields to be inside of `oneof` so while
// the fields below are mutually exclusive with the rest of the values above
// we have to place them outside of `oneof`.
2025-04-15 15:22:31 +03:00
repeated Read read = 5 ;
repeated StickerPackOperation stickerPackOperation = 10 ;
repeated Viewed viewed = 16 ;
2026-04-13 16:32:10 +03:00
2025-04-15 15:22:31 +03:00
reserved /*pniIdentity*/ 17 ;
2026-04-13 16:32:10 +03:00
optional bytes padding = 8 ;
2023-04-21 10:49:54 -04:00
}
message AttachmentPointer {
enum Flags {
VOICE_MESSAGE = 1 ;
2025-04-15 15:22:31 +03:00
BORDERLESS = 2 ;
reserved 4 ;
GIF = 8 ;
2023-04-21 10:49:54 -04:00
}
oneof attachment_identifier {
2025-04-15 15:22:31 +03:00
fixed64 cdnId = 1 ;
string cdnKey = 15 ;
}
// Cross-client identifier for this attachment among all attachments on the
// owning message.
optional bytes clientUuid = 20 ;
optional string contentType = 2 ;
optional bytes key = 3 ;
optional uint32 size = 4 ;
optional bytes thumbnail = 5 ;
optional bytes digest = 6 ;
reserved /* incrementalMac with implicit chunk sizing */ 16 ;
reserved /* incrementalMac for all attachment types */ 18 ;
optional bytes incrementalMac = 19 ;
optional uint32 chunkSize = 17 ;
optional string fileName = 7 ;
optional uint32 flags = 8 ;
optional uint32 width = 9 ;
optional uint32 height = 10 ;
optional string caption = 11 ;
optional string blurHash = 12 ;
optional uint64 uploadTimestamp = 13 ;
optional uint32 cdnNumber = 14 ;
2024-07-10 20:40:07 +03:00
// Next ID: 21
2023-04-21 10:49:54 -04:00
}
message GroupContextV2 {
2025-04-15 15:22:31 +03:00
optional bytes masterKey = 1 ;
optional uint32 revision = 2 ;
optional bytes groupChange = 3 ;
2023-04-21 10:49:54 -04:00
}
message ContactDetails {
message Avatar {
optional string contentType = 1 ;
2025-04-15 15:22:31 +03:00
optional uint32 length = 2 ;
}
optional string number = 1 ;
optional string aci = 9 ;
2026-02-09 14:13:18 +02:00
optional bytes aciBinary = 13 ; // 16-byte UUID
2025-04-15 15:22:31 +03:00
optional string name = 2 ;
optional Avatar avatar = 3 ;
reserved /* color */ 4 ;
reserved /* verified */ 5 ;
reserved /* profileKey */ 6 ;
reserved /* blocked */ 7 ;
optional uint32 expireTimer = 8 ;
optional uint32 expireTimerVersion = 12 ;
optional uint32 inboxPosition = 10 ;
reserved /* archived */ 11 ;
2026-02-09 14:13:18 +02:00
// NEXT ID: 14
2023-04-21 10:49:54 -04:00
}
message PaymentAddress {
2025-04-15 15:22:31 +03:00
message MobileCoin {
optional bytes publicAddress = 1 ;
optional bytes signature = 2 ;
2023-04-21 10:49:54 -04:00
}
2025-04-15 15:22:31 +03:00
oneof Address {
MobileCoin mobileCoin = 1 ;
2023-04-21 10:49:54 -04:00
}
}
message DecryptionErrorMessage {
2025-04-15 15:22:31 +03:00
optional bytes ratchetKey = 1 ; // set to the public ratchet key from the SignalMessage if a 1-1 payload fails to decrypt
optional uint64 timestamp = 2 ;
optional uint32 deviceId = 3 ;
2023-04-21 10:49:54 -04:00
}
message PniSignatureMessage {
2025-04-15 15:22:31 +03:00
optional bytes pni = 1 ;
// Signature *by* the PNI identity key *of* the ACI identity key
2023-04-21 10:49:54 -04:00
optional bytes signature = 2 ;
2023-07-10 11:45:45 -04:00
}
2023-12-21 18:06:58 +02:00
message EditMessage {
2025-04-15 15:22:31 +03:00
optional uint64 targetSentTimestamp = 1 ;
optional DataMessage dataMessage = 2 ;
}
message BodyRange {
enum Style {
NONE = 0 ;
BOLD = 1 ;
ITALIC = 2 ;
SPOILER = 3 ;
STRIKETHROUGH = 4 ;
MONOSPACE = 5 ;
}
optional uint32 start = 1 ; // Starting index in UTF-16 code units/raw string representation
optional uint32 length = 2 ; // Length of range in UTF-16 code units/raw string representation
oneof associatedValue {
string mentionAci = 3 ;
Style style = 4 ;
2026-02-09 14:13:18 +02:00
bytes mentionAciBinary = 5 ; // 16-byte UUID
2025-04-15 15:22:31 +03:00
}
}
message AddressableMessage {
oneof author {
string authorServiceId = 1 ;
string authorE164 = 2 ;
2026-02-09 14:13:18 +02:00
bytes authorServiceIdBinary = 4 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
2025-04-15 15:22:31 +03:00
}
optional uint64 sentTimestamp = 3 ;
}
message ConversationIdentifier {
oneof identifier {
string threadServiceId = 1 ;
bytes threadGroupId = 2 ;
string threadE164 = 3 ;
2026-02-09 14:13:18 +02:00
bytes threadServiceIdBinary = 4 ; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
2025-04-15 15:22:31 +03:00
}
2023-12-21 18:06:58 +02:00
}