การแบ่งหน้า
รายการของ Sursa API แบ่งหน้าด้วย เคอร์เซอร์ คุณขอรายการได้ไม่เกิน limit รายการ และการตอบกลับจะบอกวิธีรับหน้าถัดไป คุณไม่ต้องคำนวณออฟเซ็ตเอง และรายการจะไม่ซ้ำหรือหายไประหว่างหน้า แม้ข้อมูลจะเปลี่ยนแปลงในระหว่างนั้น
| พารามิเตอร์ | ค่า |
|---|---|
limit | จำนวนรายการต่อหน้า โดยทั่วไป 1–200 รายการใหม่มีค่าเริ่มต้น 50 และเอกสารอ้างอิงแสดงช่วงค่าและค่าเริ่มต้นของแต่ละรายการ |
cursor | เคอร์เซอร์จากหน้าก่อนหน้า ไม่ต้องส่งสำหรับหน้าแรก |
รายการส่งคืนเคอร์เซอร์ถัดไปได้สองแบบ ขึ้นอยู่กับโครงสร้างของการตอบกลับ หน้าของแต่ละเอนด์พอยต์ใน เอกสารอ้างอิง API ระบุว่าใช้แบบใด
รายการที่ห่อด้วย data
รายการที่เพิ่มเข้ามาสำหรับ API สาธารณะ เช่น ฟีดอีเวนต์ ส่งคืนออบเจ็กต์ที่มีรายการอยู่ใน data:
curl "https://api.sursa.com/v1/webhook-events?limit=2" \
-H "Authorization: Bearer $SURSA_API_KEY"{
"data": [
{"id": "evt_8a1f…", "type": "card.published", "created_at": "2026-10-24T10:00:00Z"},
{"id": "evt_8a20…", "type": "card.updated", "created_at": "2026-10-24T10:00:03Z"}
],
"next_cursor": "eyJ2IjoxLCJrIjpbMTA0Ml19",
"has_more": true
}
เมื่อ has_more เป็น true ให้ขอหน้าถัดไปโดยตั้ง cursor เป็นค่า next_cursor และใช้ ตัวกรองเดิม:
curl "https://api.sursa.com/v1/webhook-events?limit=2&cursor=eyJ2IjoxLCJrIjpbMTA0Ml19" \
-H "Authorization: Bearer $SURSA_API_KEY"รายการที่มีมาก่อนการใช้เคอร์เซอร์และส่งคืนออบเจ็กต์ยังคงใช้โครงสร้างที่ห่อแบบของตัวเอง (เช่น {"items": […], "total": 120}) รายการเหล่านี้ได้ next_cursor และ has_more ในออบเจ็กต์เดียวกัน ส่วนตัวรายการยังอยู่ที่เดิม
รายการที่ส่งคืนอาร์เรย์
รายการจำนวนหนึ่งส่งคืนอาร์เรย์ JSON ล้วน เช่น GET /v1/collections โครงสร้างการตอบกลับของรายการเหล่านี้เปลี่ยนไม่ได้ หน้าถัดไปจึงมาในเฮดเดอร์แทน:
curl -i "https://api.sursa.com/v1/collections?limit=50" \
-H "Authorization: Bearer $SURSA_API_KEY"HTTP/1.1 200 OK
Link: <https://api.example.com/v1/collections?limit=50&cursor=eyJ2IjoxLCJrIjpbNTBdfQ>; rel="next"
X-Next-Cursor: eyJ2IjoxLCJrIjpbNTBdfQ
[{"id": 1, "name": "support", …}, …]
Linkที่มีrel="next"คือที่อยู่เต็มของหน้าถัดไป ส่วนX-Next-Cursorคือเคอร์เซอร์เดียวกันแบบเดี่ยว- หากไม่มี
Linkที่มีrel="next"และไม่มีX-Next-Cursorแสดงว่านี่คือหน้าสุดท้าย - หากไม่ระบุ
limitรายการเหล่านี้จะส่งคืนทุกรายการในการตอบกลับเดียวเหมือนที่เคยเป็นมา ส่งlimitเพื่อแบ่งหน้า เคอร์เซอร์จำขนาดหน้าไว้ คำขอถัดไปจึงไม่ต้องส่งlimitก็ได้ GET /v1/cardsเป็นข้อยกเว้น รายการนี้ส่งคืนเป็นหน้าเสมอ ค่าเริ่มต้นคือ 200 การ์ด และได้สูงสุด 1,000 การ์ดเมื่อระบุlimitจึงต้องติดตามX-Next-Cursorแม้ไม่ได้ระบุlimit
// Every item of a list that returns an array.
async function* listArray(path) {
let next = `https://api.sursa.com${path}?limit=200`;
while (next) {
const response = await fetch(next, { headers: { Authorization: `Bearer ${process.env.SURSA_API_KEY}` } });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
yield* await response.json();
const cursor = response.headers.get("X-Next-Cursor");
next = cursor ? `https://api.sursa.com${path}?cursor=${encodeURIComponent(cursor)}` : null;
}
}ฟีดอีเวนต์
ฟีดอีเวนต์ GET /v1/webhook-events เป็นล็อก จึงแบ่งหน้าต่างออกไปเล็กน้อย:
- อีเวนต์เรียงจากเก่าไปใหม่
next_cursorส่งคืนมาใน ทุก หน้า แม้has_moreจะเป็นfalseให้เก็บค่านี้ไว้ แล้วขอใหม่ภายหลังด้วยเคอร์เซอร์เดิมเพื่อรับอีเวนต์ที่เกิดขึ้นหลังจากนั้น ฟีดเป็นคิวที่คุณอ่านตามจังหวะของคุณเองได้- อีเวนต์ปรากฏในฟีดภายในประมาณ 1 วินาทีหลังการเปลี่ยนแปลงที่อีเวนต์นั้นอธิบาย และจะไม่ปรากฏก่อนอีเวนต์ที่อ่านไปแล้ว
- ฟีดเก็บอีเวนต์ขององค์กรทั้งหมด การอ่านฟีดจึงต้องใช้คีย์ที่มีบทบาท
adminและขอบเขตสิทธิ์webhooks:manage
ส่งออกไปยังคลังข้อมูล แสดงลูปการโพลที่สมบูรณ์
กฎของเคอร์เซอร์
- เคอร์เซอร์เป็นสตริงทึบ (opaque) ยาวไม่เกิน 512 อักขระ อย่าแยกวิเคราะห์หรือสร้างเคอร์เซอร์เอง เพราะรูปแบบอาจเปลี่ยนได้
- เคอร์เซอร์เป็นของรายการเดียวและชุดตัวกรองชุดเดียว เคอร์เซอร์ที่เสียหาย มาจากรายการอื่น หรือส่งพร้อมตัวกรองที่ต่างไป จะได้การตอบกลับ
400พร้อมรหัสapi.cursor_invalid - แต่ละรายการมีลำดับการเรียงตายตัวที่ลงท้ายด้วยคีย์ที่ไม่ซ้ำกัน ทุกรายการจึงปรากฏในหน้าเดียวเท่านั้น
- รายการที่เพิ่มเข้ามาพร้อมเคอร์เซอร์ไม่ส่งคืนจำนวนรวม ส่วนรายการที่เคยมี
totalยังคงมีอยู่ หากต้องการจำนวนรวม ให้นับรายการไประหว่างอ่าน
การแบ่งหน้าแบบออฟเซ็ต
รายการบางรายการรับ offset มาตั้งแต่ก่อนมีเคอร์เซอร์ และยังรับอยู่ เพื่อให้ระบบที่เชื่อมต่ออยู่แล้วทำงานต่อได้ ในโค้ดใหม่ให้ใช้ cursor จะใช้ offset ร่วมกับ cursor ไม่ได้ การส่งทั้งคู่จะได้การตอบกลับ 422 พร้อมรหัส validation.failed