{
  "openapi": "3.0.3",
  "info": {
    "title": "ZeWork Connect Dev API",
    "version": "0.2.0",
    "description": "Dev integration. Real sending and two-way call media require acceptance. See /docs/guide for event, retry and WebRTC contracts."
  },
  "servers": [
    {
      "url": "https://dev-connect.zework.com"
    }
  ],
  "security": [
    {
      "partnerKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "partnerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Partner API key. Keep on backend."
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "operationId": "op0",
        "tags": [
          "Bắt đầu"
        ],
        "summary": "Kiểm tra dịch vụ",
        "description": "Không cần API key. Trả trạng thái API, không bảo đảm tài khoản Zalo đang online. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "security": []
      }
    },
    "/v1/capabilities": {
      "get": {
        "operationId": "op1",
        "tags": [
          "Bắt đầu"
        ],
        "summary": "Khả năng và giới hạn",
        "description": "Kiểm tra adapter được cấu hình. Call media vẫn cần nghiệm thu thực tế. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/login-sessions": {
      "post": {
        "operationId": "op2",
        "tags": [
          "Đăng nhập QR"
        ],
        "summary": "Lấy mã QR",
        "description": "Trả QR thật, có hạn khoảng 5 phút. Quét và xác nhận trên điện thoại. Tối đa 3 phiên chờ/đối tác. Proxy tùy chọn: thay null bằng {\"type\":\"socks5\",\"host\":\"IP_PUBLIC\",\"port\":1080,\"username\":\"user\",\"password\":\"pass\"}. Hỗ trợ socks5 hoặc http, bỏ username/password nếu không xác thực. Proxy áp dụng cho QR, socket tài khoản và upload chunk; chưa bao phủ mọi RPC nhắn tin/danh bạ hoặc media call. Tạo phiên đăng nhập mới. Không gửi tin hoặc gọi.",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "method": "pc",
                "externalAccountId": "test-account-01",
                "metadata": {},
                "proxy": null
              }
            }
          }
        }
      }
    },
    "/v1/login-sessions/{loginSessionId}": {
      "get": {
        "operationId": "op3",
        "tags": [
          "Đăng nhập QR"
        ],
        "summary": "Kiểm tra phiên QR",
        "description": "Bấm lại để cập nhật QR/trạng thái. authenticated chưa phải connected. Trang không tự polling. ",
        "parameters": [
          {
            "name": "loginSessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts": {
      "get": {
        "operationId": "op4",
        "tags": [
          "Tài khoản"
        ],
        "summary": "Danh sách tài khoản",
        "description": "Chỉ các tài khoản của API key hiện tại. Chọn tài khoản từ kết quả để điền vào các request tiếp theo. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}": {
      "get": {
        "operationId": "op5",
        "tags": [
          "Tài khoản"
        ],
        "summary": "Trạng thái tài khoản",
        "description": "Chờ connected trước khi gửi. reauth_required: cần quét QR mới. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/reconnect": {
      "post": {
        "operationId": "op6",
        "tags": [
          "Tài khoản"
        ],
        "summary": "Kết nối lại",
        "description": "Dùng phiên đã lưu để kết nối lại. Dùng phiên đã lưu để kết nối lại.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/sync": {
      "post": {
        "operationId": "op7",
        "tags": [
          "Tài khoản"
        ],
        "summary": "Yêu cầu đồng bộ",
        "description": "Tài khoản phải online. Không bảo đảm tải toàn bộ lịch sử. Tài khoản phải online. Không bảo đảm tải toàn bộ lịch sử.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/logout": {
      "post": {
        "operationId": "op8",
        "tags": [
          "Tài khoản"
        ],
        "summary": "Đăng xuất khỏi Connect",
        "description": "Xóa phiên Connect, ngắt socket và kết nối call của tài khoản. Không đăng xuất mọi thiết bị Zalo. Xóa phiên Connect, ngắt socket và kết nối call của tài khoản. Không đăng xuất mọi thiết bị Zalo.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/media": {
      "post": {
        "operationId": "op9",
        "tags": [
          "Tin nhắn và media"
        ],
        "summary": "Upload ảnh hoặc file",
        "description": "Upload raw binary, tối đa 5 MiB. Không dùng multipart. Media thuộc đối tác hiện tại. Upload file đã chọn lên service. Chưa gửi cho người nhận.",
        "parameters": [
          {
            "name": "X-File-Name",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "ASCII filename, max 200 characters."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages": {
      "post": {
        "operationId": "op10",
        "tags": [
          "Tin nhắn và media"
        ],
        "summary": "Gửi tin nhắn",
        "description": "Chọn text, ảnh, file, video, voice, sticker, mention, vị trí hoặc danh thiếp. recipientId là Zalo UID; gửi nhóm thêm isGroup:true. 202 chỉ là đã nhận tác vụ. Gửi tin thật đến người nhận. Chỉ dùng người nhận bạn được phép thử nghiệm.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "recipientId": "",
                "type": "text",
                "text": "Xin chào",
                "externalRequestId": "test-message-01"
              }
            }
          }
        }
      }
    },
    "/v1/operations/{operationId}": {
      "get": {
        "operationId": "op11",
        "tags": [
          "Tin nhắn và media"
        ],
        "summary": "Kết quả tác vụ",
        "description": "queued → running → succeeded / failed / unknown_outcome. unknown_outcome: đối soát, không tự gửi lại bằng key mới. succeeded chưa có nghĩa đã đọc. ",
        "parameters": [
          {
            "name": "operationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/contacts": {
      "get": {
        "operationId": "op12",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Danh bạ",
        "description": "Dữ liệu bên trong data còn theo upstream. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/contacts/resolve": {
      "get": {
        "operationId": "op13",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Tìm bằng số điện thoại",
        "description": "Tự chuẩn hóa số Việt Nam: 0912345678, +84912345678 hoặc 84912345678 đều thành 84912345678. Kết quả phụ thuộc quyền riêng tư upstream. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": ""
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/profile": {
      "get": {
        "operationId": "op14",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Hồ sơ tài khoản hiện tại",
        "description": "Thông tin Zalo của tài khoản đang kết nối. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/profile/{zaloUid}": {
      "get": {
        "operationId": "op15",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Hồ sơ người dùng",
        "description": "zaloUid là chuỗi ID, không phải số điện thoại. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zaloUid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/friend-requests": {
      "get": {
        "operationId": "op16",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Danh sách lời mời",
        "description": "Dữ liệu upstream trong data. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      },
      "post": {
        "operationId": "op19",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Gửi lời mời kết bạn",
        "description": "Theo dõi operation trả về. Gửi lời mời kết bạn thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "recipientId": "",
                "message": "Xin chào"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups": {
      "get": {
        "operationId": "op17",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Danh sách nhóm",
        "description": "Dữ liệu upstream trong data. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      },
      "post": {
        "operationId": "op23",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Tạo nhóm",
        "description": "Tên tối đa 100 ký tự, memberIds tối đa 100 ID chuỗi; phụ thuộc quyền trong nhóm. Tạo nhóm trên tài khoản/nhóm thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "name": "Nhóm thử nghiệm",
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}": {
      "get": {
        "operationId": "op18",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Thông tin nhóm",
        "description": "Cần quyền truy cập nhóm. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/friend-requests/{zaloUid}/accept": {
      "post": {
        "operationId": "op20",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Chấp nhận lời mời",
        "description": "Theo dõi operation trả về. Chấp nhận lời mời trên tài khoản thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zaloUid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/friend-requests/{zaloUid}/reject": {
      "post": {
        "operationId": "op21",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Từ chối lời mời",
        "description": "Theo dõi operation trả về. Từ chối lời mời trên tài khoản thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zaloUid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/friend-requests/{zaloUid}/cancel": {
      "post": {
        "operationId": "op22",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Hủy lời mời đã gửi",
        "description": "Theo dõi operation trả về. Hủy lời mời đã gửi trên tài khoản thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zaloUid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/rename": {
      "post": {
        "operationId": "op24",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Đổi tên nhóm",
        "description": "Tên tối đa 100 ký tự, memberIds tối đa 100 ID chuỗi; phụ thuộc quyền trong nhóm. Đổi tên nhóm trên tài khoản/nhóm thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "name": "Tên mới"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/add-members": {
      "post": {
        "operationId": "op25",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Thêm thành viên",
        "description": "Tên tối đa 100 ký tự, memberIds tối đa 100 ID chuỗi; phụ thuộc quyền trong nhóm. Thêm thành viên trên tài khoản/nhóm thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/remove-members": {
      "post": {
        "operationId": "op26",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Xóa thành viên",
        "description": "Tên tối đa 100 ký tự, memberIds tối đa 100 ID chuỗi; phụ thuộc quyền trong nhóm. Xóa thành viên trên tài khoản/nhóm thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/leave": {
      "post": {
        "operationId": "op27",
        "tags": [
          "Danh bạ và nhóm"
        ],
        "summary": "Rời nhóm",
        "description": "Tên tối đa 100 ký tự, memberIds tối đa 100 ID chuỗi; phụ thuộc quyền trong nhóm. Rời nhóm trên tài khoản/nhóm thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "op28",
        "tags": [
          "Sự kiện"
        ],
        "summary": "Đọc sự kiện bằng cursor",
        "description": "Lưu eventId để chống trùng. Chỉ lưu nextCursor sau xử lý thành công; cursor có thể nhảy số. ",
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "0"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "100"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/socket-tokens": {
      "post": {
        "operationId": "op29",
        "tags": [
          "Sự kiện"
        ],
        "summary": "Tạo token sự kiện",
        "description": "Dùng một lần, 60 giây. Gửi auth trong 5 giây sau mở /v1/ws. Phạm vi toàn đối tác, không riêng một account. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "operationId": "op30",
        "tags": [
          "Webhook"
        ],
        "summary": "Đăng ký webhook",
        "description": "Origin HTTPS phải được ZeWork cho phép trước. signingSecret chỉ trả một lần, lưu an toàn. Tạo nơi nhận sự kiện tài khoản. Kiểm tra URL là endpoint của bạn.",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://your-domain.example/webhooks/zework",
                "types": [
                  "message.received",
                  "message.sent",
                  "operation.failed"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "op31",
        "tags": [
          "Webhook"
        ],
        "summary": "Danh sách webhook",
        "description": "Không trả lại signingSecret. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}": {
      "delete": {
        "operationId": "op32",
        "tags": [
          "Webhook"
        ],
        "summary": "Tắt webhook",
        "description": "Hủy delivery đang chờ. Request đang gửi không thể thu hồi. Ngừng giao sự kiện tới webhook này.",
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/deliveries": {
      "get": {
        "operationId": "op33",
        "tags": [
          "Webhook"
        ],
        "summary": "Lịch sử giao webhook",
        "description": "100 delivery gần nhất: status, attempts, lastHttpStatus. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/deliveries/{deliveryId}/replay": {
      "post": {
        "operationId": "op34",
        "tags": [
          "Webhook"
        ],
        "summary": "Gửi lại delivery",
        "description": "Webhook phải còn hoạt động. Bên nhận dedupe theo eventId. Gửi lại sự kiện tới endpoint đã đăng ký.",
        "parameters": [
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/call-tokens": {
      "post": {
        "operationId": "op35",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Tạo token call",
        "description": "Token dùng một lần trong 60 giây, phiên khoảng 1 giờ. Token này dùng cho /v1/call-ws, không dùng cho socket sự kiện. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "accountId": ""
              }
            }
          }
        }
      }
    },
    "/v1/calls": {
      "post": {
        "operationId": "op36",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Tạo cuộc gọi",
        "description": "Cần client WebRTC đã kết nối /v1/call-ws và nhận ready. Trang này thử REST, không thay thế client microphone/âm thanh. recipientId: Zalo UID 1–30 chữ số. Gọi thật tới người nhận. Cần client WebRTC sẵn sàng và người nhận được phép thử.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "accountId": "",
                "recipientId": "",
                "connectionId": ""
              }
            }
          }
        }
      },
      "get": {
        "operationId": "op37",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Danh sách cuộc gọi",
        "description": "Tối đa 100 cuộc gần nhất. ",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/calls/{callId}": {
      "get": {
        "operationId": "op38",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Trạng thái cuộc gọi",
        "description": "Theo dõi dialing, ringing, answered, ended, failed, interrupted. ",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/calls/{callId}/answer": {
      "post": {
        "operationId": "op39",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Trả lời cuộc gọi",
        "description": "Dùng đúng connectionId gắn với tài khoản/cuộc gọi. accepted:true chưa phải trạng thái cuối. Trả lời cuộc gọi đang hoạt động.",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "connectionId": ""
              }
            }
          }
        }
      }
    },
    "/v1/calls/{callId}/hangup": {
      "post": {
        "operationId": "op40",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Kết thúc cuộc gọi",
        "description": "Dùng đúng connectionId gắn với tài khoản/cuộc gọi. accepted:true chưa phải trạng thái cuối. Kết thúc cuộc gọi đang hoạt động.",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "connectionId": ""
              }
            }
          }
        }
      }
    },
    "/v1/calls/{callId}/decline": {
      "post": {
        "operationId": "op41",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Từ chối cuộc gọi",
        "description": "Dùng đúng connectionId gắn với tài khoản/cuộc gọi. accepted:true chưa phải trạng thái cuối. Từ chối cuộc gọi đang hoạt động.",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "connectionId": ""
              }
            }
          }
        }
      }
    },
    "/v1/calls/{callId}/hold": {
      "post": {
        "operationId": "op42",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Giữ cuộc gọi",
        "description": "Dùng đúng connectionId gắn với tài khoản/cuộc gọi. accepted:true chưa phải trạng thái cuối. Giữ cuộc gọi đang hoạt động.",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "connectionId": ""
              }
            }
          }
        }
      }
    },
    "/v1/calls/{callId}/unhold": {
      "post": {
        "operationId": "op43",
        "tags": [
          "Cuộc gọi"
        ],
        "summary": "Tiếp tục cuộc gọi",
        "description": "Dùng đúng connectionId gắn với tài khoản/cuộc gọi. accepted:true chưa phải trạng thái cuối. Tiếp tục cuộc gọi đang hoạt động.",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "connectionId": ""
              }
            }
          }
        }
      }
    },
    "/v1/media/upload-sessions": {
      "post": {
        "operationId": "op44",
        "tags": [
          "Upload stream V2"
        ],
        "summary": "Khởi tạo upload stream",
        "description": "Không S3. File tạm trên PVC, dọn sau khoảng 24 giờ khi không có tác vụ sử dụng. Khai báo đúng số byte, tối đa 30 MiB, thời hạn upload 15 phút. Giữ dung lượng cho một phiên upload mới.",
        "parameters": [],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "fileName": "voice.webm",
                "mime": "audio/webm",
                "size": 12345
              }
            }
          }
        }
      }
    },
    "/v1/media/upload-sessions/{uploadSessionId}/content": {
      "put": {
        "operationId": "op45",
        "tags": [
          "Upload stream V2"
        ],
        "summary": "Upload stream file",
        "description": "Chọn đúng file đã khai báo; body là binary. Sau thành công nhận mediaId để gửi. Không resume giữa file; lỗi thì tạo phiên mới. Upload file lên service. Chưa gửi cho người nhận.",
        "parameters": [
          {
            "name": "uploadSessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-File-Name",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "ASCII filename, max 200 characters."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/v1/media/upload-sessions/{uploadSessionId}": {
      "get": {
        "operationId": "op46",
        "tags": [
          "Upload stream V2"
        ],
        "summary": "Trạng thái upload stream",
        "description": "pending / uploading / complete / failed / interrupted / expired. Nếu mất response PUT, GET trước để lấy mediaId; không gửi lại cùng session đã complete. ",
        "parameters": [
          {
            "name": "uploadSessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/forward": {
      "post": {
        "operationId": "op47",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Forward tin nhắn",
        "description": "sourceEventId lấy từ message.received hoặc message.echo của cùng tài khoản. Mỗi đích có operation riêng. File cần upload lại và thêm mediaId; không dùng URL S3. Media cũ không renew được sẽ báo lỗi. Chuyển tiếp tin nguồn tới các đích thật, tối đa 20 đích. Kiểm tra từng operation.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "sourceEventId": "",
                "targets": [
                  {
                    "recipientId": "",
                    "isGroup": false
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/batch": {
      "post": {
        "operationId": "op48",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Gửi nhiều nội dung",
        "description": "1–20 messages, mỗi nội dung có operation riêng. Đây là nhiều tin độc lập, không ghép album grid. Gửi tất cả nội dung trong batch tới người nhận thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "messages": [
                  {
                    "recipientId": "",
                    "type": "text",
                    "text": "Xin chào"
                  },
                  {
                    "recipientId": "",
                    "type": "image",
                    "mediaId": ""
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/reply": {
      "post": {
        "operationId": "op49",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Trả lời tin nguồn",
        "description": "Hỗ trợ quote tin text, ảnh và file trong cá nhân/nhóm. Thêm mentions:[{userId,offset,length}] để tag người trong nhóm; offset/length tính UTF-16. Đích lấy từ sourceEventId, không tự nhập recipientId. Trả lời tin nguồn trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "sourceEventId": "",
                "text": "Nội dung trả lời"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/reaction": {
      "post": {
        "operationId": "op50",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Thả cảm xúc",
        "description": "Dùng mã reaction/icon của client Zalo. Tin nguồn phải có msgId và cliMsgId. Thả cảm xúc trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "sourceEventId": "",
                "reactionType": 3,
                "icon": "/heart"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/recall": {
      "post": {
        "operationId": "op51",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Thu hồi tin đã gửi",
        "description": "Chỉ thu hồi tin do tài khoản hiện tại gửi; dùng event message.echo. Thu hồi tin đã gửi trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "sourceEventId": ""
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/pin": {
      "post": {
        "operationId": "op52",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Ghim tin nhắn",
        "description": "Ghim tin text vào đúng hội thoại nguồn. Ghim tin nhắn trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "sourceEventId": ""
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/unpin": {
      "post": {
        "operationId": "op53",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Bỏ ghim",
        "description": "topicId lấy từ danh sách ghim. Bỏ ghim trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "recipientId": "",
                "isGroup": false,
                "topicId": ""
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/messages/typing": {
      "post": {
        "operationId": "op54",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Báo đang nhập",
        "description": "Hiện chỉ hỗ trợ hội thoại cá nhân. Báo đang nhập trên hội thoại thật.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "recipientId": "",
                "isGroup": false
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/pins": {
      "get": {
        "operationId": "op55",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Danh sách tin ghim",
        "description": "Danh sách ghim upstream. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recipientId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": ""
          },
          {
            "name": "isGroup",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "false"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/stickers": {
      "get": {
        "operationId": "op56",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Danh mục và tìm sticker",
        "description": "Bỏ q để lấy danh mục, nhập q để tìm. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": ""
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/stickers/{stickerId}": {
      "get": {
        "operationId": "op57",
        "tags": [
          "Tin nhắn nâng cao"
        ],
        "summary": "Chi tiết sticker",
        "description": "Lấy stickerId/categoryId để gửi type sticker. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stickerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/labels": {
      "get": {
        "operationId": "op58",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Danh sách nhãn",
        "description": "Nhãn quản lý riêng trong Connect, không tự đồng bộ nhãn Zalo hoặc staff ZeWork. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      },
      "post": {
        "operationId": "op59",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Tạo nhãn",
        "description": "Tối đa 100 nhãn/tài khoản. POST này không hỗ trợ idempotency; kiểm tra danh sách trước khi retry. Tạo nhãn riêng của đối tác.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "name": "Khách VIP",
                "color": "#2563eb"
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/labels/{labelId}": {
      "patch": {
        "operationId": "op60",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Sửa nhãn",
        "description": "Tên tối đa 100 ký tự, màu hex. Đổi tên/màu nhãn.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "name": "Khách ưu tiên",
                "color": "#16a34a"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "op61",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Xóa nhãn",
        "description": "Bỏ nhãn khỏi tất cả liên kết trong tài khoản. Xóa nhãn và các liên kết của nhãn.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/conversations/{recipientId}/labels": {
      "get": {
        "operationId": "op62",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Nhãn của hội thoại",
        "description": "recipientId là UID cá nhân hoặc nhóm. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recipientId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "isGroup",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "false"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      },
      "put": {
        "operationId": "op63",
        "tags": [
          "Nhãn đối tác"
        ],
        "summary": "Gắn nhãn hội thoại",
        "description": "Thay toàn bộ nhãn bằng labelIds; [] để gỡ hết. Tối đa 30 nhãn. Có thể lặp PUT cùng payload. Thay danh sách nhãn hội thoại trong Connect.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recipientId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "isGroup",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "false"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "labelIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/members": {
      "get": {
        "operationId": "op64",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Thành viên nhóm",
        "description": "offset/limit phân trang trên danh sách upstream. complete=false nếu upstream chưa trả đủ. profiles chứa dữ liệu hồ sơ upstream. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "0"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "50"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/settings": {
      "get": {
        "operationId": "op65",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Cài đặt và quản trị nhóm",
        "description": "Đọc setting, creatorId và adminIds; quyền thay đổi do Zalo kiểm tra. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      },
      "post": {
        "operationId": "op70",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Cập nhật cài đặt nhóm",
        "description": "Chỉ gửi field cần sửa. 0/1: blockName, signAdminMsg, addMemberOnly, setTopicOnly, enableMsgHistory, lockCreatePost, lockCreatePoll, joinAppr, lockSendMsg, lockViewMember. Các field lock/block=1 nghĩa khóa; joinAppr=1 bật duyệt. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "settings": {
                  "joinAppr": 1
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/pending-members": {
      "get": {
        "operationId": "op66",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Thành viên chờ duyệt",
        "description": "Danh sách chờ duyệt upstream. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/invite-link": {
      "get": {
        "operationId": "op67",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Link mời nhóm",
        "description": "Đọc link mời, không tự tạo lại link. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/blocked-members": {
      "get": {
        "operationId": "op68",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Thành viên bị chặn",
        "description": "Phân trang upstream, 50 bản ghi mỗi page. ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "1"
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/group-invitations": {
      "get": {
        "operationId": "op69",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Lời mời vào nhóm",
        "description": "Trang đầu của inbox upstream (helper hiện chưa hỗ trợ phân trang). ",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/review-members": {
      "post": {
        "operationId": "op71",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Duyệt / từ chối thành viên",
        "description": "approve=true chấp nhận, false từ chối. Tối đa 50 ID. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": [],
                "approve": true
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/invite-link/renew": {
      "post": {
        "operationId": "op72",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Tạo lại link mời",
        "description": "Link cũ có thể mất hiệu lực. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/invite-link/disable": {
      "post": {
        "operationId": "op73",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Tắt link mời",
        "description": "Vô hiệu link mời hiện tại. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/block-members": {
      "post": {
        "operationId": "op74",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Chặn thành viên",
        "description": "Tối đa 50 ID. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/unblock-members": {
      "post": {
        "operationId": "op75",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Bỏ chặn thành viên",
        "description": "Tối đa 50 ID. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/admins/add": {
      "post": {
        "operationId": "op76",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Thêm phó nhóm",
        "description": "Cần quyền quản trị phù hợp trên Zalo. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/admins/remove": {
      "post": {
        "operationId": "op77",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Gỡ phó nhóm",
        "description": "Cần quyền quản trị phù hợp trên Zalo. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "memberIds": []
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/transfer-owner": {
      "post": {
        "operationId": "op78",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Chuyển trưởng nhóm",
        "description": "Thay đổi quyền sở hữu thật; chỉ dùng khi bạn chủ động muốn chuyển. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "newOwnerId": ""
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/avatar": {
      "post": {
        "operationId": "op79",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Đổi ảnh nhóm",
        "description": "Upload ảnh trước, dùng mediaId cùng đối tác; file stream/PVC, không S3. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "mediaId": ""
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}/groups/{groupId}/accept-invitation": {
      "post": {
        "operationId": "op80",
        "tags": [
          "Quản lý nhóm"
        ],
        "summary": "Chấp nhận lời mời vào nhóm",
        "description": "Dùng groupId trong inbox lời mời. Thay đổi nhóm thật. Kiểm tra operation; upstream có thể từ chối nếu thiếu quyền.",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Keep the same key and payload when retrying the same action."
          }
        ],
        "responses": {
          "2XX": {
            "description": "Successful HTTP request; inspect operation/call state for final outcome."
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or missing key"
          },
          "404": {
            "description": "Not found or not owned"
          },
          "409": {
            "description": "Conflict or account/connection unavailable"
          },
          "429": {
            "description": "Rate or queue limit"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        }
      }
    }
  }
}