Orchestrator — gom nhiều đơn hàng trong một lệnh gọi
Gửi tối đa 100 địa chỉ trong một yêu cầu duy nhất và để Netts thực hiện toàn bộ quy trình cho từng địa chỉ: kích hoạt địa chỉ nếu cần, nạp thêm Bandwidth nếu đang thiếu, sau đó thuê Energy — tự động chia nhỏ các lượng lớn thành từng phần.
Bạn nhận được phản hồi ngay lập tức 202 Accepted cùng với khóa theo dõi và không bao giờ phải chờ kết nối. Tiến trình sau đó sẽ được đọc từ endpoint trạng thái.
Tại sao nên sử dụng
Đặt Energy cho một địa chỉ mới thường mất ba lệnh gọi riêng biệt, theo đúng thứ tự, kèm logic thử lại của riêng bạn giữa các lệnh. Orchestrator thu gọn quy trình đó thành một yêu cầu và thực hiện trình tự cho từng địa chỉ:
probe → activation (if the address is not active) → bandwidth (if free < 400) → energyLỗi trong quá trình kích hoạt hoặc nạp Bandwidth không làm dừng đơn đặt Energy cho địa chỉ đó, và việc một địa chỉ bị lỗi không bao giờ ảnh hưởng đến các địa chỉ khác.
URL cơ sở của endpoint
https://netts.io/apiv2/orchestratorTiêu đề yêu cầu
| Tiêu đề | Bắt buộc | Mô tả |
|---|---|---|
| Content-Type | Có | application/json |
| X-API-KEY | Có | Khóa API của bạn từ bảng điều khiển Netts |
| X-Real-IP | Có | Địa chỉ IP từ danh sách trắng của bạn |
| X-Idempotency-Key | Có* | Khóa của bạn cho đơn hàng này, 12–128 ký tự gồm A-Z a-z 0-9 . _ : - |
* Bắt buộc phải có tiêu đề X-Idempotency-Key hoặc trường clientRequestId trong phần thân. Nếu bạn không gửi cả hai, yêu cầu sẽ bị từ chối với mã 5010.
Khóa này định danh cho toàn bộ đơn hàng. Việc lặp lại một yêu cầu với cùng một khóa sẽ trả về kết quả ban đầu thay vì tạo đơn hàng thứ hai — xem Tính lũy đẳng.
Tạo đơn hàng — POST /apiv2/orchestrator
Thân yêu cầu
{
"clientRequestId": "my-batch-2026-01-01-001",
"defaults": {
"bandwidth": true,
"bandwidthAmount": 400,
"bandwidthPeriod": "1h",
"check": true,
"trx_send": false
},
"items": [
{ "receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", "amount": 65000 },
{ "receiveAddress": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "amount": 131000 },
{ "receiveAddress": "TYYyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", "amount": 61000, "bandwidth": false }
]
}Các trường cấp cao nhất
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
items | array | Có | 1 đến 100 địa chỉ. Các địa chỉ trùng lặp trong cùng một đơn hàng sẽ bị từ chối. |
clientRequestId | string | Không | Mã tham chiếu đơn hàng của bạn, 8–128 ký tự gồm A-Z a-z 0-9 . _ : -. Đóng vai trò là khóa lũy đẳng nếu thiếu tiêu đề. |
defaults | object | Không | Các giá trị được áp dụng cho mọi mục không ghi đè chúng. |
Các trường của mục
Mọi trường ngoại trừ receiveAddress và amount đều có thể được thiết lập trong defaults. Giá trị trên mục sẽ được ưu tiên hơn giá trị mặc định.
| Trường | Loại | Mặc định | Mô tả |
|---|---|---|---|
receiveAddress | string | — | Địa chỉ TRON nhận Energy |
amount | int | — | Lượng Energy cho địa chỉ này, 61 000 … 50 000 000 |
bandwidth | bool | true | Đặt mua Bandwidth cho địa chỉ này khi đang thiếu |
bandwidthAmount | int | 400 | 400 hoặc 5000 |
bandwidthPeriod | string | 1h | 5m hoặc 1h |
check | bool | xem bên dưới | Kiểm tra Bandwidth khả dụng trước và bỏ qua việc đặt hàng nếu đã có đủ |
trx_send | bool | false | Được chuyển tiếp đến dịch vụ Bandwidth |
activation | bool | true | Kích hoạt địa chỉ nếu địa chỉ chưa hoạt động. Đặt false để bỏ qua bước này đối với địa chỉ mà bạn biết chắc chắn đã hoạt động. |
check mặc định là true khi bandwidthAmount là 400, và là false trong các trường hợp khác — việc đặt mua 5 000 đơn vị thường ngụ ý rằng bạn muốn nhận chúng bất kể lượng hiện có là bao nhiêu.
Số lượng tính trên từng địa chỉ. Một yêu cầu có thể kết hợp các số lượng khác nhau tùy ý; giới hạn duy nhất là tổng số lượng.
Giới hạn
| Giới hạn | Giá trị |
|---|---|
| Địa chỉ mỗi đơn hàng | 100 |
| Energy mỗi địa chỉ | 61 000 … 50 000 000 |
| Tổng Energy mỗi đơn hàng | 50 000 000 |
| Số đơn hàng đang xử lý trên mỗi tài khoản | 3 |
| Số địa chỉ đang xử lý trên mỗi tài khoản | 300 |
| Số dư tối thiểu để được chấp nhận | 4 TRX |
Mức trần 50 000 000 áp dụng cho tổng trên tất cả các địa chỉ trong yêu cầu, không phải cho từng địa chỉ riêng lẻ.
Phản hồi — đã chấp nhận (202, mã 10202)
{
"detail": {
"code": 10202,
"status": "accepted",
"msg": "Order accepted for processing",
"data": {
"idempotencyKey": "my-batch-2026-01-01-001",
"requestId": 1234,
"itemsAccepted": 3,
"statusUrl": "/apiv2/orchestrator/status/my-batch-2026-01-01-001",
"items": [
{
"deliveryKey": 5001,
"trackingId": "my-batch-2026-01-01-001:TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"amount": 65000,
"energyChunks": 1,
"activation": "planned",
"bandwidth": "planned",
"status": "queued"
}
]
}
}
}202 có nghĩa là đã đưa vào hàng đợi, chưa thực thi. Chưa có khoản phí nào bị trừ. Hãy thực hiện thăm dò statusUrl để nhận kết quả.
trackingId là cặp giá trị khóa lũy đẳng + địa chỉ — định danh của một địa chỉ bên trong đơn hàng của bạn. Hãy sử dụng nó trong nhật ký và đối soát của riêng bạn.
Ví dụ
curl -X POST https://netts.io/apiv2/orchestrator \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip" \
-H "X-Idempotency-Key: my-batch-2026-01-01-001" \
-d '{
"items": [
{"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", "amount": 65000}
]
}'Kiểm tra tiến trình — GET /apiv2/orchestrator/status/{idempotencyKey}
Thêm ?address=T… để nhận thông tin một địa chỉ duy nhất thay vì toàn bộ đơn hàng.
{
"detail": {
"code": 10000,
"status": "processing",
"data": {
"idempotencyKey": "my-batch-2026-01-01-001",
"requestId": 1234,
"clientRequestId": "my-batch-2026-01-01-001",
"summary": {
"total": 3, "queued": 1, "processing": 1, "completed": 1,
"partial": 0, "failed": 0, "insufficient_balance": 0,
"credentials_revoked": 0, "cancelled": 0
},
"items": [
{
"deliveryKey": 5001,
"trackingId": "my-batch-2026-01-01-001:TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"receiveAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"status": "completed",
"energy": {
"requested": 65000,
"delegated": 65000,
"status": "done",
"chunks": { "total": 1, "done": 1 },
"orderIds": ["1Hxxxxxxxxxx"],
"hashes": ["0000000000000000000000000000000000000000000000000000000000000000"]
},
"activation": { "status": "not_needed", "orderId": null, "hash": null },
"bandwidth": {
"status": "enough", "orderId": "B1Hxxxxxxxxxxxxxx",
"amount": 400, "period": "1h", "hashes": [], "skipReason": null
},
"attempts": 1,
"startedAt": "2026-01-01T00:00:00+00:00",
"finishedAt": "2026-01-01T00:00:03+00:00"
}
]
}
}
}Một khóa không xác định, hoặc khóa thuộc về một tài khoản khác, sẽ trả về 404.
Các giá trị trạng thái địa chỉ
| Trạng thái | Ý nghĩa |
|---|---|
queued | Đang chờ được xử lý |
processing | Đang xử lý |
completed | Toàn bộ Energy yêu cầu đã được ủy quyền |
partial | Đã phân phối một số phần, một số phần thất bại |
failed | Không có phần nào được phân phối |
insufficient_balance | Bị dừng — số dư của bạn đã giảm xuống dưới mức tối thiểu |
credentials_revoked | Khóa API của bạn đã bị xóa hoặc vô hiệu hóa trong khi đơn hàng đang chạy |
cancelled | Đã bị xóa khỏi hàng đợi theo yêu cầu hủy của bạn |
Các giá trị trạng thái bước
| Bước | Giá trị |
|---|---|
activation | not_needed, done, failed, skipped, skipped_unavailable |
bandwidth | enough, done, failed, skipped |
energy | done, partial, failed |
bandwidth.skipReason giải thích lý do skipped: option_off (bạn đã tắt tùy chọn), energy_gt_600000 (các đơn đặt Energy lớn không cần nạp thêm Bandwidth).
Mã hash ủy quyền
energy.hashes là bằng chứng phân phối của bạn. Khi Energy đến từ một nhà cung cấp bên ngoài, mã hash sẽ không thể biết được tại thời điểm đặt hàng — nó sẽ được điền vào khoảng một phút sau đó, và địa chỉ không được báo cáo là hoàn thành cho đến khi các mã hash được thu thập hoặc cửa sổ thời gian chờ hết hạn. Một địa chỉ ở trạng thái completed với mã hash hiện diện đã được thanh toán hoàn tất.
Hủy — POST /apiv2/orchestrator/cancel/{idempotencyKey}
Xóa khỏi hàng đợi mọi địa chỉ chưa được tiếp nhận xử lý.
{
"detail": {
"code": 10005,
"status": "cancelled",
"msg": "Order cancelled: 7 addresses removed from queue",
"data": { "cancelled": 7 }
}
}Các địa chỉ đã ở trạng thái processing không bị gián đoạn: một phần Energy của chúng có thể đã được thanh toán. Việc hủy chỉ được nỗ lực thực hiện tối đa trên phần còn lại.
Tính lũy đẳng
Đơn hàng được xác định bằng khóa của bạn — tiêu đề X-Idempotency-Key, hoặc clientRequestId khi thiếu tiêu đề.
| Yêu cầu lặp lại | Kết quả |
|---|---|
| Cùng khóa, cùng phần thân | 208 với đơn hàng ban đầu và originalAcceptedAt — không tạo đơn hàng thứ hai |
| Cùng khóa, khác phần thân | 409 4090 IDEMPOTENCY_CONFLICT |
Do đó, sự cố quá thời gian chờ mạng ở phía bạn có thể được thử lại an toàn với nội dung y nguyên. Việc thay đổi dữ liệu yêu cầu dưới một khóa đã được sử dụng sẽ bị từ chối thay vì áp dụng trong âm thầm.
Bên trong đơn hàng, mỗi địa chỉ mang một khóa nội bộ riêng, do đó một yêu cầu lặp lại cũng không bao giờ trừ phí hai lần đối với một địa chỉ duy nhất.
Thanh toán
Bản thân Orchestrator không tính phí. Mỗi bước được tính phí bởi dịch vụ thực hiện nó, theo mức giá thông thường:
| Bước | Được tính phí dưới dạng |
|---|---|
| Activation | khoản khấu trừ riêng, mã đơn hàng A… |
| Bandwidth | khoản khấu trừ riêng, mã đơn hàng B1H… — chỉ khi thực sự được ủy quyền |
| Energy | một khoản khấu trừ cho mỗi phần, mã đơn hàng 1H… |
check: true với đủ Bandwidth khả dụng sẽ không tốn phí — trạng thái là enough và không có đơn hàng nào được đặt. Các lượng Energy lớn sẽ bỏ qua Bandwidth hoàn toàn.
Nếu tài khoản của bạn hết số dư giữa chừng trong đợt xử lý, các địa chỉ còn lại sẽ kết thúc với trạng thái insufficient_balance mà không được thử thực hiện.
Tham chiếu mã lỗi
| Mã | Mô tả | Trạng thái HTTP |
|---|---|---|
10202 | Đơn hàng đã được chấp nhận / đã được chấp nhận trước đó | 202 / 208 |
10000 | Trạng thái đã được trả về | 200 |
10005 | Đơn hàng đã bị hủy | 200 |
5004 | Trường không hợp lệ: định dạng địa chỉ, amount nằm ngoài phạm vi, bandwidthAmount không phải 400/5000, bandwidthPeriod không phải 5m/1h, phần thân không phải là một đối tượng JSON | 400 |
5005 | items bị thiếu hoặc trống | 400 |
5006 | Trùng lặp receiveAddress trong một đơn hàng | 400 |
5009 | X-Idempotency-Key hoặc clientRequestId sai định dạng | 400 |
5010 | Cả X-Idempotency-Key và clientRequestId đều không được cung cấp | 400 |
5012 | Tổng Energy trong yêu cầu vượt quá 50 000 000 | 400 |
-1 | Khóa API không hợp lệ / IP không có trong danh sách trắng | 401 |
1004 | Số dư dưới mức tối thiểu 4 TRX | 402 |
-1 | Không tìm thấy đơn hàng (hoặc không phải của bạn) | 404 |
4090 | IDEMPOTENCY_CONFLICT — cùng khóa, khác phần thân | 409 |
4220 | Xác thực yêu cầu thất bại (chi tiết trong data.errors) | 422 |
429 / 5011 | Quá nhiều đơn hàng, địa chỉ hoặc phần đang được xử lý | 429 |
5003 | Đơn hàng không được chấp nhận — dịch vụ tạm thời không khả dụng, có thể thử lại an toàn | 503 |
Lỗi 503 khi tạo là an toàn trước sự cố: không có gì được lưu trữ và không có gì bị trừ phí.
Giới hạn tần suất
Bị giới hạn trên mỗi IP nguồn:
| Chu kỳ | Giới hạn |
|---|---|
| 1 giây | 20 yêu cầu |
Vượt quá giới hạn tần suất (429)
{ "message": "API rate limit exceeded" }Lưu ý
- 202 không phải là biên nhận phân phối. Hãy coi nó là "đã vào hàng đợi". Kết quả nằm trong endpoint trạng thái.
- Các địa chỉ chạy song song, tối đa 5 địa chỉ cùng lúc trong một đơn hàng, do đó một đợt xử lý lớn không phải chờ đợi một địa chỉ xử lý chậm duy nhất. Thứ tự hoàn thành không được đảm bảo.
- Tự động chia nhỏ: các lượng vượt quá 1 000 000 được chia thành các phần đều nhau, mỗi phần trở thành một đơn đặt Energy riêng.
energy.orderIdsvàenergy.hashessẽ liệt kê tất cả chúng. - Không có webhook cho toàn bộ đơn hàng orchestrator. Mỗi lần ủy quyền Energy vẫn tạo ra webhook
delegation.confirmednhư thường lệ, xem Webhooks. - Các endpoint liên quan: Activator, Bandwidth, Order 1H.