Generated from src/spec/. Every shape here was written down once, in TypeScript, and the
validators, the opcode registry and this page all come from that one place.
Confidence says what the shape rests on. measured means we sent it and read the answer;
confirmed means two independent implementations agree and we have not run it; observed
means one does; inferred means it follows from something next to it; unknown means the
sources disagree.
| Operation | Opcode | MAX's name | When | Confidence | Where it came from |
|---|---|---|---|---|---|
session.init |
6 | SESSION_INIT |
before login | measured | measured against MAX 2026-09-19; max-api-docs/protocol/auth.md; tsmax createWebAgent |
session.login |
19 | LOGIN |
before login | measured | measured against MAX 2026-09-19; measured against MAX 2026-09-20 (messages is an object); measured against MAX 2026-09-22 (token replaces a stale credential once, then repeats) |
session.ping |
1 | PING |
after login | confirmed | web.max.ru bundle read 2026-09-24: cmd(1, {interactive}) every 30 s; PyMax Opcode.PING = 1 |
session.log |
5 | LOG |
after login | observed | web.max.ru frames captured 2026-09-25 (docs/dev/capture/2026-09-25-web-tab.md): a hidden tab's only event, answered with an empty body; ids wrapped in extension 1 and times plain: inferred from the frame's unpacked size, 144 bytes, which only that encoding gives |
session.logout |
20 | LOGOUT |
never sent | observed | max-api-docs/protocol/auth.md |
login.qrRequest |
288 | GET_QR |
before login | measured | measured against MAX 2026-09-24: session start qr logged in; PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0; max-api-docs/protocol/auth.md (dac4b19) |
login.qrStatus |
289 | GET_QR_STATUS |
before login | measured | measured against MAX 2026-09-24: session start qr logged in; PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0; max-api-docs/protocol/auth.md (dac4b19) |
login.byQr |
291 | LOGIN_BY_QR |
before login | measured | measured against MAX 2026-09-24: session start qr logged in; PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0 |
login.qrApprove |
290 | AUTH_QR_APPROVE |
never sent | observed | PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0 |
login.smsRequest |
17 | AUTH_REQUEST |
before login | confirmed | PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0; max-api-docs/protocol/auth.md (dac4b19) |
login.smsCode |
18 | AUTH |
before login | confirmed | PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0; max-api-docs/protocol/auth.md (dac4b19) |
login.password |
115 | AUTH_LOGIN_CHECK_PASSWORD |
before login | measured | measured against MAX 2026-09-24: session start qr on an account with a cloud password; PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0 |
contacts.info |
32 | CONTACT_INFO |
after login | measured | measured against MAX 2026-09-19: asked for ten, got ten |
contacts.byPhone |
46 | CONTACT_INFO_BY_PHONE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account): the owner's own number answered with the owner; web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 search_by_phone |
contacts.update |
34 | CONTACT_UPDATE |
after login | measured | measured 2026-09-27: max contacts add then remove on a person the owner named; the owner saw the contact appear in the app; measured 2026-09-27 (pnpm probe:profile), on a person who agreed: UPDATE answers {contact} and keeps the name as a CUSTOM entry beside theirs; BLOCK and UNBLOCK answer {}, and CONTACT_INFO shows status: BLOCKED in between; captured 2026-09-28 from web.max.ru renaming a contact: {contactId: <wrapped id>, action: "UPDATE", firstName, lastName: null}. Measured the same day: without lastName MAX answers {contact} with the old CUSTOM name and changes nothing; with lastName: null the rename holds on a separate CONTACT_INFO read; web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 add_contact, remove_contact |
contacts.import |
21 | SYNC |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account), the owner's own number only: answered {phones: {<number>: <number>}} and no contact; PyMax 53103f0 import_contacts |
protocol.unidentified36 |
36 | UNIDENTIFIED_36 |
never sent | unknown | tsmax and PyMax call it CONTACT_LIST; max-api-docs calls it GET_BLOCKED; measured against MAX 2026-09-20: {} and {marker} are refused with proto.payload, {marker, count} closes the connection |
account.update |
16 | PROFILE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account): the profile rewritten with its own values answered {profile} shaped like LOGIN's; measured 2026-09-27 (pnpm probe:profile): photoToken from an upload with profile: true and avatarType set the photo — confirmed by the owner in the app; MAX's answers were not kept (BUG-67); web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 change_profile; measured against MAX 2026-09-19: refused an empty payload |
account.sessions |
96 | SESSIONS_INFO |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account): {client, current, info, location, time} per session — no id; web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 get_sessions |
account.closeSessions |
97 | SESSIONS_CLOSE |
after login | confirmed | web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 close_all_sessions |
folders.list |
272 | FOLDERS_GET |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account): no folder of the owner's carries include; web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 get_folders |
folders.update |
274 | FOLDERS_UPDATE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account): created, renamed and deleted a folder; a 21-character title came back folder.validation.title.too-long, 15 was taken; a chat put in and taken out measured 2026-09-27 (`max chats folders update --add |
folders.delete |
276 | FOLDERS_DELETE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:account); web.max.ru chunk _app/immutable/chunks/5oCuRT0F.js, read 2026-09-24; PyMax 53103f0 delete_folder |
banners.list |
302 | BANNERS_GET |
after login | observed | web.max.ru tab, recorded 2026-09-25 (docs_ai/captures/2026-09-25-web-tab-2.jsonl); PyMax 53103f0 names it BANNERS_GET |
calls.history |
163 | CALL_HISTORY |
after login | observed | web.max.ru tab, recorded 2026-09-25 (docs_ai/captures/2026-09-25-web-tab-2.jsonl) |
assets.update |
27 | ASSETS_UPDATE |
after login | observed | web.max.ru tab, recorded 2026-09-25 (docs_ai/captures/2026-09-25-web-tab-2.jsonl); PyMax 53103f0 names it ASSETS_UPDATE and never sends it |
chats.history |
49 | CHAT_HISTORY |
after login | measured | measured against MAX 2026-09-19; DELAYED from web.max.ru (2026-09-24, FIND-78), measured 2026-09-24 in Saved messages (pnpm probe:scheduled) |
chats.mark |
50 | CHAT_MARK |
after login | measured | web.max.ru frame captured 2026-09-25 opening an unread channel: type, chatId, messageId, mark (RES-10); its code sets mark to the message's time; measured against MAX 2026-09-25 in Saved messages (pnpm smoke:live, MAX-56); PyMax api/messages/service.py read_message (53103f0) |
chats.list |
53 | CHATS_LIST |
after login | measured | measured against MAX 2026-09-19; max-api-docs/protocol/chats.md |
chats.linkInfo |
89 | LINK_INFO |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:groups); PyMax resolve_group_by_link |
chats.join |
57 | CHAT_JOIN |
after login | measured | measured against MAX 2026-09-24 with a private group link (pnpm probe:groups); PyMax join_group |
chats.leave |
58 | CHAT_LEAVE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:groups); PyMax leave_group |
chats.update |
55 | CHAT_UPDATE |
after login | measured | measured against MAX 2026-09-24 (pnpm probe:groups, pnpm probe:members); PyMax change_group_profile, change_group_settings, rework_invite_link; the pin: measured 2026-09-24 in a group the owner named (pnpm probe:edit-pin-forward, PIN_CHAT); web.max.ru _app/immutable/chunks/5oCuRT0F.js; PyMax api/messages/payloads.py:95-98 (53103f0) |
chats.members |
59 | CHAT_MEMBERS |
after login | measured | JOIN_REQUEST measured against MAX 2026-09-24 (pnpm probe:groups): {}; MEMBER measured 2026-09-27 on a group of 2 (pnpm probe:member-list): {members: [{contact, presence, readMark}]}, no marker; PyMax get_join_requests, get_chat_members (53103f0) |
chats.updateMembers |
77 | CHAT_MEMBERS_UPDATE |
after login | measured | measured against MAX 2026-09-24 with a second person who agreed (pnpm probe:members): add, make admin, take admin back, remove; PyMax invite_users_to_group, remove_users_from_group, add_admin, confirm_join_request, decline_join_request |
chats.delete |
52 | CHAT_DELETE |
never sent | measured | PyMax delete_chat; tsmax; measured against MAX 2026-10-01 on two throwaway test chats: { chatId, lastEventTime, forAll: true } answered {} |
messages.send |
64 | MSG_SEND |
after login | measured | measured against MAX 2026-09-19, including deduplication by cid across two connections; link and elements measured 2026-09-23 in Saved messages (pnpm probe:reply); shapes from tsmax and PyMax; the FORWARD link: web.max.ru _app/immutable/chunks/5oCuRT0F.js (2026-09-24), PyMax api/messages/payloads.py:56-73; a forward with no text and no elements measured 2026-09-24 in Saved messages (pnpm probe:edit-pin-forward); LINK attributes.url and UNDERLINE sent and preserved in raw CHAT_HISTORY readback 2026-10-03 in Saved messages (release check); group creation measured 2026-09-24 (pnpm probe:groups); shape from PyMax create_group; delayedAttributes from web.max.ru (2026-09-24, FIND-78), measured 2026-09-24 in Saved messages (pnpm probe:scheduled) |
messages.edit |
67 | MSG_EDIT |
after login | measured | measured against MAX 2026-09-24 in Saved messages (pnpm probe:edit-pin-forward); web.max.ru _app/immutable/chunks/5oCuRT0F.js (2026-09-24); PyMax api/messages/payloads.py:21-28 (53103f0) |
messages.react |
178 | MSG_REACTION |
after login | measured | measured against MAX 2026-09-23 in Saved messages (pnpm probe:reply); tsmax addReaction; PyMax add_reaction |
messages.unreact |
179 | MSG_CANCEL_REACTION |
after login | measured | measured against MAX 2026-09-24 in Saved messages; tsmax removeReaction; PyMax remove_reaction |
messages.pollVote |
304 | SEND_VOTE |
after login | measured | measured 2026-09-27 in Saved messages (pnpm probe:polls, FIND-247): a vote, two answers, an empty list, a vote on a closed poll; web.max.ru _app/immutable/chunks/5oCuRT0F.js (2026-09-24, FIND-140); PyMax 2.4.1 vote_poll |
messages.reactions |
180 | MSG_GET_REACTIONS |
after login | measured | measured against MAX 2026-09-24 in Saved messages (pnpm probe:message-shapes); tsmax getReactions; PyMax get_reactions |
messages.delete |
66 | MSG_DELETE |
after login | measured | PyMax 2.4.1 delete_message; tsmax; forMe: false measured 2026-09-27: the owner, as the group's admin, deleted another member's message in a test group by max chats check (NEED-318); it was gone from the history MAX returned |
attachments.video |
83 | VIDEO_PLAY |
after login | measured | measured against MAX 2026-09-23 (pnpm probe:download); tsmax getVideoById; PyMax get_video_by_id |
attachments.file |
88 | FILE_DOWNLOAD |
after login | measured | measured against MAX 2026-09-23 (pnpm probe:download); tsmax getFileById; PyMax get_file_by_id |
uploads.photo |
80 | PHOTO_UPLOAD |
after login | measured | measured against MAX 2026-09-24 in Saved messages (pnpm probe:upload); PyMax upload_photo |
uploads.file |
87 | FILE_UPLOAD |
after login | measured | measured against MAX 2026-09-24 in Saved messages (pnpm probe:upload); PyMax upload_file |
uploads.video |
82 | VIDEO_UPLOAD |
after login | measured | measured against MAX 2026-09-27 in Saved messages (pnpm probe:video, pnpm probe:voice); PyMax 2.4.1 upload_video; web.max.ru bundle (voice) |
A number in the registry is not permission to use it.
- LOGOUT (20) —
max session endforgets the token locally and tells MAX nothing. Ending the session server-side would also end it for the browser tab the token came from, which is not what the command promises. - AUTH_QR_APPROVE (290) — The phone's side of a QR login: it lets whoever showed the code into the owner's account. A CLI logging itself in never approves anybody.
- UNIDENTIFIED_36 (36) — Nobody agrees what it is: tsmax and PyMax call it
CONTACT_LIST; the protocol documentation calls itGET_BLOCKED. Sent once with the owner's permission on 2026-09-20 and it exists — but it refuses every payload we can guess, and one guess closed the connection. It stays unsent until somebody watches a real client send it (PROTO-1). - CHAT_DELETE (52) — Deleting a chat is left out of MAX-31 for the reason of
NEED-32: a tool that can destroy a conversation for everyone in it is a poor trade for tidiness. Measured 2026-10-01:forAll: truedoes not delete it for everyone anyway — the sender leaves, a control message says so, and the chat stays for the other members.