SongSure API v1 — Production
Production base URL: https://www.sendsures.com/api/v1
ขณะนี้ยังไม่มี sandbox หรือ staging host ให้ใช้งาน ทุกตัวอย่างในเอกสารนี้จึงยิงไปที่ production ด้วย API key ของร้าน
> สถานะหลักฐานขนส่ง: ปัจจุบัน Production ยังไม่มีฟีดข้อมูลขนส่งที่เปิดใช้งานและผ่านการรับรอง รายงานใหม่จึงไม่มีผลต่อคะแนนจนกว่าจะมีหลักฐานจากฟีดดังกล่าว และจะเปลี่ยนเป็น unverifiable เมื่อครบ 14 วันหากไม่มีหลักฐาน ตัวเลข response ด้านล่างเป็นตัวอย่างรูปแบบข้อมูล ไม่ใช่ข้อมูลจริงใน Production
ข้อกำหนดที่ระบบสร้างจาก Zod contracts โดยตรงอยู่ที่ https://www.sendsures.com/api/openapi.json ร้านค้าต้องผ่าน KYC และใช้ API key ที่มี scope ตรงกับ endpoint
Authentication และ error contract
API หลักใช้ API key ที่แสดงครั้งเดียวจากหน้า Settings:
Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Type: application/jsonScope ที่ใช้คือ check และ report ทุกข้อผิดพลาดมีรูปแบบเดียวกัน:
{
"error": {
"code": "VALIDATION_ERROR",
"message_th": "ข้อมูลที่ส่งมาไม่ถูกต้อง",
"message_en": "Validation error"
}
}รหัสที่อาจได้รับ: PHONE_REQUIRED, INVALID_TH_PHONE, UNAUTHORIZED, KYC_REQUIRED, RATE_LIMITED, INSUFFICIENT_CREDITS, DUPLICATE_TRACKING, NOT_FOUND, VALIDATION_ERROR, SERVICE_UNAVAILABLE, REPLAY_DETECTED, INTERNAL
POST /check
ใช้ scope check; phone เป็น lookup key ส่วนชื่อและที่อยู่เป็นข้อมูลประกอบเท่านั้น ผลลัพธ์ไม่ส่งเบอร์เต็มกลับมา
curl -X POST https://www.sendsures.com/api/v1/check \
-H "Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"phone":"0891234567","name":"สมชาย ใจดี","ref":"ORDER-1234"}'{
"phone_masked": "08X-XXX-4567",
"score": 67,
"band": "ORANGE",
"confidence": "HIGH",
"recommended_action": "REQUEST_DEPOSIT_OR_TRANSFER",
"stats": {
"no_data": false,
"verified_rejections_6m": 3,
"verified_rejections_24m": 3,
"distinct_merchants": 3,
"total_value_thb": 4150,
"successful_deliveries_12m": 0,
"last_event_month": "2026-05"
},
"name_match": "match",
"address_signal": { "has_history": false, "verified_events": 0 },
"notes": [],
"disclaimer": "ข้อมูลนี้ใช้ประกอบการพิจารณาเท่านั้น",
"checked_at": "2026-08-08T00:00:00.000Z"
}Band คือ GREEN 0–30, YELLOW 31–60, ORANGE 61–80 และ RED 81–100 คำแนะนำคือ PROCEED_COD, CONFIRM_BEFORE_PACK, REQUEST_DEPOSIT_OR_TRANSFER หรือ PREPAID_ONLY ระบบไม่ตัดสินรับหรือปฏิเสธลูกค้าแทนร้าน
POST /bulk-check
ใช้ scope check; สูงสุด 500 แถวต่อคำขอ ระบบตรวจแต่ละแถวแยกกัน รักษาลำดับ input/output และผลสำเร็จทุกแถวมี disclaimer คำขอที่เกิน 500 แถวถูกปฏิเสธด้วย VALIDATION_ERROR และถ้าเวลาประมวลผลใกล้หมด แถวที่เหลือจะได้ SERVICE_UNAVAILABLE รายแถวเพื่อให้ส่งซ้ำเฉพาะส่วนที่ค้าง
curl -X POST https://www.sendsures.com/api/v1/bulk-check \
-H "Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"items":[{"phone":"0891234567","ref":"A-1"},{"phone":"","ref":"A-2"}]}'Reports
ใช้ scope report รายงานเริ่มที่ pending และยังไม่กระทบคะแนนจนกว่าจะมีหลักฐานจากฟีดขนส่งที่เปิดใช้งานและผ่านการรับรอง ปัจจุบัน Production ยังไม่มีฟีดดังกล่าวเชื่อมต่อ
curl -X POST https://www.sendsures.com/api/v1/reports \
-H "Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"type":"cod_rejected","phone":"0891234567","tracking_no":"TH0123456789012","carrier":"flash","order_value_thb":1290,"order_date":"2026-07-10"}'type รองรับ cod_rejected, cancelled_after_ship, return_abuse, successful_delivery และ carrier รองรับ flash, jt, kerry, thaipost, ninja, other
GET /reports?status=pending&limit=50&cursor=<created_at>|<uuid>แสดงเฉพาะรายงานของร้านและคืนnext_cursorDELETE /reports/{id}ถอนรายงานของร้านได้เฉพาะสถานะpendingGET /meคืนโปรไฟล์ร้าน เครดิต และจำนวน checks วันนี้
POST /integrations/order-hook
เป็น thin endpoint บน check engine เดียวกัน ต้องส่ง Idempotency-Key ที่ไม่ซ้ำ ผลลัพธ์ให้บริบทเพื่อการพิจารณาและไม่อนุมัติ/พักออเดอร์อัตโนมัติ
curl -X POST https://www.sendsures.com/api/v1/integrations/order-hook \
-H "Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Idempotency-Key: ORDER-20260808-001" \
-H "Content-Type: application/json" \
-d '{"order_id":"ORDER-001","phone":"0891234567","order_value_thb":1290}'POST /ingest/events — Signed feed (ช่องทางเชื่อมต่อหลัก)
Fulfillment/OMS ใช้ endpoint นี้สร้างรายงาน pending; carrier feed ใช้เป็นหลักฐานสถานะพัสดุเท่านั้น ไม่สร้าง negative report เอง สถานะที่ไม่รู้จักเข้า quarantine พาร์ตเนอร์ใหม่ทุกรายต้องเชื่อมต่อผ่าน endpoint นี้เท่านั้น การมี endpoint ไม่ได้หมายความว่ามีฟีดขนส่งที่เปิดใช้งานและผ่านการรับรองอยู่แล้ว; ปัจจุบัน Production ยังไม่มีฟีดดังกล่าว
Headers:
X-SongSure-Feed-Id: <uuid>
X-SongSure-Timestamp: 1786147200
X-SongSure-Batch-Id: WMS-20260808-001
X-SongSure-Signature: v1=<hex HMAC-SHA256>ลายเซ็นคำนวณจากข้อความต่อไปนี้ด้วย signing secret:
<timestamp>\n<batch-id>\n<raw-json-body>ข้อกำหนด: timestamp เป็น Unix epoch หน่วยวินาทีและคลาดเคลื่อนไม่เกิน 5 นาที, body ไม่เกิน 2 MB, สูงสุด 500 events, event_id ต้องไม่ซ้ำต่อ feed และ metadata รับเฉพาะ order_ref, warehouse_code, service_level, source_system
{
"events": [
{
"schema_version": "1.0",
"event_id": "WMS-EVT-0001",
"occurred_at": "2026-08-08T07:00:00+07:00",
"tracking_no": "TH0123456789012",
"carrier": "flash",
"outcome": "ปฏิเสธรับ",
"phone": "0891234567",
"order_value_thb": 1290,
"order_date": "2026-08-07",
"metadata": { "source_system": "merchant-wms" }
}
]
}Endpoint นี้เป็นคิวแบบ asynchronous ตอบ 202 ทันทีเมื่อบันทึก batch และเหตุการณ์ทั้งชุดลงคิวสำเร็จในทรานแซกชันเดียว โดยยังไม่ประมวลผล คำตอบเป็น *ใบรับ*: batch_id, status, received_events, queued, duplicate, rejected, duplicate_batch, status_url ผลของแต่ละเหตุการณ์อ่านจาก GET /ingest/batches/{batch_id}
การส่งซ้ำด้วย batch id เดิมและเหตุการณ์ชุดเดิมปลอดภัยเสมอ ระบบตอบ 202 พร้อม duplicate_batch: true และรายงาน batch เดิมโดยไม่ประมวลผลซ้ำ 409 เกิดเฉพาะเมื่อนำ batch id เดิมไปใช้กับเหตุการณ์ชุดใหม่ Envelope ผิดตอบ 400, signature ผิด 401
GET /ingest/batches/{batch_id} — สถานะและผลรายเหตุการณ์
ใช้ HMAC ชุดเดียวกับ /ingest/events (ไม่มีวิธียืนยันตัวตนแบบที่สอง) GET ไม่มี body จึงเซ็น "<timestamp>\n<batch-id>\n" เปล่า ๆ และ X-SongSure-Batch-Id ต้องตรงกับ {batch_id} ใน path มิฉะนั้นตอบ 400
คืน status ของ batch, counts (accepted, duplicate, quarantined, rejected, queued) และ events[] ที่มี source_row, event_id ของผู้ส่งเอง, disposition และเหตุผลภาษาไทยแบบคงที่ ฟีดหนึ่งเห็นได้เฉพาะ batch ของตัวเอง (404 ถ้าไม่ใช่) และคำตอบไม่มีข้อมูลร้านค้า รหัสรายงาน เลขพัสดุ หรือเบอร์โทร
Endpoint เดิมที่กำลังจะเลิกใช้
POST /api/ingest/feed เป็น bearer-token adapter ที่คงไว้เพื่อความเข้ากันได้เท่านั้น ไม่ใช่ช่องทางเชื่อมต่อที่แนะนำ และไม่รับพาร์ตเนอร์รายใหม่ รองรับถึง 6 พฤศจิกายน 2026 ส่ง Deprecation, Sunset, Link headers ทุกครั้ง และจำกัด body ไม่เกิน 2 MB เท่ากับ signed feed
GET /imports/{batch_id}/errors
ใช้ scope report ดาวน์โหลด CSV (UTF-8 with BOM) ของข้อผิดพลาดรายแถวในชุดข้อมูลที่นำเข้า คอลัมน์คือ แถวต้นฉบับ, รหัส, ปัญหา, แนวทางแก้ คืนเฉพาะชุดข้อมูลของร้านตัวเอง ถ้าไม่พบหรือไม่ใช่ของร้านตอบ 404
curl -L https://www.sendsures.com/api/v1/imports/<batch_id>/errors \
-H "Authorization: Bearer ss_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-o songsure-import-errors.csvExcel / CSV
หน้า /app/import ใช้ขั้นตอน Upload → Validate/Preview → Confirm → Process → Result รองรับ 10 MB, 2,000 แถว, 1 worksheet, 20 คอลัมน์ และ cell ไม่เกิน 500 ตัวอักษร ระบบปฏิเสธสูตร, macro, hyperlink, external reference, MIME ปลอม และไฟล์ซ้ำ พร้อมดาวน์โหลด CSV ข้อผิดพลาดที่อ้างอิงหมายเลขแถวต้นฉบับ
Outbound webhook
score.changed ส่งเฉพาะข้อมูลปกปิดและมี X-SongSure-Signature เป็น HMAC-SHA256 ของ raw body ด้วย endpoint secret การส่งล้มเหลวเข้าคิว retry โดยไม่ทำให้ transaction หลักล้ม
ข้อจำกัดการใช้ข้อมูล
เมื่อมีหลักฐานที่ผ่านการยืนยัน ระบบจะแสดงข้อมูลเป็นสถิติจากหลักฐานนั้นเพื่อประกอบการพิจารณาความเสี่ยงในการจัดส่ง ไม่ใช่การยืนยันว่าบุคคลใดกระทำผิด และห้ามใช้ตัดสินบุคคลโดยอัตโนมัติ ปัจจุบัน Production ยังไม่มีฟีดขนส่งที่เปิดใช้งานและผ่านการรับรอง เจ้าของหมายเลขสามารถใช้ช่องทาง dispute เพื่อขอตรวจสอบ แก้ไข หรือลบข้อมูลตามสิทธิ์ที่เกี่ยวข้อง