Khóa API và truy cập lập trình
Tạo biểu mẫu, nhân bản chúng và sinh liên kết tiếp nhận khách hàng từ backend của bạn bằng khóa API gắn với workspace.
Nếu bạn đã có CRM, hệ thống quản lý hồ sơ hoặc cổng nội bộ, bạn không cần nhấp qua bảng điều khiển để tạo từng biểu mẫu. Khóa API cho phép backend của bạn gọi trực tiếp API v1 của DS160.io — tạo biểu mẫu, nhân bản chúng và sinh liên kết tiếp nhận khách hàng theo lịch của bạn.
Khóa API chỉ khả dụng cho workspace dạng Business. Mỗi khóa được gắn với một workspace duy nhất và chỉ có thể hoạt động trong workspace đó.
URL gốc của API
Tất cả các endpoint v1 đều bắt nguồn từ:
https://ds160.io/api/v1
Tài liệu này có thể được host trên tên miền white-label của agency bạn, nhưng các cuộc gọi API luôn đi tới ds160.io. Mọi ví dụ mã trên trang này đều dùng URL đầy đủ để bạn có thể sao chép-dán mà không cần viết lại.
Tham chiếu endpoint
/v1 ổn định — đường dẫn và tên trường sẽ không thay đổi mà không có phiên bản chính /v2 (xem Phiên bản và hỗ trợ). Đường dẫn trong bảng dưới đây được hiển thị tương đối so với tiền tố workspace /workspaces/:workspaceId/; hình dạng đầy đủ của yêu cầu và phản hồi được ghi trong phần của mỗi endpoint.
| Phương thức | Đường dẫn | Scope | Thân yêu cầu |
|---|---|---|---|
POST | /forms | forms:write | name? |
POST | /forms/:formId/clone | forms:clone | disabledSections? |
POST | /forms/:formId/client-links | client-links:write | expiresInDays, defaultLanguage, hideBranding? |
GET | /forms | forms:read / forms:write | query: limit?, cursor? |
GET | /forms/:formId | forms:read / forms:write | — |
Tất cả thân yêu cầu và phản hồi đều là JSON. Scope forms:read cấp quyền chỉ đọc đối với siêu dữ liệu biểu mẫu; forms:write cấp cả đọc và ghi, vì vậy một khóa chỉ ghi vẫn có quyền đọc miễn phí.
1. Tạo khóa API
Mở Cài đặt không gian làm việc → Khóa API và nhấn Tạo khóa API. Chọn một tên mang tính mô tả (chúng tôi khuyến nghị một khóa cho mỗi tích hợp, ví dụ Production CRM hoặc Staging webhook handler), rồi chọn các scope mà tích hợp cần:
forms:read— chỉ đọc siêu dữ liệu biểu mẫu (liệt kê / lấy)forms:write— tạo biểu mẫu; cũng cấp quyền đọcforms:clone— sao chép biểu mẫu hiện cóclient-links:write— sinh liên kết tiếp nhận khách hàng
Chỉ Chủ sở hữu và Quản trị viên của workspace mới có thể tạo khóa.
Khi bạn nhấn Tạo khóa, nền tảng sẽ hiển thị bí mật đầy đủ một lần duy nhất. Hãy sao chép ngay vào trình quản lý bí mật của bạn — sau khi đóng modal, chỉ còn bốn ký tự cuối được hiển thị. Nếu mất khóa, hãy thu hồi và tạo lại khóa mới.
2. Xác thực
Mọi endpoint v1 đều yêu cầu header Authorization: Bearer <secret>.
export DS160_KEY="...the secret you just copied..."
export DS160_WORKSPACE="your-workspace-id"
curl https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms \
-H "Authorization: Bearer $DS160_KEY" ID workspace xuất hiện trong URL của mọi trang bảng điều khiển (/workspaces/<workspaceId>/...). Workspace của khóa được ràng buộc ở phía máy chủ — gọi endpoint thuộc workspace khác bằng khóa không khớp sẽ trả về 403 Forbidden.
Mẹo: các tab ngôn ngữ trong trang này được đồng bộ. Chọn ngôn ngữ một lần và phần còn lại của trang sẽ theo lựa chọn đó.
3. Tạo biểu mẫu
curl -X POST https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms \
-H "Authorization: Bearer $DS160_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Smith / B1 — 2026-05" }'
# → { "formId": "65f2…" } Mỗi lần gọi tiêu thụ một tín dụng biểu mẫu từ gói thanh toán của bạn (giống như tạo biểu mẫu từ bảng điều khiển). Nếu workspace hết tín dụng, lệnh gọi sẽ trả về 402 Payment Required — hãy nạp thêm trước khi thử lại.
Trường tùy chọn name đặt nhãn dễ đọc cho biểu mẫu (tối đa 200 ký tự). Bỏ qua nó để nhận tên được tạo tự động — dù sao bạn cũng có thể đổi tên biểu mẫu từ bảng điều khiển sau này.
4. Nhân bản biểu mẫu hiện có
Nếu bạn có một biểu mẫu mẫu thường xuyên tái sử dụng (chẳng hạn cùng chương trình J-1 của cùng một nhà tuyển dụng), hãy nhân bản thay vì bắt đầu lại từ đầu. Có thể tùy chọn truyền disabledSections để bỏ qua một số trang — bất kỳ mục nào liệt kê sẽ được thay bằng các trường trống trong biểu mẫu mới, để khách hàng điền lại từ đầu:
curl -X POST https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms/$SOURCE_FORM_ID/clone \
-H "Authorization: Bearer $DS160_KEY" \
-H "Content-Type: application/json" \
-d '{ "disabledSections": ["spouse-info-page", "security-background-page-5"] }'
# → { "formId": "65f3…" } Nhân bản tiêu thụ một tín dụng biểu mẫu giống như tạo mới.
Giá trị hợp lệ cho disabledSections
Truyền mảng rỗng (hoặc bỏ qua trường này) để sao chép mọi trang. Nếu không, hãy dùng tổ hợp bất kỳ của các định danh dưới đây — giá trị khác sẽ trả về 400 Bad Request.
| Định danh | Trang |
|---|---|
personal-info-page-1 | Personal Information - Part 1 |
personal-info-page-2 | Personal Information - Part 2 |
visa-purpose-page | Purpose of Visa |
travel-companions-page | Travel Companions |
previous-us-travel-page | Previous U.S. Travel History |
address-and-phone-page | Address and Phone Details |
passport-page | Passport Information |
contact-info-page | Contact Information |
family-info-page | Family Information |
spouse-info-page | Spouse Information |
deceased-spouse-info-page | Deceased Spouse Information |
former-spouse-info-page | Former Spouse Information |
present-occupation-page | Current Occupation |
previous-occuptation-page | Previous Occupation |
additional-occuptation-page | Additional Occupation Details |
security-background-page-1 | Security Background - Part 1 |
security-background-page-2 | Security Background - Part 2 |
security-background-page-3 | Security Background - Part 3 |
security-background-page-4 | Security Background - Part 4 |
security-background-page-5 | Security Background - Part 5 |
student-visa-page-1 | Student Visa Details - Part 1 |
student-visa-page-2 | Student Visa Details - Part 2 |
temporary-visa-page | Temporary Visa Information |
crew-visa-page | Crew Visa Information |
Chỉ những phần liên quan đến hạng visa của biểu mẫu mới thực sự có mặt; liệt kê một trang không tồn tại trong biểu mẫu nguồn sẽ không có tác dụng.
5. Sinh liên kết tiếp nhận khách hàng
Khi biểu mẫu đã tồn tại, hãy sinh một URL có token để khách hàng dùng điền vào:
curl -X POST https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms/$FORM_ID/client-links \
-H "Authorization: Bearer $DS160_KEY" \
-H "Content-Type: application/json" \
-d '{ "expiresInDays": 7, "defaultLanguage": "en" }' Thân yêu cầu
| Trường | Bắt buộc | Ghi chú |
|---|---|---|
expiresInDays | có | Số nguyên 1–365. Không có giá trị mặc định — bỏ qua sẽ trả về 400 Bad Request. expiresAt của liên kết được tính là now + expiresInDays và bản ghi token bên dưới được tự động xóa tại thời điểm đó. |
defaultLanguage | có | Một trong các mã ở Giá trị hợp lệ cho defaultLanguage. Đặt tiền tố locale trên url trả về và ngôn ngữ mà biểu mẫu mở lên. |
hideBranding | không | Boolean. Khi true, biểu mẫu hiển thị không có nhãn hiệu — logo và chủ đề whitelabel của agency bị ẩn cho liên kết này. Mặc định false (chrome whitelabel của workspace được hiển thị nếu đã cấu hình). |
Phản hồi ví dụ (200 OK)
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NmMxYmQ0ZjZmNGFkNTQwMzMxNDhmYmEiLCJmb3JtSWQiOiI2NWYyYTkxMTNkZjAxYzAwMTI3YjY4MmEiLCJ3b3Jrc3BhY2VJZCI6IjY1ZjJhOTAwM2RmMDFjMDAxMjdiNjgwYSIsImV4cCI6MTc0ODA0ODI0NywiaWF0IjoxNzQ3NDQzNDQ3LCJkZWZhdWx0TGFuZ3VhZ2UiOiJlbiIsImhpZGVCcmFuZGluZyI6ZmFsc2V9.SiGNATuRe",
"url": "https://intake.your-agency.com/client-intake/65f2a9113df01c00127b682a?token=eyJhbGciOi…",
"expiresAt": "2026-05-24T01:50:46.000Z"
}
| Trường | Ghi chú |
|---|---|
token | JWT cũng được nhúng trong url. Thông thường bạn không cần dùng trực tiếp — khách hàng mở url và máy chủ xác thực token nhúng. Claim jti của token là ID duy nhất của liên kết; hãy lưu nó vào hệ thống của bạn nếu có thể bạn muốn thu hồi đúng liên kết này sau đó (xem Thu hồi liên kết tiếp nhận khách hàng). |
url | Liên kết có thể chia sẻ. Sử dụng custom domain nếu đã xác minh và có SSL cho workspace; nếu không, sẽ quay về ds160.io. Tiền tố locale trong đường dẫn (/es, /cn, …) đặt theo defaultLanguage. |
expiresAt | Dấu thời gian ISO-8601. Bản ghi tương ứng sẽ tự động bị xóa tại thời điểm đó, nên các liên kết không thể tái sử dụng sau khi hết hạn. |
Gửi url cho khách hàng của bạn. Token trong URL chỉ dùng một mục đích và sẽ hết hạn tại expiresAt — không cần xác thực bổ sung để khách hàng điền vào.
Thu hồi liên kết tiếp nhận khách hàng
Không có endpoint v1 nào để thu hồi liên kết khách hàng đã phát hành — hãy thu hồi từ bảng điều khiển (Không gian làm việc → Biểu mẫu → Chia sẻ → Thu hồi liên kết). Thu hồi có hiệu lực ngay và không thể đảo ngược: yêu cầu kế tiếp trên liên kết trả về 401. Nếu nghi ngờ rò rỉ và không có ai sẵn sàng thu hồi từ UI, phương án an toàn nhất là để liên kết hết hạn (giới hạn expiresInDays tương ứng).
Giá trị hợp lệ cho defaultLanguage
defaultLanguage điều khiển ngôn ngữ của giao diện tiếp nhận khi người nhận lần đầu mở liên kết. Hãy dùng một trong các mã dưới đây — giá trị khác sẽ trả về 400 Bad Request. Các mã ngắn (en, cn, …) là định danh locale nội bộ của DS160.io; cột BCP-47 hiển thị giá trị chúng tôi phát ra trong <html lang>, hreflang và các API Intl.*. Hãy dùng mã ngắn trong các yêu cầu API; dạng BCP-47 là để tham khảo.
| Mã | Ngôn ngữ | Tên bản ngữ | BCP-47 |
|---|---|---|---|
en | English | English | en-US |
ru | Russian | Русский | ru-RU |
ro | Romanian | Română | ro-RO |
es | Spanish | Español | es-ES |
cn | Chinese | 中文 | zh-CN |
vi | Vietnamese | Tiếng Việt | vi-VN |
hi | Hindi | हिन्दी | hi-IN |
nl | Dutch | Nederlands | nl-NL |
Hãy đối xử với liên kết của khách như mật khẩu
url là một bearer credential — bất kỳ ai đang nắm giữ đều có thể điền biểu mẫu cho đến khi hết hạn, không cần yếu tố thứ hai.
- Gửi qua kênh tin cậy; không đăng tại nơi có thể bị rò rỉ (chat công khai, trang được lập chỉ mục, bộ sưu tập chia sẻ).
- Che
?token=trong log. Riêng claimjtithì an toàn để log. - Thu hồi khi nghi ngờ rò rỉ — thu hồi có hiệu lực ngay và không thể đảo ngược.
expiresInDayslà sự đánh đổi: ngắn = cửa sổ rò rỉ nhỏ hơn, dài = ít ma sát khi phải phát hành lại.
6. Liệt kê hoặc lấy biểu mẫu
# All forms in the workspace
curl https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms \
-H "Authorization: Bearer $DS160_KEY"
# A single form by id
curl https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms/$FORM_ID \
-H "Authorization: Bearer $DS160_KEY" Các endpoint đọc này chấp nhận scope forms:read (chỉ đọc) hoặc forms:write (cũng cấp quyền đọc).
Phân trang
GET /v1/workspaces/:workspaceId/forms được phân trang. Truyền các tham số truy vấn ?limit= và ?cursor= để duyệt qua kết quả:
| Tham số | Ý nghĩa |
|---|---|
limit | Số biểu mẫu tối đa trả về trên trang này. Mặc định 50, giới hạn cứng 200. |
cursor | id biểu mẫu từ nextCursor của trang trước. Bỏ trống ở yêu cầu đầu tiên để bắt đầu từ biểu mẫu mới nhất. |
Mỗi phản hồi đều có trường nextCursor. Khi không còn trang nào, nextCursor là null. Ví dụ:
{
"forms": [
{ "id": "65f2a911…", "name": "Smith / B1", "status": "in_progress", "workspaceId": "65f2a900…", "userId": "65f2a8f0…", "preferredConsulate": null, "createdAt": "2026-05-14T09:12:33.000Z", "archivedAt": null },
{ "id": "65f2a8a3…", "name": "Garcia / F1", "status": "completed", "workspaceId": "65f2a900…", "userId": "65f2a8f0…", "preferredConsulate": "MAD", "createdAt": "2026-05-13T18:01:09.000Z", "archivedAt": null }
],
"nextCursor": "65f2a8a3…"
}
Tiếp tục bằng cách gửi ?cursor=65f2a8a3…&limit=50 ở yêu cầu kế tiếp. Biểu mẫu được sắp xếp từ mới nhất đến cũ nhất theo id, vì vậy cursor giữ vị trí đọc của bạn cố định ngay cả khi có biểu mẫu mới được tạo giữa các lần gọi — bạn sẽ không thấy bản trùng và không bỏ lỡ điều gì đã tồn tại tại thời điểm bạn bắt đầu phân trang.
Các giá trị status của biểu mẫu
Trường status trên mỗi phản hồi siêu dữ liệu biểu mẫu là một trong:
| Giá trị | Khi nào áp dụng |
|---|---|
not_started | Biểu mẫu đã được tạo (qua API hoặc bảng điều khiển) nhưng chưa có trường nào được trả lời. |
in_progress | Đã có ít nhất một trường được trả lời. Hầu hết biểu mẫu trải qua phần lớn vòng đời ở trạng thái này. |
completed | Người nộp đơn đã hoàn tất và gửi đi; agency giờ có thể tải xuống/nộp PDF DS-160. |
archived | Biểu mẫu đã được lưu trữ từ bảng điều khiển. Bị loại khỏi kết quả liệt kê mặc định trừ khi bạn truy vấn rõ ràng các mục đã lưu trữ. |
Định dạng đi qua dây dùng dấu gạch dưới (in_progress, không phải in-progress). So sánh trực tiếp với các chuỗi ở trên luôn hoạt động.
Truy cập PII qua API
Các endpoint siêu dữ liệu biểu mẫu v1 (GET /workspaces/:workspaceId/forms và GET /workspaces/:workspaceId/forms/:formId) chỉ trả về siêu dữ liệu vận hành: id, name, status, workspaceId, userId, preferredConsulate, createdAt, archivedAt. Chúng không để lộ câu trả lời của người nộp đơn — không có tên, ngày sinh, số hộ chiếu, lịch sử đi lại hay bất kỳ trường DS-160 nào có thể truy cập qua /v1.
PDF DS-160 đã hoàn tất và dữ liệu trường đầy đủ chỉ có thể truy cập qua bảng điều khiển, dưới chủ sở hữu được ghi log kiểm toán của người nộp đơn. Nếu tích hợp của bạn cần đọc dữ liệu do người nộp đơn nhập, hãy thực hiện qua luồng tiếp nhận khách hàng của riêng bạn (CRM của bạn thu thập dữ liệu trước, rồi đẩy vào DS160.io) — đừng bao giờ giả định API sẽ trả lại dữ liệu đó.
Giới hạn tần suất
Mỗi khóa được giới hạn 60 yêu cầu mỗi phút. Mỗi phản hồi đều có:
| Header | Ý nghĩa |
|---|---|
X-RateLimit-Limit | Mức trần (60). |
X-RateLimit-Remaining | Số yêu cầu còn lại trong cửa sổ hiện tại. |
X-RateLimit-Reset | Dấu thời gian Unix khi cửa sổ đặt lại. |
Nếu vượt giới hạn, API trả về 429 Too Many Requests cùng header Retry-After. Nếu tích hợp của bạn thật sự cần trần cao hơn, hãy liên hệ bộ phận hỗ trợ — chúng tôi có thể nâng giới hạn cho các khóa cụ thể.
Tính idempotent và lần thử lại
API v1 không hỗ trợ header Idempotency-Key. Cụ thể:
POST /formsvàPOST /forms/:formId/clonekhông idempotent và tiêu một tín dụng biểu mẫu mỗi lần gọi. Một lần thử lại ngây thơ sau timeout mạng sẽ tạo biểu mẫu trùng và đốt thêm một tín dụng.POST /forms/:formId/client-linkscũng không idempotent nhưng không tiêu tín dụng — lần gọi lại đơn giản tạo một liên kết thứ hai vớijtivàexpiresAtriêng.- Mọi endpoint
GETđều an toàn để thử lại tự do.
Mẫu thử lại được khuyến nghị cho create/clone: nếu POST /forms (hoặc /clone) timeout hay trả về 5xx, đừng thử lại một cách mù quáng. Thay vào đó, gọi GET /workspaces/:workspaceId/forms (biểu mẫu được sắp xếp mới nhất trước) và kiểm tra xem có biểu mẫu nào với name bạn cung cấp được tạo trong vài giây qua không. Nếu có, coi lần gọi gốc là thành công và bỏ qua lần thử lại. Nếu không, ghi gốc chắc chắn không thành công và thử lại là an toàn.
Chúng tôi có thể bổ sung hỗ trợ Idempotency-Key trong một bản phát hành nhỏ trong tương lai; tích hợp nên lên kế hoạch nhưng không phụ thuộc vào điều đó hôm nay.
Thu hồi khóa
Nếu khóa bị rò rỉ, hết vòng đời hoặc đơn giản là không còn dùng, hãy thu hồi qua Cài đặt không gian làm việc → Khóa API → Thu hồi. Việc thu hồi có hiệu lực ngay — yêu cầu kế tiếp dùng khóa đó sẽ trả về 401 Unauthorized. Khóa đã thu hồi vẫn nằm trong danh sách để phục vụ kiểm toán nhưng không thể kích hoạt lại; hãy tạo khóa mới nếu cần duy trì tích hợp.
Thực hành tốt nhất
- Một khóa cho mỗi tích hợp. Dễ thu hồi chính xác khi một hệ thống ngừng sử dụng, và cột
Last usedtrong bảng điều khiển cho bạn biết tích hợp nào còn đang hoạt động. - Scope tối thiểu. Một khóa chỉ sinh liên kết khách hàng không cần
forms:clone. Scope nhỏ hơn nghĩa là phạm vi rủi ro nhỏ hơn khi bí mật bị lộ. - Lưu bí mật trong vault. Không bao giờ commit vào quản lý mã nguồn hoặc nhúng vào bundle frontend — mọi tab trình duyệt sẽ làm lộ nó.
- Luân chuyển theo lịch. Tạo khóa mới, chuyển tích hợp, rồi thu hồi khóa cũ. Bảng điều khiển hiển thị thời điểm sử dụng lần cuối của mỗi khóa để bạn xác nhận đã chuyển xong trước khi thu hồi.
Lỗi
Mọi phản hồi không phải 2xx đều có chung dạng JSON:
{ "error": "thông điệp dễ đọc" }
Giá trị error là một chuỗi. Đối với 400 Bad Request từ xác thực schema, đó là một mảng JSON đã được tuần tự hóa mô tả từng ràng buộc bị vi phạm; với phần còn lại, đó là một thông điệp ngắn mà bạn có thể hiển thị hoặc ghi log trực tiếp.
| Trạng thái | Khi nào xảy ra | Ví dụ thân |
|---|---|---|
400 | Thân yêu cầu hoặc tham số đường dẫn không qua xác thực (trường bắt buộc bị thiếu, giá trị ngoài khoảng, giá trị enum chưa biết, v.v.). | { "error": "[{\"keyword\":\"required\",\"params\":{\"missingProperty\":\"expiresInDays\"}}]" } |
401 | Thiếu header Authorization, token Bearer sai định dạng, bí mật không khớp khóa nào, hoặc khóa đã bị thu hồi. | { "error": "Missing API key" } · { "error": "Invalid API key" } · { "error": "API key revoked" } |
402 | Workspace đã hết tín dụng biểu mẫu. Chỉ create/clone. Hãy nạp thêm vào workspace và thử lại. | { "error": "Workspace has no remaining credits" } |
403 | Khóa thiếu scope cần thiết, hoặc :workspaceId trên đường dẫn không khớp workspace bị gắn của khóa. | { "error": "Missing required scope: forms:write" } · { "error": "API key does not match workspace" } |
404 | Không tìm thấy biểu mẫu, hoặc biểu mẫu tồn tại nhưng nằm trong workspace khác với khóa. (Trả về dưới dạng 404 thay vì 403 để không rò rỉ sự tồn tại giữa các workspace.) | { "error": "Form not found" } |
429 | Vượt giới hạn tần suất theo khóa (mặc định 60 req/min). Đợi đến giá trị Retry-After (giây) rồi thử lại. | { "error": "Rate limit exceeded" } |
5xx | Lỗi máy chủ tạm thời. GET an toàn để thử lại tự do; với endpoint ghi, hãy xem Tính idempotent và lần thử lại trước khi thử lại. | — |
Ví dụ đầu-đến-cuối
Một luồng tiếp nhận hoàn chỉnh — tạo biểu mẫu, phát hành liên kết khách hàng, gửi đi và poll trạng thái hoàn tất — bằng curl. Các tích hợp thực tế sẽ dùng client HTTP riêng; hình dạng giống nhau ở mọi ngôn ngữ.
# 0. thông tin xác thực (đặt một lần)
export DS160_KEY="..."
export DS160_WORKSPACE="65f2a900..."
# 1. Tạo biểu mẫu. Lấy formId từ phản hồi.
FORM_ID=$(curl -s -X POST \
https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms \
-H "Authorization: Bearer $DS160_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Smith / B1 — 2026-05" }' \
| jq -r .formId)
# 2. Phát hành liên kết khách hàng có hiệu lực 14 ngày.
LINK_JSON=$(curl -s -X POST \
https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms/$FORM_ID/client-links \
-H "Authorization: Bearer $DS160_KEY" \
-H "Content-Type: application/json" \
-d '{ "expiresInDays": 14, "defaultLanguage": "en" }')
CLIENT_URL=$(echo "$LINK_JSON" | jq -r .url)
# 3. Gửi $CLIENT_URL cho người nộp đơn qua kênh thông thường của bạn
# (email, cổng bảo mật, v.v.). Người nộp đơn điền biểu mẫu.
# 4. Poll trạng thái hoàn tất. Chuyển trạng thái:
# not_started → in_progress → completed
curl -s https://ds160.io/api/v1/workspaces/$DS160_WORKSPACE/forms/$FORM_ID \
-H "Authorization: Bearer $DS160_KEY" \
| jq .status
# → "completed" khi người nộp đơn đã xong
# 5. Tải PDF DS-160 từ bảng điều khiển
# (chưa có endpoint v1 cho việc này hôm nay).
Vài ghi chú về công thức này:
- Nhịp poll: mỗi 5–15 phút là đủ. Với trần 60 req/min, một khóa duy nhất có thể thoải mái poll hàng nghìn biểu mẫu đang xử lý.
- Webhook chưa khả dụng. Nếu bạn cần thông báo đẩy khi hoàn tất, hãy theo dõi trang này hoặc liên hệ hỗ trợ — đang nằm trong lộ trình.
- Bước 5 (tải PDF đã hoàn tất) hôm nay yêu cầu một phiên bảng điều khiển. API v1 cố tình không để lộ câu trả lời của người nộp đơn — xem Truy cập PII qua API.
Phiên bản và hỗ trợ
Tính ổn định. /v1 là bề mặt API ổn định. Chúng tôi bổ sung các trường tùy chọn mới, endpoint mới và giá trị enum mới trong /v1 mà không tăng phiên bản chính, nhưng chúng tôi không đổi tên, gỡ bỏ hoặc thay đổi kiểu của trường hiện có. Nếu cần thay đổi phá vỡ, nó sẽ phát hành dưới /v2 và /v1 tiếp tục hoạt động ít nhất 12 tháng song song.
Bổ sung tương thích ngược cần lên kế hoạch:
- Theo thời gian sẽ xuất hiện các trường yêu cầu tùy chọn mới. Yêu cầu hiện có không gửi chúng vẫn sẽ tiếp tục hoạt động.
- Có thể thêm các trường mới vào phản hồi. Hãy coi các trường chưa biết là có thể bỏ qua — đừng thất bại khi xuất hiện trường tương lai.
- Sẽ thêm các giá trị enum mới cho
status,defaultLanguagevàdisabledSections. Đừng crash trên giá trị chưa biết; hãy log và bỏ qua.
Hỗ trợ:
- Giới hạn cao hơn, custom domain, truy cập sớm webhook và câu hỏi tích hợp: hãy liên hệ account manager của bạn hoặc support@ds160.io.
- Báo lỗi đối với API v1: cùng địa chỉ. Mỗi phản hồi đều mang header
x-request-id— hãy đính kèm trong báo cáo để chúng tôi tìm chính xác lệnh gọi trong log.