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
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ạngli2_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
| Trường | Bắt buộc | Ghi chú |
|---|---|---|
deepLink | Có điều kiện | URL hợp lệ, có host và path slug khác rỗng |
li2Domains | Có điều kiện | Mảng hostname (không kèm scheme/path) mà app được entitle. Thường chỉ một; gửi nhiều nếu app trải trên nhiều custom domain. Khi clipboard rỗng/từ chối, trường này cho server biết domain/org nào để ghi nhận deferred_miss đúng chỗ. |
clipboardStatus | Không | Chỉ nhận read, empty, denied, optout; giá trị khác → 400 |
installReferrer | Có điều kiện | Chuỗi referrer thô từ Google Play |
deepLink, li2Domains, hoặc installReferrer.
Server chọn đường xử lý như thế nào
| Điều kiện | Đường xử lý | Ý nghĩa |
|---|---|---|
Có installReferrer | Android deferred | Giải mã referrer, lấy li2_cid, đối chiếu deferred |
Có deepLink và có li2_cid | iOS clipboard deferred | Đối chiếu deferred theo clipboard token |
Có deepLink, không có li2_cid | Immediate | App đã cài, link mở bình thường |
Chỉ có li2Domains (kèm clipboardStatus) | Ghi nhận miss | iOS báo clipboard rỗng / từ chối / bỏ qua → ghi deferred_miss |
deep_link_attribution) và suy ra platform (ios/android) từ User-Agent.
Response
Response
- Khi khớp:
linkđược điền,missReasonbị bỏ qua. - Khi trượt (deferred không đối chiếu được):
linklànull,missReasonđược điền. clickIdluô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òngdeferred_miss).link.idlà UUID 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ằnglink.url;link.keylà slug,link.domainlà host.
Ví dụ theo từng luồng
Mỗi tab là một lệnhcurl chạy được (thay your-domain.com và li2_pk_... bằng giá trị của bạn) kèm response mẫu.
platform và matchMethod 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: null và matchMethod 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.- Immediate (đã cài app)
- iOS deferred (khớp)
- Android deferred (khớp)
- Deferred (trượt)
App đã cài, mở qua Universal Link / App Link — chỉ gửi Trên Android, cùng request này trả về
deepLink, không có li2_cid:Request
Response · 200
"matchMethod": "app_link" và "platform": "android".Giá trị matchMethod
| Giá trị | Ý nghĩa |
|---|---|
universal_link | iOS, app đã cài (immediate) |
app_link | Android, app đã cài (immediate) |
clipboard | iOS deferred, khớp qua li2_cid trên clipboard |
install_referrer | Android deferred, khớp qua Google Play Install Referrer |
Giá trị missReason
| Giá trị | Ý nghĩa |
|---|---|
no_candidate | Tra cứu clipboard không có kết quả (hoặc bản ghi đã hết hạn) |
clipboard_denied | Người dùng chặn quyền dán trên iOS |
clipboard_empty | Clipboard rỗng (không có link Li2) |
opt_out | Người dùng chủ động bỏ qua |
cross_tenant_blocked | Hostname thuộc organization khác — bị chặn theo cô lập tenant |
Mã trạng thái
| Status | Khi nào |
|---|---|
200 | Thành công (kể cả khi trượt — link: null + missReason) |
400 | Body sai định dạng / clipboardStatus không hợp lệ |
401 | Thiếu hoặc sai X-Li2-Key (hoặc gửi nhầm server API key) |
403 | Org không có gói Pro; hoặc (luồng immediate) domain không thuộc org / deep link bị tắt |
404 | Không tìm thấy slug (touch point) |
429 | Vượt 1000 request/phút/IP. Server đặt header X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset; hãy backoff theo đó. |
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;dataluônnullkhi lỗi.error_codelà mã ổn định, máy đọc được — hãy branch theo nó thay vì so khớp chuỗimessage. Hầu hết lỗi phía client (4xx) đều kèmerror_code; lỗi server (5xx) trả cùng envelope nhưng không cóerror_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èmerror_code— xem cảnh báo bên dưới.
Các error_code của endpoint
| HTTP | error_code | Khi nào |
|---|---|---|
| 400 | INVALID_JSON | Body không parse được |
| 400 | MISSING_REQUIRED_FIELD | Thiếu cả deepLink, li2Domains lẫn installReferrer |
| 400 | INVALID_FIELD_FORMAT | clipboardStatus/li2Domains sai định dạng, hoặc deepLink không phải URL hợp lệ |
| 400 | INVALID_CLICK_ID | li2_cid không đúng 16 ký tự base62 |
| 401 | MISSING_API_KEY | Thiếu / không xác thực được X-Li2-Key |
| 403 | FEATURE_NOT_ALLOWED | Org không có gói Pro |
| 403 | CROSS_ORG_ATTRIBUTION | (luồng immediate) domain không thuộc org của key |
| 404 | LINK_NOT_FOUND | Không tìm thấy slug (touch point) |
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.

