# RPC Reference **Proto package:** `qpc.v1` **Proto files:** 14 files in `proto/qpc/v1/` **Total methods:** 44 This page is the complete Protobuf definition reference for all 14 proto files in the v2 RPC protocol. For transport framing, see [Wire Format Overview](overview.md). For method ID assignments, see [Method ID Reference](envelope-schema.md). Generated Rust types live in `crates/quicprochat-proto/src/` (via prost). --- ## auth.proto (IDs 100-103) OPAQUE asymmetric PAKE for registration and login. See [Auth Schema](auth-schema.md) for field-level documentation and flow diagrams. ```protobuf syntax = "proto3"; package qpc.v1; message OpaqueRegisterStartRequest { string username = 1; bytes request = 2; } message OpaqueRegisterStartResponse { bytes response = 1; } message OpaqueRegisterFinishRequest { string username = 1; bytes upload = 2; bytes identity_key = 3; } message OpaqueRegisterFinishResponse { bool success = 1; } message OpaqueLoginStartRequest { string username = 1; bytes request = 2; } message OpaqueLoginStartResponse { bytes response = 1; } message OpaqueLoginFinishRequest { string username = 1; bytes finalization = 2; bytes identity_key = 3; } message OpaqueLoginFinishResponse { bytes session_token = 1; } ``` --- ## common.proto Shared types and account deletion. ```protobuf syntax = "proto3"; package qpc.v1; // Auth context for federation and internal use. // In v2, session authentication is carried at the QUIC connection level // (session token), not per-message. message Auth { bytes access_token = 1; bytes device_id = 2; } // Account deletion (ID 950). message DeleteAccountRequest {} message DeleteAccountResponse { bool success = 1; } ``` `DeleteAccountRequest` is empty; the server derives the user identity from the authenticated QUIC session. On success, all user data is purged: OPAQUE record, identity keys, key packages, hybrid keys, queued deliveries, channel memberships, devices, and recovery bundles. --- ## delivery.proto (IDs 200-205) Store-and-forward message relay. See [Delivery Schema](delivery-schema.md) for field-level documentation. ```protobuf syntax = "proto3"; package qpc.v1; message Envelope { uint64 seq = 1; bytes data = 2; } message EnqueueRequest { bytes recipient_key = 1; bytes payload = 2; bytes channel_id = 3; uint32 ttl_secs = 4; bytes message_id = 5; } message EnqueueResponse { uint64 seq = 1; bytes delivery_proof = 2; bool duplicate = 3; } message FetchRequest { bytes recipient_key = 1; bytes channel_id = 2; uint32 limit = 3; bytes device_id = 4; } message FetchResponse { repeated Envelope payloads = 1; } message FetchWaitRequest { bytes recipient_key = 1; bytes channel_id = 2; uint64 timeout_ms = 3; uint32 limit = 4; bytes device_id = 5; } message FetchWaitResponse { repeated Envelope payloads = 1; } message PeekRequest { bytes recipient_key = 1; bytes channel_id = 2; uint32 limit = 3; bytes device_id = 4; } message PeekResponse { repeated Envelope payloads = 1; } message AckRequest { bytes recipient_key = 1; bytes channel_id = 2; uint64 seq_up_to = 3; bytes device_id = 4; } message AckResponse {} message BatchEnqueueRequest { repeated bytes recipient_keys = 1; bytes payload = 2; bytes channel_id = 3; uint32 ttl_secs = 4; bytes message_id = 5; } message BatchEnqueueResponse { repeated uint64 seqs = 1; } ``` --- ## keys.proto (IDs 300-304, 510-520) MLS KeyPackages, hybrid PQ keys, and key transparency. See [Delivery Schema](delivery-schema.md) for field-level documentation. ```protobuf syntax = "proto3"; package qpc.v1; message UploadKeyPackageRequest { bytes identity_key = 1; bytes package = 2; } message UploadKeyPackageResponse { bytes fingerprint = 1; } message FetchKeyPackageRequest { bytes identity_key = 1; } message FetchKeyPackageResponse { bytes package = 1; } message UploadHybridKeyRequest { bytes identity_key = 1; bytes hybrid_public_key = 2; } message UploadHybridKeyResponse {} message FetchHybridKeyRequest { bytes identity_key = 1; } message FetchHybridKeyResponse { bytes hybrid_public_key = 1; } message FetchHybridKeysRequest { repeated bytes identity_keys = 1; } message FetchHybridKeysResponse { repeated bytes keys = 1; } // Key revocation (ID 510). message RevokeKeyRequest { bytes identity_key = 1; string reason = 2; } message RevokeKeyResponse { bool success = 1; uint64 leaf_index = 2; } // Check revocation status (ID 511). message CheckRevocationRequest { bytes identity_key = 1; } message CheckRevocationResponse { bool revoked = 1; string reason = 2; uint64 timestamp_ms = 3; } // KT audit log retrieval (ID 520). message AuditKeyTransparencyRequest { uint64 start = 1; uint64 end = 2; } message AuditKeyTransparencyResponse { repeated LogEntry entries = 1; uint64 tree_size = 2; bytes root = 3; } message LogEntry { uint64 index = 1; bytes leaf_hash = 2; } ``` --- ## channel.proto (ID 400) ```protobuf syntax = "proto3"; package qpc.v1; // Channel create (1 method). // Method ID: 400. message CreateChannelRequest { bytes peer_key = 1; } message CreateChannelResponse { bytes channel_id = 1; bool was_new = 2; } ``` `CreateChannel` deterministically derives a channel ID from the calling user's identity key and `peer_key`, so repeated calls with the same peer return the same `channel_id`. `was_new` is `true` on the first creation. --- ## group.proto (IDs 410-413) Group management: member removal, metadata, member listing, and key rotation. ```protobuf syntax = "proto3"; package qpc.v1; // Group management (4 methods). // Method IDs: 410-413. message RemoveMemberRequest { bytes group_id = 1; bytes member_identity_key = 2; } message RemoveMemberResponse { bytes commit = 1; } message UpdateGroupMetadataRequest { bytes group_id = 1; string name = 2; string description = 3; bytes avatar_hash = 4; } message UpdateGroupMetadataResponse { bool success = 1; } message ListGroupMembersRequest { bytes group_id = 1; } message ListGroupMembersResponse { repeated GroupMemberInfo members = 1; } message GroupMemberInfo { bytes identity_key = 1; string username = 2; uint64 joined_at = 3; } message RotateKeysRequest { bytes group_id = 1; } message RotateKeysResponse { bytes commit = 1; } // Server-side group metadata store. message GroupMetadata { bytes group_id = 1; string name = 2; string description = 3; bytes avatar_hash = 4; bytes creator_key = 5; uint64 created_at = 6; } ``` `RemoveMember` and `RotateKeys` return a `commit` field containing the MLS `Commit` message bytes that the caller must fan-out to the remaining group members via `BatchEnqueue`. `joined_at` in `GroupMemberInfo` is a Unix timestamp in milliseconds. --- ## moderation.proto (IDs 420-424) Content moderation: encrypted reports, bans, and audit lists. ```protobuf syntax = "proto3"; package qpc.v1; // Moderation service: report, ban, unban, list reports, list banned. // Method IDs: 420-424. message ReportMessageRequest { bytes encrypted_report = 1; bytes conversation_id = 2; } message ReportMessageResponse { bool accepted = 1; } message BanUserRequest { bytes identity_key = 1; string reason = 2; uint64 duration_secs = 3; } message BanUserResponse { bool success = 1; } message UnbanUserRequest { bytes identity_key = 1; } message UnbanUserResponse { bool success = 1; } message ListReportsRequest { uint32 limit = 1; uint32 offset = 2; } message ReportEntry { uint64 id = 1; bytes encrypted_report = 2; bytes conversation_id = 3; bytes reporter_identity = 4; uint64 timestamp = 5; } message ListReportsResponse { repeated ReportEntry reports = 1; } message ListBannedRequest {} message BannedUserEntry { bytes identity_key = 1; string reason = 2; uint64 banned_at = 3; uint64 expires_at = 4; // 0 = permanent ban. } message ListBannedResponse { repeated BannedUserEntry users = 1; } ``` `ReportMessageRequest.encrypted_report` is encrypted asymmetrically to the server's admin key; the server cannot read it without the admin private key. `BanUserRequest.duration_secs = 0` is a permanent ban. `BannedUserEntry.expires_at = 0` denotes a permanent ban. --- ## user.proto (IDs 500-501) Forward and reverse user resolution. ```protobuf syntax = "proto3"; package qpc.v1; // User resolve + identity (2 methods). // Method IDs: 500-501. message ResolveUserRequest { string username = 1; } message ResolveUserResponse { bytes identity_key = 1; bytes inclusion_proof = 2; } message ResolveIdentityRequest { bytes identity_key = 1; } message ResolveIdentityResponse { string username = 1; } ``` `ResolveUser` returns the user's Ed25519 identity key (32 bytes) along with a key-transparency inclusion proof. `ResolveIdentity` is the reverse lookup: given a key, return the username. --- ## blob.proto (IDs 600-601) Content-addressed binary object storage with chunked upload and ranged download. ```protobuf syntax = "proto3"; package qpc.v1; // Blob upload/download (2 methods). // Method IDs: 600-601. message UploadBlobRequest { bytes blob_hash = 1; bytes chunk = 2; uint64 offset = 3; uint64 total_size = 4; string mime_type = 5; } message UploadBlobResponse { bytes blob_id = 1; } message DownloadBlobRequest { bytes blob_id = 1; uint64 offset = 2; uint32 length = 3; } message DownloadBlobResponse { bytes chunk = 1; uint64 total_size = 2; string mime_type = 3; } ``` `UploadBlob` accepts chunks; callers send multiple requests for large blobs using `offset` + `total_size` for reassembly. `blob_hash` is the SHA-256 of the entire blob (content addressing). `DownloadBlob` supports ranged reads via `offset` + `length`. --- ## device.proto (IDs 700-702, 710) Multi-device management and push notification token registration. ```protobuf syntax = "proto3"; package qpc.v1; // Device register/list/revoke (3 methods). // Method IDs: 700-702. message RegisterDeviceRequest { bytes device_id = 1; string device_name = 2; } message RegisterDeviceResponse { bool success = 1; } message ListDevicesRequest {} message ListDevicesResponse { repeated Device devices = 1; } message Device { bytes device_id = 1; string device_name = 2; uint64 registered_at = 3; } message RevokeDeviceRequest { bytes device_id = 1; } message RevokeDeviceResponse { bool success = 1; } // Push notification token registration (ID 710). enum PushPlatform { PUSH_PLATFORM_UNSPECIFIED = 0; PUSH_PLATFORM_APNS = 1; PUSH_PLATFORM_FCM = 2; PUSH_PLATFORM_WEB_PUSH = 3; } message RegisterPushTokenRequest { bytes device_id = 1; PushPlatform platform = 2; string token = 3; } message RegisterPushTokenResponse { bool success = 1; } ``` `Device.registered_at` is a Unix timestamp in milliseconds. `Device.device_id` is a client-generated UUID (16 bytes). `RegisterPushToken` associates a platform-specific push token with the device for server-initiated push notifications. --- ## recovery.proto (IDs 750-752) Encrypted account recovery bundle storage. The server stores an opaque blob indexed by `SHA-256(recovery_token)`. The plaintext recovery token and bundle contents are never visible to the server. ```protobuf syntax = "proto3"; package qpc.v1; // Recovery service. // Method IDs: 750-752. message StoreRecoveryBundleRequest { bytes token_hash = 1; // SHA-256(recovery_token) bytes bundle = 2; // Encrypted recovery bundle (opaque to server). uint64 ttl_secs = 3; // Default 90 days = 7776000. } message StoreRecoveryBundleResponse { bool success = 1; } message FetchRecoveryBundleRequest { bytes token_hash = 1; // SHA-256(recovery_token) } message FetchRecoveryBundleResponse { bytes bundle = 1; // Empty if no bundle found. } message DeleteRecoveryBundleRequest { bytes token_hash = 1; // SHA-256(recovery_token) } message DeleteRecoveryBundleResponse { bool success = 1; } ``` --- ## p2p.proto (IDs 800-802) iroh P2P node address exchange and server health probe. ```protobuf syntax = "proto3"; package qpc.v1; // P2P endpoint publish/resolve + health (3 methods). // Method IDs: 800-802. message PublishEndpointRequest { bytes identity_key = 1; bytes node_addr = 2; } message PublishEndpointResponse {} message ResolveEndpointRequest { bytes identity_key = 1; } message ResolveEndpointResponse { bytes node_addr = 1; } message HealthRequest {} message HealthResponse { string status = 1; string node_id = 2; string version = 3; uint64 uptime_secs = 4; string storage_backend = 5; } ``` `node_addr` is an iroh `NodeAddr` serialised to bytes. `HealthResponse.storage_backend` is one of `"sql"`, `"file"`, or `"postgres"`. `HealthRequest` requires no authentication and is suitable for infrastructure health checks. --- ## federation.proto (IDs 900-905) Cross-server relay and proxy operations. All federation methods include a `FederationAuth` struct carrying the origin server's domain for inter-server authentication. ```protobuf syntax = "proto3"; package qpc.v1; // Federation relay + proxy (6 methods). // Method IDs: 900-905. message FederationAuth { string origin = 1; } message RelayEnqueueRequest { bytes recipient_key = 1; bytes payload = 2; bytes channel_id = 3; FederationAuth auth = 4; } message RelayEnqueueResponse { uint64 seq = 1; } message RelayBatchEnqueueRequest { repeated bytes recipient_keys = 1; bytes payload = 2; bytes channel_id = 3; FederationAuth auth = 4; } message RelayBatchEnqueueResponse { repeated uint64 seqs = 1; } message ProxyFetchKeyPackageRequest { bytes identity_key = 1; FederationAuth auth = 2; } message ProxyFetchKeyPackageResponse { bytes package = 1; } message ProxyFetchHybridKeyRequest { bytes identity_key = 1; FederationAuth auth = 2; } message ProxyFetchHybridKeyResponse { bytes hybrid_public_key = 1; } message ProxyResolveUserRequest { string username = 1; FederationAuth auth = 2; } message ProxyResolveUserResponse { bytes identity_key = 1; } message FederationHealthRequest {} message FederationHealthResponse { string status = 1; string server_domain = 2; } ``` Federation relay methods (`RelayEnqueue`, `RelayBatchEnqueue`) are analogous to the client-facing delivery methods but originate from a peer server rather than a client. Proxy methods allow one server to fetch resources (key packages, hybrid keys, user identities) on behalf of a user whose home server is remote. --- ## push.proto (Event IDs 1000-1003) Server-push event types sent on QUIC uni-streams using the push frame format. ```protobuf syntax = "proto3"; package qpc.v1; // Server-push event types (sent on QUIC uni-streams). // Event type IDs: 1000+. message PushEvent { oneof event { NewMessage new_message = 1; TypingIndicator typing = 2; PresenceUpdate presence = 3; GroupMembershipChange membership = 4; } } message NewMessage { bytes channel_id = 1; bytes sender_key = 2; uint64 seq = 3; bytes payload = 4; uint64 timestamp_ms = 5; } message TypingIndicator { bytes channel_id = 1; bytes sender_key = 2; bool is_typing = 3; } message PresenceUpdate { bytes identity_key = 1; bool online = 2; uint64 last_seen_ms = 3; } message GroupMembershipChange { bytes channel_id = 1; bytes actor_key = 2; bytes target_key = 3; MembershipAction action = 4; } enum MembershipAction { MEMBERSHIP_ACTION_UNSPECIFIED = 0; MEMBERSHIP_ACTION_ADDED = 1; MEMBERSHIP_ACTION_REMOVED = 2; MEMBERSHIP_ACTION_LEFT = 3; } ``` Push events are sent by the server without a client request. The `event_type` field in the push frame header (see [Wire Format Overview](overview.md)) determines which `oneof` variant is present. Clients must handle all event types and ignore unknown types gracefully. --- ## Further reading - [Wire Format Overview](overview.md) -- frame format and transport parameters - [Method ID Reference](envelope-schema.md) -- complete method ID table - [Auth Schema](auth-schema.md) -- OPAQUE flow documentation - [Delivery Schema](delivery-schema.md) -- delivery and key management documentation - [Authentication Service Internals](../internals/authentication-service.md) -- server-side OPAQUE flow - [Storage Backend](../internals/storage-backend.md) -- how data is persisted