Webhooks — การแจ้งเตือนคำสั่งซื้อ
ลงทะเบียน HTTPS endpoint เพื่อรับ webhook ที่มีการลงนาม (signed webhook) ทันทีที่คำสั่งซื้อของคุณรายการใดรายการหนึ่ง เสร็จสมบูรณ์และได้รับการตรวจสอบบนบล็อกเชน (on-chain) แทนที่จะต้องคอยส่งคำขอตรวจสอบเป็นระยะ (polling) คุณสามารถดำเนินการตามขั้นตอนของคุณต่อไปได้ทันที (เช่น ปล่อย USDT) ทันทีที่การแจ้งเตือนมาถึง
เหตุการณ์ที่จัดส่งมี 3 ประเภท:
| เหตุการณ์ | ส่งเมื่อ |
|---|---|
delegation.confirmed | การเช่า Energy (1h / 5m) ได้รับการยืนยันบนบล็อกเชนแล้ว |
bandwidth.delegated | คำสั่งซื้อ Bandwidth ดำเนินการเสร็จสมบูรณ์แล้ว |
activation.confirmed | การเปิดใช้งานที่อยู่ (address activation) ดำเนินการบนบล็อกเชนแล้ว |
หน้านี้ครอบคลุมถึง API สำหรับการจัดการ (สร้าง / เรียกดูรายการ / แก้ไข / ผลัดเปลี่ยน Secret / ลบ endpoint ของคุณ) และรูปแบบของ webhook ที่เราจัดส่งให้คุณ
ℹ️ บทบาทหน้าที่ คุณจัดการ endpoint ของคุณที่นี่ การจัดส่งจะดำเนินการโดย Netts ในรูปแบบอะซิงโครนัสหลังจาก คำสั่งซื้อได้รับการตรวจสอบแล้ว — ไม่จำเป็นต้องคอย polling แต่ละเหตุการณ์จะถูกส่งเฉพาะกรณีที่สำเร็จเท่านั้น โดยจะไม่มีการจัดส่ง เหตุการณ์ที่ล้มเหลวหรือหมดเวลาเด็ดขาด
🔒 ทุกแฮชที่เราส่งจะได้รับการตรวจสอบบนบล็อกเชนก่อนเสมอ Webhook จะถูกส่งออกไปหลังจากที่แฮชของธุรกรรมแต่ละรายการในข้อความนั้น ถูกพบในบล็อกแล้วเท่านั้น หากแฮชยังไม่อยู่ในบล็อก การจัดส่งจะถูกระงับไว้และ ตรวจสอบซ้ำทุก 30 วินาทีเป็นเวลาสูงสุด 5 นาที หากไม่ปรากฏบนบล็อกเชนในที่สุด จะไม่มีการส่งข้อมูลใดๆ สำหรับ คำสั่งซื้อนั้น คุณจะไม่มีทางได้รับแฮชที่ไม่มีอยู่จริงบนบล็อกเชน
URL พื้นฐานของ Endpoint
https://netts.io/apiv2/webhooksส่วนหัวของคำขอ (Request Headers)
| ส่วนหัว | จำเป็น | คำอธิบาย |
|---|---|---|
| Content-Type | ใช่ (สำหรับ POST/PATCH) | application/json |
| X-API-KEY | ใช่ | คีย์ API ของคุณจากแดชบอร์ด Netts |
| X-Real-IP | ใช่ | ที่อยู่ IP จากไวท์ลิสต์ของคุณ |
user_id ของคุณจะถูกดึงมาจากคีย์ API โดยตรง — คุณไม่ต้องส่งค่านี้ไป คุณสามารถดูและแก้ไขได้เฉพาะ endpoint ของคุณ เองเท่านั้น
Endpoint หลักและสำรอง
คุณสามารถลงทะเบียนได้ไม่เกินสอง endpoint และแต่ละรายการจะมี role:
| บทบาท (Role) | วัตถุประสงค์ |
|---|---|
primary | ที่อยู่ที่ webhook ทุกรายการจะถูกจัดส่งไปเป็นหลัก |
backup | ระบบสำรอง ใช้เฉพาะเมื่อการจัดส่งไปยัง primary ล้มเหลวหลังจากพยายามส่งซ้ำจนครบกำหนดแล้ว |
คำสั่งซื้อที่ได้รับการยืนยันหนึ่งรายการจะสร้าง webhook เพียงรายการเดียว ซึ่งไม่ใช่การกระจายส่งพร้อมกัน (fan-out): เหตุการณ์เดียวกัน จะไม่ถูกส่งไปยังทั้งสองที่อยู่พร้อมกัน Endpoint แบบ backup มีไว้เพื่อความยืดหยุ่นในการทำงาน — หากโฮสต์หลักของคุณ ไม่สามารถติดต่อได้หรือส่งคืนสถานะที่ไม่ใช่ 2xx อย่างต่อเนื่อง การจัดส่งจะเปลี่ยนไปยังโฮสต์สำรองแทนที่จะถูก ยกเลิกไป
Endpoint แรกที่คุณสร้างจะกลายเป็น primary และรายการที่สองจะกลายเป็น backup คุณสามารถส่งค่า role อย่างชัดเจน หรือสลับตำแหน่งในภายหลังด้วย PATCH ก็ได้
ทำไมจึงไม่แยก URL ตามประเภทการดำเนินการ? เพราะประเภทของเหตุการณ์จะถูกส่งมาภายในเนื้อหาของข้อมูล (body) ในฟิลด์
eventอยู่แล้ว ตัวประมวลผลเดียว การตรวจสอบลายเซ็นเดียว และรองรับประเภทเหตุการณ์ใหม่ๆ ได้ทันทีโดย ที่คุณไม่ต้องลงทะเบียนอะไรเพิ่มเติม
จัดการ endpoint
สร้าง — POST /apiv2/webhooks
ลงทะเบียน endpoint ใหม่และส่งคืน secret ซึ่งจะแสดงเพียงครั้งเดียวเท่านั้น (โปรดจัดเก็บไว้ให้ดี — ใช้สำหรับลงนาม webhook ทุกรายการที่คุณได้รับ)
// request body — role is optional
{
"url": "https://your-server.example/netts/delegation-hook",
"role": "primary"
}หากคุณไม่ระบุ role ระบบจะกำหนดบทบาทแรกที่ยังว่างอยู่ให้: primary แล้วตามด้วย backup
// response 201
{
"detail": {
"code": 10000,
"status": "created",
"data": {
"id": 1,
"url": "https://your-server.example/netts/delegation-hook",
"secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"role": "primary",
"is_active": true,
"created_at": "2026-01-01T00:00:00"
}
}
}ข้อกำหนดของ URL (มีการตรวจสอบความถูกต้องเมื่อสร้างและเมื่อแก้ไขทุกครั้ง):
- ต้องเป็น
https - ต้องแปลงค่าเป็นที่อยู่สาธารณะ (public address) ได้ — ปฏิเสธ loopback, private (RFC1918), link-local (รวมถึง
169.254.169.254) และช่วง IP อื่นๆ ที่ไม่สามารถกำหนดเส้นทางได้ - ห้ามมีข้อมูลยืนยันตัวตนใน URL (
user:pass@…) - ความยาวสูงสุด 2048 ตัวอักษร
URL ที่ไม่ผ่านเกณฑ์จะส่งคืนสถานะ 400
คุณสามารถมีได้ สอง endpoint — primary หนึ่งรายการ และ backup หนึ่งรายการ หากเพิ่มรายการที่สามจะส่งคืน 409 (4090) การร้องขอ role ที่ถูกใช้งานไปแล้วจะส่งคืน 409 (4091) — ให้สลับบทบาทด้วย PATCH หรือ ลบรายการเดิมออกก่อน
curl -X POST https://netts.io/apiv2/webhooks \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip" \
-d '{"url": "https://your-server.example/netts/delegation-hook", "role": "primary"}'เรียกดูรายการ — GET /apiv2/webhooks
ส่งคืนรายการ endpoint ของคุณ (ค่า secret จะไม่ถูกส่งคืนที่นี่เด็ดขาด)
{
"detail": {
"code": 10000,
"status": "ok",
"data": {
"endpoints": [
{
"id": 1,
"url": "https://your-server.example/netts/delegation-hook",
"role": "primary",
"is_active": true,
"created_at": "2026-01-01T00:00:00",
"updated_at": "2026-01-01T00:00:00"
},
{
"id": 2,
"url": "https://backup.example/netts/delegation-hook",
"role": "backup",
"is_active": true,
"created_at": "2026-01-01T00:00:00",
"updated_at": "2026-01-01T00:00:00"
}
],
"count": 2,
"max_endpoints": 2,
"roles": ["primary", "backup"]
}
}
}เรียกดูรายการเดียว — GET /apiv2/webhooks/{id}
มีรูปแบบข้อมูลเหมือนกับรายการใน List (ไม่มี secret) หากเป็น id ของผู้อื่นหรือไม่มีอยู่จริงจะส่งคืน 404
แก้ไข — PATCH /apiv2/webhooks/{id}
เปลี่ยน url, is_active และ/หรือ role สามารถส่งเพียงบางฟิลด์ได้ หากส่ง body ว่างเปล่าจะส่งคืน 422 กรณีที่ url มีการเปลี่ยนแปลงจะถูกตรวจสอบความถูกต้องใหม่ (https / SSRF) หากเป็น id ของผู้อื่นหรือไม่มีอยู่จริงจะส่งคืน 404
// request body (any subset)
{ "url": "https://your-server.example/netts/new-hook", "is_active": false }// response 200
{
"detail": {
"code": 10000,
"status": "updated",
"data": {
"id": 1,
"url": "https://your-server.example/netts/new-hook",
"role": "primary",
"is_active": false,
"created_at": "2026-01-01T00:00:00",
"updated_at": "2026-01-01T00:00:01"
}
}
}การเลื่อนขั้นระบบสำรอง การส่ง {"role": "primary"} ไปยัง endpoint สำรองของคุณจะเป็นการสลับทั้งสอง บทบาทในทรานแซกชันเดียว — โดย primary เดิมจะเปลี่ยนไปเป็น backup คุณจะไม่มีทางขาดที่อยู่หลัก และไม่จำเป็นต้องเรียกใช้ API แยกต่างหากสำหรับอีก endpoint หนึ่ง
curl -X PATCH https://netts.io/apiv2/webhooks/2 \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-H "X-Real-IP: your_whitelisted_ip" \
-d '{"role": "primary"}'กำหนด
is_active: falseเพื่อหยุดการจัดส่งชั่วคราวโดยไม่ต้องลบ endpoint และกำหนดtrueเพื่อดำเนินการต่อ การหยุดprimaryของคุณชั่วคราวจะไม่มีการเลื่อนขั้น endpoint สำรองขึ้นมาแทน — การจัดส่งจะยังคงพุ่งเป้าไปที่ primary อยู่ หากต้องการให้ สำรองทำงานแทน ให้ทำการสลับบทบาท
ผลัดเปลี่ยน Secret — POST /apiv2/webhooks/{id}/rotate-secret
สร้าง secret ใหม่และส่งคืนค่าเพียงครั้งเดียว Secret ใหม่จะมีผลทันทีสำหรับการ จัดส่งในครั้งถัดไป — โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม แต่ละ endpoint จะมี Secret เป็นของตัวเอง: การผลัดเปลี่ยน Secret ของ primary จะไม่ส่งผลกระทบต่อ Secret ของ backup
// response 200
{
"detail": {
"code": 10000,
"status": "rotated",
"data": {
"id": 1,
"secret": "whsec_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
}
}
}ลบ — DELETE /apiv2/webhooks/{id}
ลบ endpoint แบบถาวร (Hard-delete) และคืนบทบาทให้ว่างลง ส่งคืนสถานะ 204 (ไม่มี body) หากเป็น id ของผู้อื่นหรือไม่มีอยู่จริงจะส่งคืน 404
curl -X DELETE https://netts.io/apiv2/webhooks/1 \
-H "X-API-KEY: your_api_key" -H "X-Real-IP: your_whitelisted_ip"Webhook ที่เราจัดส่ง
เมื่อคำสั่งซื้อของคุณรายการใดรายการหนึ่งเสร็จสมบูรณ์ Netts จะส่งคำขอ POST ไปยัง endpoint แบบ primary ของคุณ Body ทุกรายการจะอยู่ในรูปแบบ application/json (UTF-8) โดยที่อยู่และแฮชจะเป็นค่าแบบเต็มเสมอ
ฟิลด์ทั่วไปที่มีในทุกเหตุการณ์:
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
event | string | ประเภทเหตุการณ์ — คีย์สำหรับกำหนดเส้นทาง (routing key) สำหรับตัวประมวลผลของคุณ |
delivery_id | int | รหัสการจัดส่ง — คีย์สำหรับตัดข้อมูลซ้ำ (dedup key) ในฝั่งของคุณ นอกจากนี้ยังถูกส่งไปในส่วนหัว X-Netts-Delivery ด้วย |
order_id | string | รหัสคำสั่งซื้อของคุณ |
order_type | string | 1h, 5m, bandwidth หรือ activation |
tx_hashes | string[] | แฮชธุรกรรมทั้งหมดของการดำเนินการ ซึ่งแต่ละรายการได้รับการตรวจสอบบนบล็อกเชนแล้ว |
confirmed_at | string | UTC ISO-8601 |
delegation.confirmed — การเช่า Energy
{
"event": "delegation.confirmed",
"delivery_id": 1,
"order_id": "1Hxxxxxxxxxx",
"order_type": "1h",
"receive_address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"energy_amount": 65000,
"tx_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"tx_hashes": ["0000000000000000000000000000000000000000000000000000000000000000"],
"delegation_timestamp": 1700000000000,
"confirmed_at": "2026-01-01T00:00:00Z"
}| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
order_type | string | 1h หรือ 5m |
receive_address | string | ที่อยู่ TRON ที่ได้รับ Energy |
energy_amount | int | ปริมาณ Energy ที่ได้รับการมอบสิทธิ์ (delegated) |
tx_hash | string | ฟิลด์แบบเดิม (Legacy) เก็บไว้เพื่อความเข้ากันได้: มีค่าเหมือนกับ tx_hashes[0] |
delegation_timestamp | int? | ทางเลือก (Optional) — จะมีค่าเฉพาะเมื่อยืนยันผ่านเส้นทาง Mongo เท่านั้น |
สำหรับการเชื่อมต่อระบบใหม่ แนะนำให้ใช้
tx_hashesเป็นหลัก — เนื่องจากในทางทฤษฎีแล้วคำสั่งซื้ออาจเสร็จสมบูรณ์ได้โดย มากกว่าหนึ่งธุรกรรม ส่วนtx_hashจะยังคงใช้งานได้ต่อไปตามปกติ
bandwidth.delegated — คำสั่งซื้อ Bandwidth
{
"event": "bandwidth.delegated",
"delivery_id": 2,
"order_id": "B1Hxxxxxxxxxxxxx",
"order_type": "bandwidth",
"rental_label": "1h",
"rental_seconds": 3600,
"receive_address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"bandwidth_amount": 400,
"fulfillment": "delegated",
"tx_hashes": ["0000000000000000000000000000000000000000000000000000000000000000"],
"confirmed_at": "2026-01-01T00:00:00Z"
}| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
rental_label / rental_seconds | string / int | ระยะเวลาการเช่า เช่น 1h / 3600 |
receive_address | string | ที่อยู่ TRON ที่ได้รับ Bandwidth |
bandwidth_amount | int | หน่วยของ Bandwidth (สุทธิ) |
fulfillment | string | วิธีการดำเนินการของคำสั่งซื้อ — ดูรายละเอียดด้านล่าง |
ค่าของ fulfillment:
| ค่า | ความหมาย | tx_hashes |
|---|---|---|
delegated | มอบสิทธิ์ Bandwidth จากพูลของเรา | 1 แฮชขึ้นไป |
trx_send | ดำเนินการโดยการส่ง TRX ไปยังที่อยู่ดังกล่าวแทนการมอบสิทธิ์ | 1 แฮชขึ้นไป |
already_enough | ที่อยู่ดังกล่าวมี Bandwidth ว่างเพียงพออยู่แล้ว — จึงไม่มีการส่งรายการใดบนบล็อกเชน | ว่างเปล่า |
already_enough เป็นกรณีเดียวที่ tx_hashes จะว่างเปล่า: คำสั่งซื้อปิดงานสำเร็จเรียบร้อย แต่ไม่มีธุรกรรมเกิดขึ้นเนื่องจากไม่จำเป็นต้องทำรายการ
activation.confirmed — การเปิดใช้งานที่อยู่
{
"event": "activation.confirmed",
"delivery_id": 3,
"order_id": "123456",
"order_type": "activation",
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"activation_type": "ACC_CREATE",
"source": "telegram_bot",
"tx_hashes": ["0000000000000000000000000000000000000000000000000000000000000000"],
"confirmed_at": "2026-01-01T00:00:00Z"
}| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
order_id | string | รหัสคำสั่งซื้อการเปิดใช้งาน (สตริงตัวเลข) |
address | string | ที่อยู่ TRON ที่ได้รับการเปิดใช้งาน |
activation_type | string | ACC_CREATE (AccountCreateContract) หรือ DIRECT (การโอน TRX) |
source | string | เครื่องหมายระบุต้นทาง ไม่ว่าจะเป็นแท็กบริการ หรือรหัสของคำสั่งซื้อ Energy ที่จำเป็นต้องมีการเปิดใช้งาน |
จัดส่งเฉพาะการเปิดใช้งานจริงเท่านั้น หากตรวจพบว่าที่อยู่นั้นเปิดใช้งานอยู่แล้วและไม่มีการ ทำธุรกรรมเกิดขึ้น จะไม่มีการส่ง webhook ใดๆ ทั้งสิ้น
คำสั่งซื้อ Energy ที่จำเป็นต้องมีการเปิดใช้งานที่อยู่ด้วย จะสร้าง webhook สอง รายการ — ได้แก่
activation.confirmedหนึ่งรายการ และdelegation.confirmedอีกหนึ่งรายการ ซึ่งเป็นคนละเหตุการณ์และแยกdelivery_idกัน โปรดกำหนดเส้นทางการประมวลผลด้วยฟิลด์event
ส่วนหัวที่เราส่ง:
| ส่วนหัว | ค่า |
|---|---|
X-Netts-Event | ประเภทเหตุการณ์: delegation.confirmed, bandwidth.delegated หรือ activation.confirmed |
X-Netts-Delivery | delivery_id (สำหรับตัดข้อมูลซ้ำ) |
X-Netts-Timestamp | เวลาแบบ unix seconds ณ ขณะที่ส่ง |
X-Netts-Signature | sha256=<hex>, hex = HMAC_SHA256(secret, "<timestamp>." + raw_body) |
User-Agent | netts-webhook/1.0 |
การตรวจสอบลายเซ็น
ลายเซ็นใช้รูปแบบเดียวกับ Stripe (timestamp.body) คำนวณจาก ไบต์ดิบ (raw bytes) ที่เราส่งไป ให้คำนวณค่าใหม่อีกครั้งด้วย secret ของคุณ เปรียบเทียบข้อมูลแบบเวลาคงที่ (constant-time) และปฏิเสธหาก X-Netts-Timestamp อยู่นอก ช่วงเวลา ±5 นาที (การป้องกันการโจมตีแบบ Replay)
ลงนามด้วย Secret ของ endpoint ที่ได้รับคำขอนั้น: primary และ backup จะมี Secret แยกกัน หากทั้งสองที่อยู่ของคุณประมวลผลด้วยตัวจัดการเดียวกัน ให้เลือก Secret ตาม URL ที่ คำขอนั้นส่งเข้ามา
import hmac, hashlib, time
def verify(raw_body: bytes, sig_header: str, ts_header: str, secret: str) -> bool:
# freshness (anti-replay)
if abs(time.time() - int(ts_header)) > 300:
return False
signed = f"{ts_header}.".encode() + raw_body
expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig_header)
# Flask example:
# ok = verify(request.get_data(),
# request.headers["X-Netts-Signature"],
# request.headers["X-Netts-Timestamp"], SECRET)รูปแบบการรับประกันการจัดส่ง (สำคัญ — at-least-once)
การจัดส่งเป็นแบบ at-least-once (อย่างน้อยหนึ่งครั้ง): การตอบกลับที่สูญหายอาจทำให้เกิดการส่งซ้ำ ดังนั้นคุณอาจได้รับ เหตุการณ์เดิมซ้ำสองครั้ง และเนื่องจากการดำเนินงานทางธุรกิจ (การปล่อย USDT) เกี่ยวข้องกับเรื่องเงิน:
- จำเป็นต้องตัดข้อมูลที่ซ้ำซ้อน — ประมวลผลแต่ละเหตุการณ์อย่างมีคุณสมบัติ idempotent โดยอิงตาม
delivery_id(และ/หรือorder_id) หากเป็นข้อมูลซ้ำต้องไม่ดำเนินการซ้ำ (no-op) - ตรวจสอบ HMAC ก่อนดำเนินการใดๆ ที่เกี่ยวกับเงิน — อย่าเชื่อถือ body จนกว่าลายเซ็นจะตรงกันและ
X-Netts-Timestampยังอยู่ในช่วงเวลาที่ถูกต้อง - ส่งคืนสถานะ 2xx หลังจากที่คุณจัดเก็บเหตุการณ์ไว้อย่างถาวรแล้วเท่านั้น — มิฉะนั้นระบบของเราจะพยายามส่งซ้ำ (ตามการทำงานที่ถูกต้อง)
ตอบกลับด้วยสถานะ 2xx เพื่อยืนยันการรับข้อมูล หากส่งสถานะที่ไม่ใช่ 2xx / เกิดการหมดเวลา จะกระตุ้นให้เกิดการพยายามส่งใหม่
ลำดับขั้นตอนการพยายามส่ง:
- การพยายามส่งใหม่จะส่งไปยัง endpoint แบบ
primaryของคุณ โดยกรอบเวลาจะขึ้นอยู่กับประเภทคำสั่งซื้อ: คำสั่งซื้อประเภท5mจะพยายามส่งใหม่เป็นเวลา ~1 นาที ส่วนประเภทอื่นๆ ทั้งหมดจะพยายามส่งใหม่เป็นเวลา ~10 นาที - หากหมดกรอบเวลาแล้วและคุณได้ลงทะเบียน
backupไว้ การจัดส่งจะย้ายไปที่นั่นและกำหนดการพยายามส่งใหม่จะเริ่มต้นใหม่อีกครั้ง — โดยจะลงนามด้วย Secret ของ backup เอง - ระบบจะทำเครื่องหมายว่าการจัดส่งล้มเหลวโดยสมบูรณ์ (dead) ต่อเมื่อการพยายามส่งไปยัง backup หมดรอบแล้วเท่านั้น
ระบบจะใช้ delivery_id เดียวกันตลอดกระบวนการ ดังนั้นข้อความที่ล้มเหลวใน primary ในตอนแรกแล้วมา สำเร็จที่ backup จะยังคงถือว่าเป็นเหตุการณ์เดียวกันสำหรับตรรกะการตัดข้อมูลซ้ำของคุณ
ข้อมูลอ้างอิงรหัสข้อผิดพลาด
| รหัส | คำอธิบาย | สถานะ HTTP |
|---|---|---|
10000 | สำเร็จ (created / ok / updated / rotated) | 200 / 201 |
- | ลบสำเร็จ (ไม่มี body) | 204 |
4000 | URL ของ webhook ไม่ถูกต้อง / ไม่ปลอดภัย (ไม่ใช่ https, เป็น private/loopback, มีข้อมูลยืนยันตัวตน, ยาวเกินไป) | 400 |
-1 | คีย์ API ไม่ถูกต้อง / IP ไม่อยู่ในไวท์ลิสต์ | 401 |
-1 | ไม่พบ endpoint (หรือไม่ใช่ของคุณ) | 404 |
4090 | จำนวน endpoint ถึงขีดจำกัดแล้ว (สูงสุด 2 รายการ: primary, backup) | 409 |
4091 | บทบาทที่ร้องขอถูกใช้งานแล้ว — ให้สลับด้วย PATCH หรือลบ endpoint ที่มีอยู่ออกก่อน | 409 |
4220 | ไม่มีข้อมูลให้อัปเดต (PATCH ด้วย body ว่างเปล่า) | 422 |
5003 | ไม่สามารถสร้าง endpoint ได้ (โปรดลองอีกครั้ง) | 503 |
ขีดจำกัดอัตราการเรียกใช้งาน (Rate Limits)
จำกัดต่อหนึ่งคีย์ API (ส่วนหัว X-API-KEY):
| ระยะเวลา | ขีดจำกัด |
|---|---|
| 1 วินาที | 5 คำขอ |
| 1 นาที | 150 คำขอ |
เรียกใช้งานเกินขีดจำกัด (429)
{ "message": "API rate limit exceeded" }หมายเหตุ
- Secret จะแสดงเพียงครั้งเดียว — เมื่อสร้างและเมื่อผลัดเปลี่ยน จะไม่สามารถเรียกดูได้ผ่าน
GET/LISTเด็ดขาด หากทำหาย ให้ทำการผลัดเปลี่ยน (rotate) เพื่อรับค่าใหม่ - มีสอง endpoint ไม่ใช่การกระจายส่งพร้อมกัน (fan-out): มี
primaryหนึ่งรายการ และbackupหนึ่งรายการ คำสั่งซื้อที่ได้รับการยืนยันแต่ละรายการจะสร้าง webhook หนึ่งรายการ ซึ่งจะถูกจัดส่งไปยัง primary ส่วน backup จะถูกใช้เมื่อ primary พยายามส่งจนครบกำหนดแล้วเท่านั้น - การเปลี่ยน URL โดยไม่มีดาวน์ไทม์ (Zero-downtime): ลงทะเบียนที่อยู่ใหม่เป็น
backupตรวจสอบความถูกต้อง จากนั้นใช้คำสั่งPATCHเพื่อเปลี่ยนเป็นprimary— การสลับตำแหน่งจะเกิดขึ้นในทันที (atomic) - การหยุดชั่วคราว:
PATCH … {"is_active": false}จะหยุดการจัดส่งโดยไม่ทำให้ endpoint สูญหาย - ส่งเฉพาะเหตุการณ์ที่สำเร็จเท่านั้น:
delegation.confirmed,bandwidth.delegated,activation.confirmedไม่มีเหตุการณ์สำหรับความล้มเหลว — คำสั่งซื้อที่ล้มเหลวหรือหมดเวลาจะไม่สร้าง webhook ใดๆ - อาจมีการเพิ่มประเภทเหตุการณ์ใหม่ในอนาคต ให้กำหนดเส้นทางการประมวลผลด้วยฟิลด์
eventและข้ามประเภทที่คุณยัง ไม่รองรับไปก่อน — คุณไม่จำเป็นต้องลงทะเบียนสิ่งใหม่ใดๆ เพื่อเริ่มรับข้อมูลเหล่านั้น - แฮชได้รับการตรวจสอบบนบล็อกเชนก่อนการจัดส่งเสมอ (ดูหมายเหตุที่ด้านบน): webhook จะมีเฉพาะแฮช ที่บันทึกอยู่ในบล็อกแล้วทั้งหมด หรือมิฉะนั้นจะไม่ถูกส่งเลย
- URL ได้รับการตรวจสอบเพื่อความปลอดภัยจาก SSRF ขณะลงทะเบียนและทุกครั้งที่มีการแก้ไข โดยฝั่งระบบจัดส่ง จะทำการตรวจสอบซ้ำอีกครั้ง ณ เวลาที่ส่งข้อมูล