Skip to main content
Hướng dẫn này là một ví dụ trọn vẹn về việc đọc /v1 vào Power BI. Hướng dẫn bao gồm mẫu kết nối Power Query (M), mô hình ngữ nghĩa lược đồ hình sao được xây dựng trên /v1/activities, làm mới gia tăng, và thời điểm nên dùng các tập dữ liệu xem trước reporting cho kết quả phishing theo từng cá nhân. Các ví dụ sử dụng máy chủ production tại Hoa Kỳ (https://api.us-east-1.livingsecurity.ai/v1). Đối với tổ chức tại EU, hãy dùng https://api.eu-west-1.livingsecurity.ai/v1 ở cả Fn_FetchAll và Fn_GetJson, sau đó liên kết thông tin xác thực của nguồn dữ liệu với máy chủ đó. Xem Khu vực. Hướng dẫn này sử dụng thông tin xác thực Basic được lưu trữ cùng với khóa API. Quý vị không cần máy khách OAuth. Xem Xác thực để biết các lựa chọn thông tin xác thực, và Developer Hub để biết cách truy cập và thiết lập.

Mục đích của ví dụ này

Hãy sử dụng khi quý vị cần:
  • Tải các endpoint danh sách /v1 vào tập dữ liệu Power BI với phân trang theo con trỏ chính xác và cơ chế thử lại khi gặp giới hạn tốc độ.
  • Xây dựng mô hình ngữ nghĩa trong đó các thước đo (“thực thể hoạt động”, “hoạt động trên mỗi thực thể hoạt động”) mang tính chiều thay vì được đếm từ một bảng phẳng.
  • Chuyển việc làm mới theo lịch của Power BI từ việc duyệt toàn bộ lịch sử xuống một khoảng thời gian nhỏ hằng ngày bằng cách làm mới gia tăng.
  • Chọn đúng mức chi tiết cho phishing: tổng số theo chiến dịch (vận hành) so với kết quả theo từng cá nhân và các sự kiện có kiểu (xem trước báo cáo).

Điều kiện tiên quyết

  • Một khóa API có các quyền mà truy vấn của quý vị cần:
    • Ví dụ vận hành: activity:read, entity:read và simulation:read.
    • Phishing theo từng cá nhân thông qua các tập dữ liệu báo cáo: reporting:read. Xem Khóa API.
  • Power BI Desktop, hoặc một không gian làm việc Power BI / Fabric nơi quý vị có thể tạo mô hình ngữ nghĩa và lên lịch làm mới.

Chọn đúng mức chi tiết

/v1 cung cấp hai bề mặt liên quan cho phishing. Hai bề mặt này không thể thay thế cho nhau. Các truy vấn ví dụ Power BI bên dưới gọi các route vận hành (/v1/simulations, /v1/simulations/{id}/results, /v1/activities, /v1/entities). Đối với báo cáo phishing theo từng cá nhân, nên ưu tiên dùng nhóm xem trước reporting bên dưới. Khóa chỉ được cấp reporting:read không thể gọi /v1/simulation_results vận hành (API trả về 403).

Thang độ khó

Độ khó của mô phỏng là số nguyên từ 1–5 trên /v1/simulations (difficulty_level), /v1/simulation_results (difficulty_level), các thuộc tính /v1/activities (difficulty_tier) và /v1/reporting/simulation_events (difficulty_tier). 1 là dễ nhất và 5 là khó nhất. Các mô phỏng thích ứng và lũy tiến không có giá trị đơn nhất ở cấp chiến dịch, do đó /v1/simulations.difficulty_level là null trong khi difficulty_level theo từng người nhận trên kết quả vẫn có thể được đặt. Để ánh xạ sang các bản xuất cũ theo mức thấp/trung bình/cao, hãy xem 1–2 là thấp, 3 là trung bình và 4–5 là cao.
Không xây dựng các tích hợp BI mới dựa trên các lệnh gọi mạng Bảng điều khiển không được ghi chép hoặc phần tổng quan Public API /api/v1 được tuyển chọn cũ. Hãy xác thực với máy chủ /v1 theo khu vực của tổ chức bằng khóa API của Developer Hub. Xem Khu vực.

Mẫu kết nối (Power Query)

Bốn quy tắc làm nền tảng cho mọi truy vấn trong ví dụ. Mỗi quy tắc được áp dụng bởi Power BI Service chứ không phải do sở thích về phong cách.
Đặt mọi thành phần động vào RelativePath và Query. Đối số đầu tiên của Web.Contents phải là một chuỗi literal kết thúc tại gốc /v1 theo khu vực của tổ chức:
  • US: https://api.us-east-1.livingsecurity.ai/v1
  • EU: https://api.eu-west-1.livingsecurity.ai/v1
Khi đó bên gọi chỉ truyền tài nguyên ("simulations", không phải "v1/simulations"). Không dán máy chủ US cho tổ chức tại EU.Nếu đối số đầu tiên được tạo bằng cách nối chuỗi, Power BI Service không thể xác định tĩnh nguồn dữ liệu và việc làm mới theo lịch sẽ thất bại với lỗi “dynamic data source”, mặc dù truy vấn vẫn hoạt động trong Power BI Desktop.
Khi Power BI nhắc nhập thông tin xác thực cho nguồn dữ liệu /v1, hãy chọn Basic và dán khóa API vào mục username. Đặt một giá trị giữ chỗ như x vào trường Mật khẩu. Power BI Service từ chối mật khẩu để trống mặc dù API bỏ qua trường này. Dùng khóa làm mật khẩu với tên người dùng giữ chỗ cũng hoạt động.Không thêm tiêu đề Authorization trong M. Cách này chạy được trên máy tính của quý vị, nhưng sau đó nhúng khóa vào tệp truy vấn và gây xung đột với việc làm mới theo lịch.
GET /v1 yêu cầu xác thực: nó trả về 200 với khóa hợp lệ và 401 nếu không có khóa. Trỏ nguồn dữ liệu tới …/v1 và không bỏ qua bước kiểm tra — khóa hợp lệ sẽ được lưu, còn khóa bị thu hồi hoặc sai định dạng sẽ thất bại ngay lập tức.Các ví dụ cũ dùng máy chủ trần làm nguồn dữ liệu và yêu cầu bỏ qua bước kiểm tra vì GET / luôn là 404. Hãy trỏ lại các mô hình đó tới …/v1.
Kích thước trang mặc định trên mọi endpoint danh sách /v1 là 25. Để mặc định sẽ làm tăng số lượng yêu cầu cho cùng một lượng dữ liệu. Giá trị truy vấn phải là văn bản — limit = "500" trong M, không phải limit = 500.

Hàm phân trang dùng chung

Mọi truy vấn trong ví dụ đều gọi một Fn_FetchAll duy nhất duyệt next_page_token cho đến khi nó là null (xem phân trang). Các đặc điểm đáng chú ý:
  • URL cơ sở /v1 tĩnh, RelativePath và Query động. Bắt buộc đối với việc làm mới theo lịch và bước kiểm tra thông tin xác thực.
  • ManualStatusHandling = {429} với số lần thử lại có giới hạn. Hàm đọc Retry-After khi Power Query cung cấp, nếu không thì chờ 30 giây, và dừng sau 5 phản hồi 429 liên tiếp với một lỗi tường minh thay vì lặp cho đến khi việc làm mới hết thời gian. 5xx được cố ý không thử lại — lỗi máy chủ cần được hiển thị, không âm thầm tạo ra một tập dữ liệu không đầy đủ.
  • Timeout 60 giây. Các trang thường phản hồi trong chưa đầy một giây, do đó một phút không có phản hồi nghĩa là yêu cầu đã chết.
  • Binary.Buffer trước Json.Document. Nếu không có bộ đệm, engine mashup có thể yêu cầu lại luồng phản hồi nếu đọc nó nhiều hơn một lần.
  • baseQuery được truyền nguyên vẹn ở mỗi lần lặp. Mã thông báo trang là con trỏ có chữ ký, không trong suốt, gắn với tổ chức, thông tin xác thực, phiên bản hợp đồng, và dấu vân tay của bộ lọc và sắp xếp. Thay đổi bộ lọc giữa chừng sẽ bị từ chối như một mã thông báo không hợp lệ thay vì bắt đầu lại từ trang một.
Fn_FetchAll.pq — base and call shape

Truy vấn có kiểu cho từng endpoint

Mọi bên sử dụng Fn_FetchAll đều theo cùng một cấu trúc: gọi endpoint, chiếu một danh sách cột cố định, loại bỏ bộ phân biệt object, và định kiểu dấu thời gian là datetimezone để các thước đo ngày không bị lệch âm thầm theo múi giờ của dung lượng làm mới.
Danh sách cột tường minh trên Table.FromRecords giữ cho lược đồ ổn định khi endpoint trả về không dòng nào. Một Table.FromRecords({}) trần tạo ra một bảng không có cột và mọi bước sau đó đều thất bại do thiếu các trường.

Excel

Cùng Power Query (M) chạy trong Get & Transform của Excel — đây là cùng một engine với Power BI Desktop. Hãy dùng cách này khi quý vị muốn có bảng trong worksheet thay vì mô hình ngữ nghĩa. Trên Excel dành cho Windows (Microsoft 365, Excel 2024, 2021, 2019 hoặc 2016):
  1. Data → Get Data → From Other Sources → Blank Query.
  2. Trong Power Query Editor, chọn Home → Trình chỉnh sửa nâng cao. Dán Fn_FetchAll trước, sau đó đổi tên truy vấn đó thành Fn_FetchAll (Query Settings → Name, hoặc nhấp chuột phải trong ngăn Queries → Rename).
  3. Lặp lại cho Fn_GetJson, rồi cho từng truy vấn báo cáo.
  4. Home → Close & Load → Close & Load To… mở hộp thoại Import Data. Chọn Only Create Connection cho Fn_FetchAll và Fn_GetJson (chúng là hàm, không phải bảng). Chọn Table cho từng truy vấn báo cáo mà quý vị muốn đưa vào worksheet.
  5. Ở lần làm mới đầu tiên, chọn Basic: khóa API làm User name, một giá trị giữ chỗ như x làm Mật khẩu. Excel lưu một thông tin xác thực cho mỗi URL nguồn dữ liệu; các truy vấn sau đó truy cập cùng máy chủ /v1 sẽ dùng lại thông tin đó.
Close & Load To… có thể bị mờ ở lần đầu quý vị tạo truy vấn trong một workbook. Hãy dùng Close & Load, sau đó trong Excel chọn Data → Queries & Connections, nhấp chuột phải vào truy vấn và chọn Load To. Microsoft có ghi chép đường dẫn này cho trường hợp này.
Quý vị không thể gửi Living-Security-Version từ Power Query trên một nguồn đã xác thực — cùng hạn chế như Power BI. Hãy ghim tài khoản dịch vụ hoặc truyền api_version trong bản ghi truy vấn. Xem Phiên bản hợp đồng và thông tin xác thực được lưu trữ. Các truy vấn báo cáo dựng sẵn (ánh xạ cột và những điểm khác biệt so với bản xuất của nhà cung cấp trước đây):

Tuân thủ theo từng cá nhân

Các lượt ghi danh Đào tạo ở mức chi tiết người × bài giao.

Nhật ký phishing qua email

Các tương tác phishing ở cấp sự kiện, 12 tháng gần nhất.

Người dùng dễ bị tấn công nhất

Tổng hợp 12 tháng theo từng cá nhân về nhấp chuột, thông tin xác thực và báo cáo.

Tập dữ liệu xem trước báo cáo (phishing theo từng cá nhân)

Nhóm tập dữ liệu xem trước báo cáo cung cấp các tập dữ liệu cho phishing theo từng cá nhân. Nhóm này yêu cầu reporting:read và quyền truy cập báo cáo cho tổ chức của quý vị. Hãy dùng danh mục tập dữ liệu bên dưới để kiểm tra lược đồ và chính sách dữ liệu của chúng. Khám phá danh mục trực tiếp:
Mỗi tập dữ liệu khai báo mức chi tiết, khóa chính, các phép nối, mốc, chính sách hiệu chỉnh và chính sách xóa.

simulation_results

  • Đường dẫn: GET /v1/reporting/simulation_results
  • Mức chi tiết: thực thể × mô phỏng
  • Bộ lọc: simulation, entity, updated_after, cộng với limit / page_token
  • Đối tượng wire: reporting.simulation_result
  • Khóa nối: entity_id, simulation_id
ReportingSimulationResults.pq (sketch)
Hãy dùng updated_after làm mốc dưới bao gồm khi quý vị làm mới các phân vùng gần đây. Các chiều kết quả có thể thay đổi sẽ được ghi lại tại chỗ dưới cùng id.

simulation_events

  • Đường dẫn: GET /v1/reporting/simulation_events
  • Mức chi tiết: một dữ kiện có kiểu cho mỗi tương tác được quan sát
  • Bộ lọc: simulation, entity, event_type, occurred_after, cộng với limit / page_token
  • Đối tượng wire: reporting.simulation_event
  • Loại sự kiện: các mã thông báo công khai đã đóng như simulation.delivered, simulation.opened, simulation.link_clicked, simulation.credentials_submitted, simulation.reported — không phải các loại hoạt động phishing.simulation.* ClickHouse thô
  • Thiết bị: device_type là lớp được suy ra (các mã thông báo quan sát được gồm desktop, mobile, tablet, unknown). user_agent thô không có trên /v1. IP thô không bao giờ có trên /v1 (không bao giờ được lưu trữ; chỉ có ip_hash đã thêm salt).
ReportingSimulationEvents.pq (sketch)
Hãy dùng occurred_after cho các lần tải sự kiện gia tăng. Các dữ kiện chỉ được nối thêm; dữ liệu đến muộn là các dòng mới.

entities

  • Đường dẫn: GET /v1/reporting/entities
  • Mức chi tiết: một dòng hiện tại cho mỗi thực thể
  • Bộ lọc: type, updated_after, cộng với limit / page_token
  • Đối tượng wire: reporting.entity
  • Khóa nối: id / entity_id (cùng giá trị)
Nối các dữ kiện phishing với con người bằng reporting.simulation_results.entity_id = reporting.entities.id. GET /v1/entities vận hành vẫn nằm trên entity:read và là một quyền khác.
ReportingEntities.pq

entity_versions và cohort_memberships

Hai tập dữ liệu này có một ngoại lệ chỉ-hiện-tại được nêu tên:
Không tồn tại bảng lịch sử phiên bản hoặc tư cách thành viên có thẩm quyền. Tập dữ liệu này chiếu dòng hiện tại thành một khoảng không giới hạn cuối (valid_to là null, is_current là true). valid_from là created_at hoặc nếu không thì updated_at đối với phiên bản thực thể, và là thời điểm quan sát yêu cầu đối với tư cách thành viên Nhóm. Các khoảng lịch sử đã đóng không được tạo ra giả.
  • entity_versions: GET /v1/reporting/entity_versions. Cùng bộ lọc với entities. valid_from là created_at hoặc nếu không thì updated_at. Một thực thể có cả hai dấu thời gian là null sẽ bị bỏ qua.
  • cohort_memberships: GET /v1/reporting/cohort_memberships. Bộ lọc: cohort, entity, updated_after. updated_at là lần cập nhật cuối của Nhóm để việc làm mới gia tăng luôn chính xác. valid_from là thời điểm quan sát yêu cầu. Nối entity_id với reporting.entities.id.
ReportingEntityVersions.pq
ReportingCohortMemberships.pq

Mô hình ngữ nghĩa lược đồ hình sao trên /v1/activities

/v1/activities là luồng sự kiện có dấu thời gian của tổ chức. Nó không có thước đo số nào — mọi đại lượng trong báo cáo đều là số dòng được đếm — điều này khiến lược đồ hình sao trở nên rất phù hợp.
  • Activities là bảng dữ kiện sự kiện ở mức chi tiết thực. Một dòng cho mỗi hoạt động. Người tham gia được loại bỏ ở đây và được dựng lại thành bảng riêng.
  • ActivityParticipants tồn tại vì người tham gia thực sự là quan hệ một-nhiều, với các vai trò như actor và target. Làm phẳng vào Activities sẽ hoặc nhân đôi các dòng hoạt động (làm phồng mọi số đếm) hoặc loại bỏ các người tham gia bổ sung. Quan hệ với Activities là quan hệ hai chiều duy nhất của mô hình, nhờ đó bộ cắt lát thực thể tác động được tới bảng dữ kiện.
  • Entities là chiều đặt tên cho người tham gia. Các dòng người tham gia trên một hoạt động mang entity_id và một vai trò nhưng không có tên hiển thị.
  • Dates được tạo trong M (không có lệnh gọi API nào) và được đánh dấu là bảng ngày của mô hình. Điều đó giúp cho DAX time intelligence (DATESINPERIOD, DATEADD) hợp lệ. Các cột tên tháng và tên thứ trong tuần khai báo sortByColumn trên các cột số tương ứng để các hình ảnh trực quan không sắp xếp tháng theo thứ tự bảng chữ cái.
Tất cả thước đo đều tường minh (mô hình đặt discourageImplicitMeasures): tổng số hoạt động, thực thể hoạt động, hoạt động trên mỗi thực thể hoạt động, số ngày có hoạt động, và trung bình hằng ngày trong 7 ngày gần nhất.

Cấu trúc bảng cầu nối

ActivityParticipants duyệt /v1/activities và bung mảng participants thành một dòng cho mỗi người tham gia:
ActivityParticipants.pq
ActivityParticipants duyệt /v1/activities một cách độc lập thay vì tham chiếu truy vấn Activities. Trong Power BI, hai truy vấn được tải thành hai bảng sẽ mỗi bảng tự lấy dữ liệu độc lập tại thời điểm làm mới. Giữ chúng độc lập cho phép dịch vụ làm mới song song các phân vùng của cả hai bảng.

Làm mới gia tăng

Cả hai bảng dữ kiện (Activities và ActivityParticipants) đều khai báo một chính sách làm mới gia tăng của Power BI: giữ 5 năm phân vùng theo năm, nhập lại 14 ngày gần nhất ở mỗi lần làm mới. Cơ chế này là một cặp tham số DateTime, RangeStart và RangeEnd, mà dịch vụ Power BI gán lại cho từng phân vùng tại thời điểm làm mới. Mỗi truy vấn dữ kiện đưa các tham số đó vào các bộ lọc start_date và end_date của API, do đó lượng yêu cầu ở cấp phân vùng tỷ lệ với phân vùng, chứ không phải với tổng lịch sử. Truy vấn mở rộng cửa sổ API thêm một phút ở mỗi phía và áp dụng lại ranh giới nửa mở [RangeStart, RangeEnd) chính xác tại chỗ, nhờ đó tính đúng đắn của phân vùng không phụ thuộc vào việc máy chủ coi các cận là bao gồm hay loại trừ.
Activities.pq — the fold that makes incremental refresh work
Lần làm mới đầu tiên sau khi triển khai sẽ áp dụng chính sách: một lần tải toàn bộ lịch sử, chậm. Mọi lần làm mới sau đó chỉ chạm tới cửa sổ gia tăng. Được đo trên tập dữ liệu khoảng 158.000 hoạt động và khoảng 2.300 thực thể:
Endpoint REST làm mới cổ điển của Power BI (POST .../refreshes chỉ với notifyOption) âm thầm bỏ qua các chính sách làm mới và duyệt toàn bộ mỗi lần. Để áp dụng chính sách qua REST API, hãy dùng làm mới nâng cao: gửi type, commitMode và applyRefreshPolicy trong nội dung yêu cầu. Các lần làm mới được kích hoạt bởi bộ lập lịch của Power BI Service luôn áp dụng chính sách — điểm bất thường này chỉ xảy ra với lệnh gọi REST.
Cửa sổ 14 ngày được cố ý đặt rộng rãi. Việc thu nạp hoạt động không phải là chỉ-nối-thêm-tại-thời-điểm-hiện-tại: các lần backfill của trình kết nối đưa vào các sự kiện có dấu thời gian trong quá khứ. Cửa sổ 1-2 ngày sẽ bỏ sót chúng vĩnh viễn.

Mở rộng cửa sổ làm mới vào API

GET /v1/activities chấp nhận các bộ lọc start_date và end_date mà các tham số Power BI được đưa vào, lọc event_ts giữa các cận. Entities là một chiều, do đó ví dụ này làm mới toàn bộ nó mỗi lần thay vì làm mới gia tăng. Các tập dữ liệu báo cáo dùng mốc riêng của chúng (updated_after, occurred_after) thay vì cửa sổ ngày của activities.

Giới hạn tốc độ trong khi làm mới

/v1 áp dụng các ngân sách riêng theo từng khóa và từng IP (xem giới hạn tốc độ). Hãy tuân thủ 429 + Retry-After; đừng mã hóa cứng ngân sách yêu cầu vào mô hình của quý vị. Hai đặc tính của việc làm mới Power BI đáng lưu ý:
  • Việc duyệt một bảng diễn ra tuần tự. Mỗi yêu cầu trang cần mã thông báo của trang trước, do đó một bảng bị giới hạn bởi độ trễ bất kể kích thước trang.
  • Việc làm mới đồng thời nhiều bảng làm tăng tải. Nhiều bảng lớn được làm mới song song là trường hợp chạm trần, đó là lý do đường thử lại 429 trong Fn_FetchAll quan trọng. Hãy ưu tiên ít bảng song song hơn thay vì giả định khả năng đồng thời không giới hạn.
Cơ chế thử lại đã được kiểm nghiệm với một bộ giới hạn thực sự bão hòa. Một lần làm mới chạy trong khi một khối lượng công việc song song cố ý giữ khóa ở mức trần vẫn hoàn tất và tạo ra cùng số dòng như đường cơ sở không tranh chấp — các lần thử lại trả về các trang đầy đủ, không có khoảng trống.

Phiên bản hợp đồng và thông tin xác thực được lưu trữ

/v1 chấp nhận tiêu đề yêu cầu Living-Security-Version để ghim một phiên bản hợp đồng đã xuất bản (xem Khởi động nhanh API). Power Query không thể gửi tiêu đề đó khi nguồn dữ liệu dùng thông tin xác thực được lưu trữ — chỉ các nguồn dữ liệu ẩn danh mới cho phép tiêu đề tùy chỉnh. Việc thêm tiêu đề này khiến việc làm mới thất bại với lỗi:
Hãy giữ khóa trong thông tin xác thực được lưu trữ của Power BI và bỏ qua tiêu đề tùy chỉnh. Khi yêu cầu không có phiên bản tường minh, API dùng contract_version đã ghim của tài khoản dịch vụ, hoặc phiên bản đã xuất bản mới nhất nếu không có ghim nào. Hãy xác nhận phiên bản hợp đồng của tài khoản với quản trị viên API của quý vị trước khi xuất bản một lần làm mới. Xem nhật ký thay đổi API để biết các phiên bản được hỗ trợ. Nếu một lần làm mới bắt đầu hoạt động không như mong đợi, hãy kiểm tra tiêu đề phản hồi Living-Security-Version của API để xem hợp đồng nào thực sự đã phục vụ yêu cầu.

Làm mới và xác minh mô hình của quý vị

Xuất bản mô hình ngữ nghĩa lên không gian làm việc Power BI của quý vị, liên kết thông tin xác thực được lưu trữ với nguồn /v1 theo khu vực, và chạy một lần làm mới trước khi bật lịch. Xem lại lịch sử làm mới để tìm lỗi hoặc các lần đọc không đầy đủ. Kiểm tra số dòng so với một lần đọc API độc lập dùng cùng các bộ lọc. Hướng dẫn phân trang có các ví dụ Python và cURL để đọc toàn bộ tập kết quả. Một lần làm mới chỉ đọc trang đầu tiên có thể trông như thành công trên tập dữ liệu nhỏ; hãy so sánh số đếm trước khi tin cậy vào báo cáo.

Lựa chọn mô hình

  • Tổng số theo chiến dịch và kết quả theo từng cá nhân có mức chi tiết khác nhau. SimulationResults gọi GET /v1/simulations/{id}/results (một GET cho mỗi lần chạy). Đối với phishing theo từng cá nhân, hãy thêm các truy vấn cho GET /v1/reporting/simulation_results và GET /v1/reporting/simulation_events (hoặc GET /v1/simulation_results vận hành nếu quý vị đã có simulation:read).
  • vectors trên /v1/simulations được làm phẳng thành một chuỗi nối bằng dấu phẩy. Cột kiểu danh sách không thể được dùng để cắt lát như một chiều thực sự. Nếu một trang báo cáo cần lọc theo vector, hãy thêm bảng cầu nối mô phỏng-vector.

Bước tiếp theo

Developer Hub

Tạo tài khoản dịch vụ và khóa API cho Power BI.

Khởi động nhanh API

Xác thực các yêu cầu /v1 bằng Basic auth.

Phân trang

Phong bì danh sách, mã thông báo con trỏ và tính ổn định của bộ lọc trong suốt một lần duyệt.

Giới hạn tốc độ

Ngân sách theo từng khóa và từng IP, hợp đồng 429 và hướng dẫn thử lại.