Skip to main content

API: POST /track/open

Bạn sẽ học: Toàn bộ hợp đồng của endpoint POST /api/v1/track/open — cách xác thực, các trường request, server chọn đường xử lý ra sao, hình dạng response, và ý nghĩa từng giá trị matchMethod / missReason.

Endpoint & môi trường

Đây là base URL production duy nhất — dùng chung cho mọi organization, không có host sandbox/staging riêng. Bạn test ngay trên production bằng custom domain đã verify của mình và một bản cài thật từ store (TestFlight/internal-test) — xem Kiểm thử trên production. Endpoint đi qua các middleware: CORS, rate limit (1000 request/phút/IP), và AuthMobileApikeyMiddleware.

Xác thực

Gửi publishable key trong header:
  • Lấy publishable key ở đâu: dashboard → Settings → Analytics → Publishable Key (dạng li2_pk_...). Key được tạo tự động khi bật Analytics; chi tiết tại Thiết lập Conversion Tracking.
  • Fallback cho caller không đặt được custom header (ví dụ sendBeacon): tham số query ?li2_key=....
  • Không dùng server API key (X-Li2-API-Key) cho endpoint này — sẽ trả về 401. Endpoint mobile chỉ chấp nhận key dạng li2_pk_*.
Vì sao publishable key an toàn khi nhúng trong app: với request từ web (có Origin/Referer), server kiểm tra origin theo whitelist của key. Với app native (không có Origin/Referer), server bỏ qua bước origin và kiểm tra phía server rằng domain được track thuộc đúng organization của key. Key không thể dùng để track domain tùy ý hay truy cập dữ liệu org khác.

Request

Request
Phải có ít nhất một trong deepLink, li2Domains, hoặc installReferrer.

Server chọn đường xử lý như thế nào

Trước khi xử lý, server kiểm tra org có gói Pro (deep_link_attribution) và suy ra platform (ios/android) từ User-Agent.

Response

Response
  • Khi khớp: link được điền, missReason bị bỏ qua.
  • Khi trượt (deferred không đối chiếu được): linknull, missReason được điền.
  • clickId luôn có: dùng id của click gốc khi khớp, hoặc một id ngẫu nhiên khi trượt (đồng thời ghi một dòng deferred_miss).
  • link.idUUID của touch point (cấu hình link trong Li2), không phải id của short link hiển thị hay của click. Điều hướng người dùng bằng link.url; link.key là slug, link.domain là host.

Ví dụ theo từng luồng

Mỗi tab là một lệnh curl chạy được (thay your-domain.comli2_pk_... bằng giá trị của bạn) kèm response mẫu.
platformmatchMethod suy ra từ User-Agent. Server đọc UA của request để phân loại ios/android. Một lệnh curl mặc định (UA curl/8.x) khớp không nền tảng nào → trả về platform: nullmatchMethod rỗng. Vì vậy các ví dụ dưới đây đều kèm header -A giả lập UA thiết bị để response khớp như minh họa. Từ app thật, UA của URLSession/okhttp đã chứa sẵn dấu hiệu nền tảng nên bạn không cần làm gì thêm.
App đã cài, mở qua Universal Link / App Link — chỉ gửi deepLink, khôngli2_cid:
Request
Response · 200
Trên Android, cùng request này trả về "matchMethod": "app_link""platform": "android".

Giá trị matchMethod

Giá trị missReason

Mã trạng thái

Cô lập tenant ở luồng deferred (clipboard/referrer) không trả 403 mà trả 200 + missReason: cross_tenant_blocked (link: null) — để không lộ việc hostname có thuộc org khác hay không. Chỉ luồng immediate mới trả 403 khi domain không thuộc org.

Hình dạng body lỗi

Response thành công là object phẳng ({ clickId, link, ... } như trên — không bọc envelope). Mọi response lỗi dùng chung một envelope:
Error
  • code = HTTP status; message = mô tả tiếng Anh dễ đọc; data luôn null khi lỗi.
  • error_codemã ổn định, máy đọc được — hãy branch theo nó thay vì so khớp chuỗi message. Hầu hết lỗi phía client (4xx) đều kèm error_code; lỗi server (5xx) trả cùng envelope nhưng khôngerror_code (chỉ cần retry/backoff). Ngoại lệ quan trọng: lỗi xác thực sinh ở tầng middleware (key thiếu/sai, origin sai) không kèm error_code — xem cảnh báo bên dưới.

Các error_code của endpoint

Lỗi xác thực ở tầng middleware không có error_code. Bảng trên là các mã do controller phát ra sau khi đã qua xác thực. Nhưng khi X-Li2-Key thiếu hoặc sai, hoặc origin không hợp lệ (luồng web SDK), request bị chặn ngay ở middleware (AuthMobileApikeyMiddleware) — và những phản hồi đó dùng envelope cũ không có trường error_code:
Hệ quả thực tế cho client: với lỗi xác thực (401/403 từ middleware) hãy branch theo HTTP status; chỉ với lỗi validation/nghiệp vụ (4xx từ controller) mới có error_code để branch. Cụ thể: MISSING_API_KEY (401) chỉ xuất hiện ở một nhánh nội bộ của controller, không phải mã bạn nhận khi gửi key sai — trường hợp đó là 401 không kèm error_code. Tương tự, CROSS_ORG_ATTRIBUTION là mã của controller (luồng immediate, domain không thuộc org); còn 403 do origin sai ở middleware thì không kèm error_code.

Bước tiếp theo

Tích Hợp iOS & Android

Xem cách gọi endpoint này từ app native.

Tổng Quan Deep Link

Quay lại bức tranh tổng thể về immediate vs deferred.