---
title: "Cập nhật khảo sát"
method: PUT
path: "/admin/surveys/{surveyId}"
tags: ["SurveysAdmin"]
---

# Cập nhật khảo sát

`PUT /admin/surveys/{surveyId}`

## Request

- Base URL: `https://api.fireant.vn`
- URL: `https://api.fireant.vn/admin/surveys/{surveyId}`
- Auth: OAuth 2
  - Implicit: `https://accounts.fireant.vn/connect/authorize`
  - Scopes: `user-data-write`
- TypeScript: <https://skmtc.dev/fireant/apis/fireant-restful-api/docs/admin/surveys/:surveyId/put.ts> (a function with typed inputs; its response is checked against the schema)

questions = null: giữ nguyên bộ câu hỏi; khác null: thay thế toàn bộ (chỉ khi khảo sát chưa có phản hồi hoàn thành).
audienceRules = null: giữ nguyên; khác null: thay thế toàn bộ (được phép bất kỳ lúc nào).

## Path parameters

- `surveyId` integer, required

## Request body

- FireAntApiModelsSurveysSurveyChangeRequest: Yêu cầu tạo mới / cập nhật khảo sát (Admin)
  - `code` string: Mã/slug khảo sát (tùy chọn, duy nhất)
  - `title` string, required: Tiêu đề (bắt buộc)
  - `description` string: Mô tả
  - `thankYouMessage` string: Lời cảm ơn sau khi gửi
  - `imageUrl` string: Ảnh minh họa
  - `isAnonymous` boolean: Cho phép trả lời không cần đăng nhập
  - `allowMultipleResponses` boolean: Cho phép một người trả lời nhiều lần
  - `showResults` boolean: Cho phép người trả lời xem kết quả tổng hợp
  - `startDate` string, date-time: Thời điểm bắt đầu nhận phản hồi
  - `endDate` string, date-time: Thời điểm kết thúc nhận phản hồi
  - `maxResponses` integer: Số phản hồi tối đa
  - `targetAudience` string: Nhóm đối tượng
  - `priority` integer: Ưu tiên hiển thị
  - `displayMode` 0 | 1 | 2: Cách hiển thị trên App/Web: 0 ListOnly, 1 Banner (mặc định), 2 Prompt (0 = ListOnly, 1 = Banner, 2 = Prompt)
  - `dismissible` boolean: Cho phép người dùng "Để sau" / "Không quan tâm" (mặc định true)
  - `snoozeDays` integer: Số ngày ẩn khi "Để sau" (1..90, mặc định 3)
  - `showToGuests` boolean: Khảo sát yêu cầu đăng nhập vẫn hiện với khách chưa đăng nhập, bấm vào thì mời đăng nhập (mặc định true)
  - `questions` FireAntApiModelsSurveysSurveyQuestionChangeRequest[]: Danh sách câu hỏi theo thứ tự hiển thị (Section dùng để chia nhóm / ngắt trang). Khi cập nhật: null = giữ nguyên; khác null = thay thế toàn bộ (chỉ khi khảo sát chưa có phản hồi). Điều kiện rẽ nhánh tham chiếu câu hỏi/lựa chọn bằng chỉ số trong mảng (0-based).
    - `questionText` string, required: Nội dung câu hỏi (bắt buộc; với Section là tiêu đề nhóm)
    - `description` string: Mô tả / hướng dẫn thêm
    - `questionType` 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17: Loại câu hỏi (1 = SingleChoice, 2 = MultipleChoice, 3 = Text, 4 = Rating, 5 = YesNo, 6 = Number, 7 = Date, 8 = Dropdown, 9 = Matrix, 10 = Ranking, 11 = FileUpload, 12 = Symbol, 13 = DateRange, 14 = Slider, 15 = Section, 16 = Hotspot, 17 = FillInBlank)
    - `isRequired` boolean: Bắt buộc trả lời
    - `orderIndex` integer: Thứ tự hiển thị (null = theo vị trí trong mảng)
    - `minValue` integer: Rating/Slider/Number/Matrix(thang điểm): giá trị nhỏ nhất (Rating mặc định 1, Slider mặc định 0)
    - `maxValue` integer: Rating/Slider/Number/Matrix(thang điểm): giá trị lớn nhất (Rating mặc định 5, Slider mặc định 100)
    - `minLabel` string: Rating/Slider: nhãn đầu thang
    - `maxLabel` string: Rating/Slider: nhãn cuối thang
    - `maxSelections` integer: MultipleChoice/Ranking/Symbol/FileUpload: số lượng tối đa
    - `allowOtherOption` boolean: Tự động thêm lựa chọn "Khác" cho phép nhập text
    - `placeholder` string: Gợi ý nhập
    - `maxLength` integer: Text: độ dài tối đa
    - `settings` FireAntApiModelsSurveysSurveyQuestionSettings: Cấu hình bổ sung theo loại câu hỏi (lưu JSON trong SurveyQuestions.Settings). Chỉ các trường phù hợp với loại câu hỏi mới được sử dụng.
      - `step` number, double: Slider/Number: bước nhảy (ví dụ 0.5). Null = tự do
      - `unit` string: Slider/Number/Rating: đơn vị hiển thị (%, VND, điểm...)
      - `minSelections` integer: MultipleChoice/Ranking/Symbol/FileUpload: số lượng tối thiểu phải chọn/nhập
      - `allowedFileTypes` string[]: FileUpload: đuôi tệp cho phép (ví dụ ["jpg","png","pdf"]). Null = mặc định ảnh + pdf
      - `maxFileSizeKb` integer: FileUpload: dung lượng tối đa mỗi tệp (KB). Null = 10240
      - `minDate` string, date-time: Date/DateRange: ngày sớm nhất được chọn
      - `maxDate` string, date-time: Date/DateRange: ngày muộn nhất được chọn
      - `maxRangeDays` integer: DateRange: số ngày tối đa của khoảng
      - `symbolTypes` string[]: Symbol: chỉ cho phép loại chứng khoán (STOCK, ETF, INDEX...). Null = tất cả
      - `showAsStars` boolean: Rating: hiển thị dạng sao (client dùng). Giữ để tương thích; ưu tiên ratingStyle
      - `ratingStyle` string: Rating: number | star | emoji | heart | nps (0..10, tô màu 3 nhóm)
      - `emojis` string[]: Rating (emoji) / Slider (emoji): emoji theo từng mức, từ thấp tới cao
      - `scaleLabels` string[]: Rating: nhãn cho từng mức, từ thấp tới cao (hiện dưới mức đang chọn)
      - `yesNoStyle` string: YesNo: buttons | thumbs | emoji
      - `yesLabel` string: YesNo: nhãn nút Có (bỏ trống = "Có")
      - `noLabel` string: YesNo: nhãn nút Không (bỏ trống = "Không")
      - `optionLayout` string: SingleChoice/MultipleChoice: list | grid (ô vuông) | cards (thẻ ảnh lớn)
      - `imageAspect` string: grid/cards: tỷ lệ ảnh 1:1 | 4:3 | 16:9 | 3:4
      - `showOptionText` boolean: grid/cards: hiện chữ dưới ảnh (mặc định true)
      - `columns` integer: grid/cards: số cột trên màn rộng (2..4, mặc định tự động)
      - `sliderStyle` string: Slider: default | gradient | emoji
      - `marks` FireAntApiModelsSurveysSurveySliderMark[]: Slider: vạch mốc có nhãn
        - `value` number, double: Giá trị
        - `label` string: Nhãn hiển thị (bỏ trống = giá trị)
      - `prefix` string: Slider/Number: tiền tố hiển thị (ví dụ "+", "$")
      - `range` boolean: Slider: chọn khoảng hai đầu (trả lời number + numberTo)
      - `gradientColors` string[]: Slider (gradient): màu dải từ thấp tới cao (#RRGGBB)
      - `showValue` boolean: Slider: hiện giá trị đang chọn (mặc định true)
      - `rankingStyle` string: Ranking: drag (kéo thả sắp tất cả) | pick (chọn top N rồi sắp)
      - `imageUrl` string: Hotspot: ảnh nền (bắt buộc)
      - `imageWidth` integer: Hotspot: bề rộng ảnh gốc (px) để giữ đúng tỷ lệ
      - `imageHeight` integer: Hotspot: chiều cao ảnh gốc (px)
      - `showHeatmapPublic` boolean: Hotspot: cho người trả lời xem bản đồ nhiệt ở kết quả công khai
      - `showRegions` boolean: Hotspot: hiện viền các vùng có tên cho người trả lời
      - `requireRegion` boolean: Hotspot: điểm chạm bắt buộc nằm trong một vùng có tên
      - `template` string: FillInBlank: câu mẫu, ô trống viết {{key}} (key = optionValue của ô trống). Ví dụ "Tôi đầu tư vì {{1}}"
    - `randomizeOptions` boolean: Xáo thứ tự lựa chọn khi hiển thị
    - `conditionLogic` 0 | 1: Cách kết hợp điều kiện hiển thị (All = AND, Any = OR) (0 = All, 1 = Any)
    - `options` FireAntApiModelsSurveysSurveyOptionChangeRequest[]: Danh sách lựa chọn (bắt buộc với SingleChoice/MultipleChoice/Dropdown/Ranking/Matrix). Matrix: dòng có optionGroup = Choice, cột có optionGroup = MatrixColumn (bỏ cột nếu dùng thang điểm minValue..maxValue).
      - `optionText` string, required: Nội dung lựa chọn (bắt buộc)
      - `optionValue` string: Giá trị nội bộ (tùy chọn)
      - `orderIndex` integer: Thứ tự hiển thị (null = theo vị trí trong mảng)
      - `isOther` boolean: Là lựa chọn "Khác"
      - `imageUrl` string: Ảnh minh họa
      - `optionGroup` 0 | 1 | 2 | 3: Nhóm: Choice (mặc định), MatrixColumn, Blank (ô trống), BlankChoice (lựa chọn của ô trống) (0 = Choice, 1 = MatrixColumn, 2 = Blank, 3 = BlankChoice)
      - `settings` FireAntApiModelsSurveysSurveyOptionSettings: Thiết lập của một lựa chọn (JSON trong SurveyQuestionOptions.Settings)
        - `shape` string: Hotspot: hình của vùng - rect | ellipse
        - `x` number, double: Hotspot: tọa độ trái của vùng theo tỷ lệ bề rộng ảnh (0..1)
        - `y` number, double: Hotspot: tọa độ trên của vùng theo tỷ lệ chiều cao ảnh (0..1)
        - `w` number, double: Hotspot: bề rộng vùng theo tỷ lệ (0..1)
        - `h` number, double: Hotspot: chiều cao vùng theo tỷ lệ (0..1)
        - `blankKind` string: FillInBlank: kiểu ô trống - text | choice | number | symbol
        - `placeholder` string: FillInBlank: gợi ý trong ô trống
        - `maxLength` integer: FillInBlank (text): độ dài tối đa (mặc định 200)
        - `min` number, double: FillInBlank (number): giá trị nhỏ nhất
        - `max` number, double: FillInBlank (number): giá trị lớn nhất
        - `required` boolean: FillInBlank: ô trống bắt buộc khi câu hỏi bắt buộc (mặc định true)
        - `width` string: FillInBlank: độ rộng ô - sm | md | lg
        - `icon` string: Lựa chọn: icon đại diện - tên trong bộ icon khảo sát (@fireant-media/survey-ui/icons, Lucide), ví dụ "wallet", "trending-up". Chỉ kiểm tra dạng tên (chữ thường, số, "-", tối đa 40 ký tự) để thêm icon mới không cần deploy API.
        - `emoji` string: Lựa chọn: emoji đại diện (cũ - survey-ui tự đổi emoji quen thuộc sang icon; khảo sát mới dùng Icon)
        - `description` string: Lựa chọn dạng thẻ: mô tả phụ
      - `parentOptionIndex` integer: BlankChoice: chỉ số (0-based) của ô trống cha trong cùng mảng options
    - `conditions` FireAntApiModelsSurveysSurveyConditionChangeRequest[]: Điều kiện hiển thị (rỗng = luôn hiển thị)
      - `sourceQuestionIndex` integer: Chỉ số (0-based) của câu hỏi nguồn trong mảng questions - phải nhỏ hơn chỉ số câu hỏi hiện tại
      - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
      - `sourceOptionIndex` integer: Chỉ số (0-based) của lựa chọn trong mảng options của câu nguồn (cho các loại chọn)
      - `value` string: Giá trị so sánh (số, text, true/false, ngày ISO yyyy-MM-dd)
    - `carryForwardQuestionIndex` integer: Lấy lựa chọn từ đáp án câu trước: chỉ số (0-based) câu nguồn, phải đứng trước và có cùng số lựa chọn
    - `carryForwardMode` 1 | 2: Cách lấy lựa chọn (bắt buộc khi có carryForwardQuestionIndex) (1 = Selected, 2 = NotSelected)
    - `jumps` FireAntApiModelsSurveysSurveyJumpChangeRequest[]: Quy tắc nhảy sau câu này (xét theo thứ tự, quy tắc đầu tiên khớp được dùng)
      - `targetQuestionIndex` integer: Chỉ số câu/phần đích (phải lớn hơn chỉ số câu hiện tại). Null = kết thúc khảo sát
      - `conditionLogic` 0 | 1: Cách kết hợp điều kiện (0 = All, 1 = Any)
      - `conditions` FireAntApiModelsSurveysSurveyConditionChangeRequest[]: Điều kiện (sourceQuestionIndex ≤ chỉ số câu hiện tại). Rỗng = luôn nhảy
        - `sourceQuestionIndex` integer: Chỉ số (0-based) của câu hỏi nguồn trong mảng questions - phải nhỏ hơn chỉ số câu hỏi hiện tại
        - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
        - `sourceOptionIndex` integer: Chỉ số (0-based) của lựa chọn trong mảng options của câu nguồn (cho các loại chọn)
        - `value` string: Giá trị so sánh (số, text, true/false, ngày ISO yyyy-MM-dd)
  - `audienceRules` FireAntApiModelsSurveysSurveyAudienceRuleChangeRequest[]: Quy tắc nhắm đối tượng (AND). Khi cập nhật: null = giữ nguyên; khác null (kể cả rỗng) = thay thế toàn bộ. Được phép thay đổi kể cả khi khảo sát đã có phản hồi.
    - `ruleType` 1 | 2 | 3 | 4 | 5 | 6 | 7: Loại quy tắc (1 = Platform, 2 = AppVersion, 3 = MembershipLevel, 4 = Role, 5 = UserName, 6 = IdentityVerified, 7 = Tag)
    - `operator` 1 | 2 | 3 | 4 | 5 | 6: Phép so sánh (1 = In, 2 = NotIn, 3 = GreaterOrEqual, 4 = LessOrEqual, 5 = Equals, 6 = NotEquals)
    - `value` string, required: Giá trị so sánh (bắt buộc)
  - `targets` FireAntApiModelsSurveysSurveyTargetChangeRequest[]: Đối tượng khảo sát gắn vào (post, symbol, room...). Khi cập nhật: null = giữ nguyên; khác null (kể cả rỗng) = thay thế toàn bộ. Khảo sát có gắn đối tượng chỉ hiện theo ngữ cảnh (GET /surveys/target/{type}/{key}), không được mời chung ở Home.
    - `targetType` string, required: Loại đối tượng: post, symbol, room, user, event, article, url (chữ thường, a-z0-9_-)
    - `targetKey` string, required: Khóa đối tượng (postId, mã CK, roomId...)
  - `outcomeRules` FireAntApiModelsSurveysSurveyOutcomeRuleChangeRequest[]: Hành động sau khảo sát (nút bấm dẫn tới URL / màn hình app / khảo sát khác / mã CK theo câu trả lời). Khi cập nhật: null = giữ nguyên; khác null (kể cả rỗng) = thay thế toàn bộ. Được phép đổi kể cả khi đã có phản hồi. Điều kiện tham chiếu câu hỏi theo chỉ số trong mảng questions (hoặc theo thứ tự câu hỏi hiện có nếu không gửi questions).
    - `title` string: Tiêu đề hiển thị (tùy chọn, tối đa 256)
    - `description` string: Mô tả ngắn (tùy chọn, tối đa 1024)
    - `buttonLabel` string, required: Nhãn nút bấm (bắt buộc, tối đa 128)
    - `actionType` 1 | 2 | 3 | 4: Loại hành động: 1 Url, 2 AppRoute, 3 Survey, 4 Symbol (1 = Url, 2 = AppRoute, 3 = Survey, 4 = Symbol)
    - `actionValue` string, required: Giá trị hành động (bắt buộc, tối đa 1024). Hỗ trợ placeholder {answer:N}, {surveyId}, {responseId}, {userName}, {anonymousId}.
    - `openInNewTab` boolean: Mở trong tab mới (Url trên web)
    - `conditionLogic` 0 | 1: Cách kết hợp điều kiện (0 = All, 1 = Any)
    - `isDefault` boolean: Quy tắc mặc định (không cần điều kiện; tối đa một quy tắc)
    - `conditions` FireAntApiModelsSurveysSurveyConditionChangeRequest[]: Điều kiện; quy tắc không mặc định cần ít nhất một điều kiện
      - `sourceQuestionIndex` integer: Chỉ số (0-based) của câu hỏi nguồn trong mảng questions - phải nhỏ hơn chỉ số câu hỏi hiện tại
      - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
      - `sourceOptionIndex` integer: Chỉ số (0-based) của lựa chọn trong mảng options của câu nguồn (cho các loại chọn)
      - `value` string: Giá trị so sánh (số, text, true/false, ngày ISO yyyy-MM-dd)
  - `presentationMode` 0 | 1 | 2: Chế độ trình bày: 0 cuộn một trang (mặc định), 1 mỗi Section một trang, 2 mỗi câu một màn hình (0 = Scroll, 1 = SectionPages, 2 = OneByOne)
  - `settings` FireAntApiModelsSurveysSurveySettings: Thiết lập trình bày của khảo sát (JSON trong Surveys.Settings). Client dùng; bỏ trống = mặc định.
    - `autoAdvance` boolean: Tự chuyển sang câu sau khi chọn xong câu chọn một / Có-Không / thang điểm (chế độ từng câu). Mặc định true
    - `showWelcome` boolean: Hiện màn hình mở đầu (ảnh bìa, thời gian ước tính, nút Bắt đầu) ở chế độ từng câu. Mặc định true
    - `showProgress` boolean: Hiện thanh tiến độ. Mặc định true
    - `allowBack` boolean: Cho quay lại câu trước. Mặc định true
    - `celebrate` boolean: Hiệu ứng chúc mừng khi hoàn thành. Mặc định true
    - `showQuestionNumbers` boolean: Hiện số thứ tự câu hỏi. Mặc định true
    - `accentColor` string: Màu nhấn của khảo sát (#RRGGBB). Bỏ trống = màu thương hiệu của ứng dụng
    - `welcomeTitle` string: Tiêu đề màn hình mở đầu (bỏ trống = tiêu đề khảo sát)
    - `welcomeButton` string: Nhãn nút bắt đầu (bỏ trống = "Bắt đầu")
    - `estimatedMinutes` integer: Thời gian ước tính (phút) ghi đè cách tính tự động

## Response `200`

Thành công

- FireAntApiModelsSurveysSurveyDetail: Thông tin chi tiết khảo sát kèm danh sách câu hỏi, lựa chọn, điều kiện rẽ nhánh và quy tắc đối tượng
  - `questions` FireAntApiModelsSurveysSurveyQuestionItem[]: Danh sách câu hỏi theo thứ tự hiển thị
    - `questionId` integer: ID câu hỏi
    - `surveyId` integer: ID khảo sát
    - `questionText` string: Nội dung câu hỏi (với Section: tiêu đề nhóm/trang)
    - `description` string: Mô tả / hướng dẫn thêm
    - `questionType` 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17: Loại câu hỏi (1 = SingleChoice, 2 = MultipleChoice, 3 = Text, 4 = Rating, 5 = YesNo, 6 = Number, 7 = Date, 8 = Dropdown, 9 = Matrix, 10 = Ranking, 11 = FileUpload, 12 = Symbol, 13 = DateRange, 14 = Slider, 15 = Section, 16 = Hotspot, 17 = FillInBlank)
    - `isRequired` boolean: Bắt buộc trả lời
    - `orderIndex` integer: Thứ tự hiển thị
    - `minValue` integer: Rating/Number/Slider/Matrix(thang điểm): giá trị nhỏ nhất
    - `maxValue` integer: Rating/Number/Slider/Matrix(thang điểm): giá trị lớn nhất
    - `minLabel` string: Rating/Slider: nhãn đầu thang
    - `maxLabel` string: Rating/Slider: nhãn cuối thang
    - `maxSelections` integer: MultipleChoice/Ranking/Symbol/FileUpload: số lượng tối đa (null = không giới hạn / xếp hạng tất cả)
    - `allowOtherOption` boolean: Có lựa chọn "Khác" cho phép nhập text
    - `placeholder` string: Gợi ý nhập (Text/Number/Symbol)
    - `maxLength` integer: Text: độ dài tối đa
    - `settings` FireAntApiModelsSurveysSurveyQuestionSettings: Cấu hình bổ sung theo loại câu hỏi (lưu JSON trong SurveyQuestions.Settings). Chỉ các trường phù hợp với loại câu hỏi mới được sử dụng.
      - `step` number, double: Slider/Number: bước nhảy (ví dụ 0.5). Null = tự do
      - `unit` string: Slider/Number/Rating: đơn vị hiển thị (%, VND, điểm...)
      - `minSelections` integer: MultipleChoice/Ranking/Symbol/FileUpload: số lượng tối thiểu phải chọn/nhập
      - `allowedFileTypes` string[]: FileUpload: đuôi tệp cho phép (ví dụ ["jpg","png","pdf"]). Null = mặc định ảnh + pdf
      - `maxFileSizeKb` integer: FileUpload: dung lượng tối đa mỗi tệp (KB). Null = 10240
      - `minDate` string, date-time: Date/DateRange: ngày sớm nhất được chọn
      - `maxDate` string, date-time: Date/DateRange: ngày muộn nhất được chọn
      - `maxRangeDays` integer: DateRange: số ngày tối đa của khoảng
      - `symbolTypes` string[]: Symbol: chỉ cho phép loại chứng khoán (STOCK, ETF, INDEX...). Null = tất cả
      - `showAsStars` boolean: Rating: hiển thị dạng sao (client dùng). Giữ để tương thích; ưu tiên ratingStyle
      - `ratingStyle` string: Rating: number | star | emoji | heart | nps (0..10, tô màu 3 nhóm)
      - `emojis` string[]: Rating (emoji) / Slider (emoji): emoji theo từng mức, từ thấp tới cao
      - `scaleLabels` string[]: Rating: nhãn cho từng mức, từ thấp tới cao (hiện dưới mức đang chọn)
      - `yesNoStyle` string: YesNo: buttons | thumbs | emoji
      - `yesLabel` string: YesNo: nhãn nút Có (bỏ trống = "Có")
      - `noLabel` string: YesNo: nhãn nút Không (bỏ trống = "Không")
      - `optionLayout` string: SingleChoice/MultipleChoice: list | grid (ô vuông) | cards (thẻ ảnh lớn)
      - `imageAspect` string: grid/cards: tỷ lệ ảnh 1:1 | 4:3 | 16:9 | 3:4
      - `showOptionText` boolean: grid/cards: hiện chữ dưới ảnh (mặc định true)
      - `columns` integer: grid/cards: số cột trên màn rộng (2..4, mặc định tự động)
      - `sliderStyle` string: Slider: default | gradient | emoji
      - `marks` FireAntApiModelsSurveysSurveySliderMark[]: Slider: vạch mốc có nhãn
        - `value` number, double: Giá trị
        - `label` string: Nhãn hiển thị (bỏ trống = giá trị)
      - `prefix` string: Slider/Number: tiền tố hiển thị (ví dụ "+", "$")
      - `range` boolean: Slider: chọn khoảng hai đầu (trả lời number + numberTo)
      - `gradientColors` string[]: Slider (gradient): màu dải từ thấp tới cao (#RRGGBB)
      - `showValue` boolean: Slider: hiện giá trị đang chọn (mặc định true)
      - `rankingStyle` string: Ranking: drag (kéo thả sắp tất cả) | pick (chọn top N rồi sắp)
      - `imageUrl` string: Hotspot: ảnh nền (bắt buộc)
      - `imageWidth` integer: Hotspot: bề rộng ảnh gốc (px) để giữ đúng tỷ lệ
      - `imageHeight` integer: Hotspot: chiều cao ảnh gốc (px)
      - `showHeatmapPublic` boolean: Hotspot: cho người trả lời xem bản đồ nhiệt ở kết quả công khai
      - `showRegions` boolean: Hotspot: hiện viền các vùng có tên cho người trả lời
      - `requireRegion` boolean: Hotspot: điểm chạm bắt buộc nằm trong một vùng có tên
      - `template` string: FillInBlank: câu mẫu, ô trống viết {{key}} (key = optionValue của ô trống). Ví dụ "Tôi đầu tư vì {{1}}"
    - `randomizeOptions` boolean: Xáo thứ tự lựa chọn mỗi lần hiển thị (lựa chọn "Khác" luôn ở cuối)
    - `conditionLogic` 0 | 1: Cách kết hợp các điều kiện hiển thị (0 = All, 1 = Any)
    - `options` FireAntApiModelsSurveysSurveyOptionItem[]: Danh sách lựa chọn. Với Matrix: optionGroup = Choice là dòng, optionGroup = MatrixColumn là cột.
      - `optionId` integer: ID lựa chọn
      - `questionId` integer: ID câu hỏi
      - `optionText` string: Nội dung lựa chọn
      - `optionValue` string: Giá trị nội bộ (mã/điểm) - tùy chọn
      - `orderIndex` integer: Thứ tự hiển thị
      - `isOther` boolean: Là lựa chọn "Khác" (cho phép nhập text kèm theo)
      - `imageUrl` string: Ảnh minh họa
      - `optionGroup` 0 | 1 | 2 | 3: Nhóm: Choice (lựa chọn / dòng ma trận / vùng hotspot), MatrixColumn (cột ma trận), Blank (ô trống), BlankChoice (lựa chọn của ô trống) (0 = Choice, 1 = MatrixColumn, 2 = Blank, 3 = BlankChoice)
      - `settings` FireAntApiModelsSurveysSurveyOptionSettings: Thiết lập của một lựa chọn (JSON trong SurveyQuestionOptions.Settings)
        - `shape` string: Hotspot: hình của vùng - rect | ellipse
        - `x` number, double: Hotspot: tọa độ trái của vùng theo tỷ lệ bề rộng ảnh (0..1)
        - `y` number, double: Hotspot: tọa độ trên của vùng theo tỷ lệ chiều cao ảnh (0..1)
        - `w` number, double: Hotspot: bề rộng vùng theo tỷ lệ (0..1)
        - `h` number, double: Hotspot: chiều cao vùng theo tỷ lệ (0..1)
        - `blankKind` string: FillInBlank: kiểu ô trống - text | choice | number | symbol
        - `placeholder` string: FillInBlank: gợi ý trong ô trống
        - `maxLength` integer: FillInBlank (text): độ dài tối đa (mặc định 200)
        - `min` number, double: FillInBlank (number): giá trị nhỏ nhất
        - `max` number, double: FillInBlank (number): giá trị lớn nhất
        - `required` boolean: FillInBlank: ô trống bắt buộc khi câu hỏi bắt buộc (mặc định true)
        - `width` string: FillInBlank: độ rộng ô - sm | md | lg
        - `icon` string: Lựa chọn: icon đại diện - tên trong bộ icon khảo sát (@fireant-media/survey-ui/icons, Lucide), ví dụ "wallet", "trending-up". Chỉ kiểm tra dạng tên (chữ thường, số, "-", tối đa 40 ký tự) để thêm icon mới không cần deploy API.
        - `emoji` string: Lựa chọn: emoji đại diện (cũ - survey-ui tự đổi emoji quen thuộc sang icon; khảo sát mới dùng Icon)
        - `description` string: Lựa chọn dạng thẻ: mô tả phụ
      - `parentOptionId` integer: BlankChoice: optionId của ô trống cha
    - `conditions` FireAntApiModelsSurveysSurveyQuestionConditionItem[]: Điều kiện hiển thị (rỗng = luôn hiển thị)
      - `conditionId` integer: ID điều kiện
      - `questionId` integer: Câu hỏi bị điều kiện
      - `sourceQuestionId` integer: Câu hỏi nguồn (luôn đứng trước câu bị điều kiện)
      - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
      - `optionId` integer: Lựa chọn của câu nguồn để so sánh (các loại chọn)
      - `value` string: Giá trị để so sánh (số, text, true/false, ngày ISO)
      - `orderIndex` integer: Thứ tự
    - `carryForwardQuestionId` integer: Lấy lựa chọn từ đáp án câu trước: câu nguồn (cùng số lựa chọn, ánh xạ theo thứ tự). Chỉ hiện các lựa chọn tương ứng đã chọn (Selected) hoặc chưa chọn (NotSelected) ở câu nguồn.
    - `carryForwardMode` 1 | 2: Cách lấy lựa chọn từ câu nguồn (1 = Selected, 2 = NotSelected)
    - `jumps` FireAntApiModelsSurveysSurveyQuestionJumpItem[]: Quy tắc nhảy sau câu này (quy tắc đầu tiên khớp được dùng)
      - `jumpId` integer: ID quy tắc
      - `questionId` integer: Câu hỏi nguồn
      - `targetQuestionId` integer: Câu/phần đích (đứng sau câu nguồn). Null = kết thúc khảo sát
      - `conditionLogic` 0 | 1: Cách kết hợp điều kiện (0 = All, 1 = Any)
      - `orderIndex` integer: Thứ tự xét
      - `conditions` FireAntApiModelsSurveysSurveyJumpConditionItem[]: Điều kiện (cùng phép so sánh với rẽ nhánh; câu nguồn là câu này hoặc câu trước đó)
        - `conditionId` integer: ID điều kiện
        - `jumpId` integer: ID quy tắc
        - `sourceQuestionId` integer: Câu hỏi nguồn
        - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
        - `optionId` integer: Lựa chọn so sánh
        - `value` string: Giá trị so sánh
        - `orderIndex` integer: Thứ tự
  - `audienceRules` FireAntApiModelsSurveysSurveyAudienceRuleItem[]: Quy tắc nhắm đối tượng (rỗng = mọi người dùng)
    - `ruleId` integer: ID quy tắc
    - `surveyId` integer: ID khảo sát
    - `ruleType` 1 | 2 | 3 | 4 | 5 | 6 | 7: Loại quy tắc (1 = Platform, 2 = AppVersion, 3 = MembershipLevel, 4 = Role, 5 = UserName, 6 = IdentityVerified, 7 = Tag)
    - `operator` 1 | 2 | 3 | 4 | 5 | 6: Phép so sánh (1 = In, 2 = NotIn, 3 = GreaterOrEqual, 4 = LessOrEqual, 5 = Equals, 6 = NotEquals)
    - `value` string: Giá trị so sánh, danh sách phân cách bởi dấu phẩy với In/NotIn (VD: "ios,android", "2", "user1,user2", "1.5.0", "true")
    - `orderIndex` integer: Thứ tự
  - `outcomeRules` FireAntApiModelsSurveysSurveyOutcomeRuleItem[]: Hành động sau khảo sát (rỗng = không có). Client có thể dùng để xem trước; server là nơi quyết định khi gửi.
    - `ruleId` integer: ID quy tắc
    - `surveyId` integer: ID khảo sát
    - `orderIndex` integer: Thứ tự ưu tiên (nhỏ hơn được xét trước)
    - `title` string: Tiêu đề hiển thị trên màn hình cảm ơn (tùy chọn)
    - `description` string: Mô tả ngắn lý do gợi ý (tùy chọn)
    - `buttonLabel` string: Nhãn nút bấm
    - `actionType` 1 | 2 | 3 | 4: Loại hành động (1 = Url, 2 = AppRoute, 3 = Survey, 4 = Symbol)
    - `actionValue` string: Giá trị hành động: URL (Url), JSON {route, routeParams} (AppRoute), SurveyId (Survey), mã CK (Symbol). Hỗ trợ placeholder {answer:N}, {surveyId}, {responseId}, {userName}, {anonymousId}.
    - `openInNewTab` boolean: Mở trong tab mới (chỉ có ý nghĩa với Url trên web)
    - `conditionLogic` 0 | 1: Cách kết hợp điều kiện: All (mặc định) hoặc Any (0 = All, 1 = Any)
    - `isDefault` boolean: Quy tắc mặc định: áp dụng khi không quy tắc nào khác khớp (tối đa một)
    - `conditions` FireAntApiModelsSurveysSurveyOutcomeConditionItem[]: Điều kiện (rỗng với quy tắc mặc định)
      - `conditionId` integer: ID điều kiện
      - `ruleId` integer: ID quy tắc
      - `sourceQuestionId` integer: Câu hỏi nguồn
      - `operator` 1 | 2 | 3 | 4 | 5 | 6 | 7: Phép so sánh (1 = Equals, 2 = NotEquals, 3 = Contains, 4 = GreaterThan, 5 = LessThan, 6 = Answered, 7 = NotAnswered)
      - `optionId` integer: Lựa chọn của câu nguồn để so sánh
      - `value` string: Giá trị so sánh (số, text, true/false, ngày)
      - `orderIndex` integer: Thứ tự
  - `surveyId` integer: ID khảo sát
  - `code` string: Mã/slug khảo sát (tùy chọn)
  - `title` string: Tiêu đề
  - `description` string: Mô tả
  - `thankYouMessage` string: Lời cảm ơn hiển thị sau khi gửi
  - `imageUrl` string: Ảnh minh họa
  - `status` 0 | 1 | 2 | 3: Trạng thái (0 = Draft, 1 = Published, 2 = Closed, 3 = Archived)
  - `isAnonymous` boolean: Cho phép trả lời không cần đăng nhập
  - `allowMultipleResponses` boolean: Cho phép một người trả lời nhiều lần
  - `showResults` boolean: Cho phép người trả lời xem kết quả tổng hợp
  - `startDate` string, date-time: Thời điểm bắt đầu nhận phản hồi (null = ngay khi publish)
  - `endDate` string, date-time: Thời điểm kết thúc nhận phản hồi (null = không giới hạn)
  - `maxResponses` integer: Số phản hồi tối đa (null = không giới hạn)
  - `targetAudience` string: Nhóm đối tượng (all, premium, ios, android...)
  - `priority` integer: Ưu tiên hiển thị (cao hơn lên trước)
  - `displayMode` 0 | 1 | 2: Cách hiển thị trên App/Web: 0 ListOnly, 1 Banner, 2 Prompt (0 = ListOnly, 1 = Banner, 2 = Prompt)
  - `dismissible` boolean: Cho phép người dùng "Để sau" / "Không quan tâm"
  - `snoozeDays` integer: Số ngày ẩn khảo sát khi người dùng chọn "Để sau"
  - `showToGuests` boolean: Khảo sát yêu cầu đăng nhập vẫn hiện với khách chưa đăng nhập (client mời đăng nhập khi bấm vào)
  - `presentationMode` 0 | 1 | 2: Chế độ trình bày: 0 cuộn một trang, 1 mỗi Section một trang, 2 mỗi câu một màn hình (0 = Scroll, 1 = SectionPages, 2 = OneByOne)
  - `settings` FireAntApiModelsSurveysSurveySettings: Thiết lập trình bày của khảo sát (JSON trong Surveys.Settings). Client dùng; bỏ trống = mặc định.
    - `autoAdvance` boolean: Tự chuyển sang câu sau khi chọn xong câu chọn một / Có-Không / thang điểm (chế độ từng câu). Mặc định true
    - `showWelcome` boolean: Hiện màn hình mở đầu (ảnh bìa, thời gian ước tính, nút Bắt đầu) ở chế độ từng câu. Mặc định true
    - `showProgress` boolean: Hiện thanh tiến độ. Mặc định true
    - `allowBack` boolean: Cho quay lại câu trước. Mặc định true
    - `celebrate` boolean: Hiệu ứng chúc mừng khi hoàn thành. Mặc định true
    - `showQuestionNumbers` boolean: Hiện số thứ tự câu hỏi. Mặc định true
    - `accentColor` string: Màu nhấn của khảo sát (#RRGGBB). Bỏ trống = màu thương hiệu của ứng dụng
    - `welcomeTitle` string: Tiêu đề màn hình mở đầu (bỏ trống = tiêu đề khảo sát)
    - `welcomeButton` string: Nhãn nút bắt đầu (bỏ trống = "Bắt đầu")
    - `estimatedMinutes` integer: Thời gian ước tính (phút) ghi đè cách tính tự động
  - `isDismissed` boolean: Người dùng hiện tại đang bỏ qua khảo sát này (Để sau còn hạn hoặc Không quan tâm)
  - `dismissedUntil` string, date-time: Ẩn đến thời điểm này (null nếu không bỏ qua hoặc ẩn hẳn)
  - `dismissCount` integer: Số người đã bỏ qua khảo sát (admin)
  - `targetCount` integer: Số đối tượng khảo sát được gắn vào (0 = khảo sát chung)
  - `targetSummary` string: Tóm tắt đối tượng gắn kèm cho admin, ví dụ "symbol:FPT, post:40203799"
  - `targets` FireAntApiModelsSurveysSurveyTargetItem[]: Đối tượng gắn kèm (có trong chi tiết và danh sách người dùng cuối)
    - `targetId` integer: ID bản ghi
    - `surveyId` integer: ID khảo sát
    - `targetType` string: Loại đối tượng (chữ thường): post, symbol, room, user, event, article, url...
    - `targetKey` string: Khóa đối tượng: postId, mã CK (viết hoa), roomId, userId, URL...
    - `orderIndex` integer: Thứ tự hiển thị
  - `questionCount` integer: Số câu hỏi
  - `responseCount` integer: Số phản hồi đã nhận
  - `hasResponded` boolean: Người dùng hiện tại đã trả lời khảo sát này chưa
  - `hasDraft` boolean: Người dùng hiện tại đang có bản nháp chưa gửi
  - `draftCount` integer: Số bản nháp đang tồn tại (admin)
  - `isActive` boolean: Khảo sát đang trong thời gian nhận phản hồi
  - `createdBy` string: Người tạo
  - `createdDate` string, date-time: Ngày tạo
  - `updatedBy` string: Người cập nhật cuối
  - `updatedDate` string, date-time: Ngày cập nhật cuối
  - `publishedDate` string, date-time: Ngày publish
  - `closedDate` string, date-time: Ngày đóng
  - `isDeleted` boolean: Đã xóa mềm

## Other responses

- `400`: Dữ liệu không hợp lệ / khảo sát đã có phản hồi
- `404`: Không tồn tại

## Changes

- **2026-09-25** `a481789cd81c`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/fireant/apis/fireant-restful-api/changes/admin/surveys/:surveyId/put.md)

---

[API](https://skmtc.dev/fireant/apis/fireant-restful-api.md) - [All operations](https://skmtc.dev/fireant/apis/fireant-restful-api/llms.txt) - [OpenAPI document](https://skmtc.dev/fireant/apis/fireant-restful-api/revisions/c9b3aa855f95?raw)
