Paxa Labs

อัตราจำกัดคำขอและคำขอพร้อมกัน

ลิมิตระดับบัญชีสองตัวที่กำหนดโดยแพ็กเกจ คำขอต่อนาทีใช้หน้าต่างเวลาร่วมกันทุกผลิตภัณฑ์ ส่วนคำขอพร้อมกันนับแยกตามผลิตภัณฑ์ พร้อมวิธีนับของแต่ละลิมิต วิธีอ่านเฮดเดอร์ x-ratelimit และวิธีส่งซ้ำเมื่อเจอ 429

ดูเป็น Markdown

ลิมิตมีสองตัว และแพ็กเกจเป็นตัวกำหนดทั้งคู่ คำขอต่อนาทีนับครั้งเดียวทั้งบัญชี: หน้าต่างเวลาเดียวครอบคลุมทุกผลิตภัณฑ์และทุกคีย์ ส่วนคำขอพร้อมกันนับแยกตามผลิตภัณฑ์: เสียงพูด การถอดเสียง OCR และแปลภาษา มีโควตาแยกของตัวเองขนาดเท่าตัวเลขของแพ็กเกจ และการสกัดข้อมูลจากเอกสารใช้โควตาเดียวกับ OCR เอนด์พอยต์แคตตาล็อก บัญชี และสถานะระบบ ไม่ถูกจำกัด ส่วนความคิดเห็นมีโควตารายวันของตัวเอง ดูตัวเลขของแต่ละแพ็กเกจได้ที่หน้าราคา ปัจจุบันคือ

แพ็กเกจคำขอต่อนาทีคำขอพร้อมกัน
Free101
Starter605
Standard20015
Proไม่จำกัด60

คำขอพร้อมกันนับแยกตามผลิตภัณฑ์: แพ็กเกจ Standard จึงมีคำขอเสียงพูดค้างอยู่ได้ 15 คำขอ พร้อมกับคำขอถอดเสียงอีก 15 คำขอ คำขอ OCR อีก 15 คำขอ และคำขอแปลภาษาอีก 15 คำขอในเวลาเดียวกัน GET /v1/me รายงานตัวเลขทั้งสองของบัญชีที่ยืนยันตัวตนแล้ว

หน้าต่างคำขอเดียว โควตาพร้อมกันแยกกัน#

ลิมิตสองตัวนี้ตั้งใจให้นับต่างกัน:

  • คำขอต่อนาทีใช้ร่วมกัน หน้าต่างเวลาเดียวครอบคลุมทั้งบัญชี: ทุกผลิตภัณฑ์ ทุกคีย์ และทุกรอบสังเคราะห์บนสตรีมสด รวมกัน
  • คำขอพร้อมกันแยกจากกัน เสียงพูด การถอดเสียง OCR และแปลภาษา มีโควตาของตัวเองขนาดเท่าตัวเลขของแพ็กเกจ และคำขอสกัดข้อมูลจากเอกสารนับในโควตา OCR งานแปลชุดใหญ่ที่ช้าจึงไม่มีทางขวางเสียงพูด การอ่านเอกสาร หรือการถอดเสียง และกลับกันก็เช่นกัน
  • การเชื่อมต่อสดที่เปิดอยู่ถือหนึ่งช่องของฝั่งเสียงพูดตลอดเวลาที่เชื่อมต่อ ไม่ว่าขณะนั้นจะกำลังสังเคราะห์อยู่หรือไม่

หน้าต่างเวลาแบบเลื่อน#

การจำกัดใช้หน้าต่างเวลา 60 วินาทีแบบเลื่อน นาทีก่อนหน้ายังถูกนับตามสัดส่วนเวลาที่เหลืออยู่ การยิงคำขอชุดใหญ่จึงใช้โควตาซ้อนกันสองเท่าตรงรอยต่อของนาทีไม่ได้ และโควตาทยอยคืนอย่างต่อเนื่อง

อ่านเฮดเดอร์#

ในแพ็กเกจที่มีการจำกัด การตอบกลับของคำขอสังเคราะห์ทุกครั้งรายงานโควตาผ่าน x-ratelimit-limit, x-ratelimit-remaining และ x-ratelimit-reset (เวลา Unix เป็นวินาที) ส่วนแพ็กเกจที่ไม่จำกัดจะไม่ส่งเฮดเดอร์ชุดนี้

Response headers
HTTP/1.1 200 OK
Content-Type: audio/mpeg
x-request-id: 7d9c2b7e-4a41-4c8e-9a35-1f26d8c04b7a
x-credits-charged: 0.86
x-ratelimit-limit: 60
x-ratelimit-remaining: 42
x-ratelimit-reset: 1785762360

คำขอพร้อมกัน#

หนึ่งช่องคือหนึ่งคำขอที่ค้างอยู่: คำขอสังเคราะห์ผ่าน HTTP นับตั้งแต่รับเข้าจนการตอบกลับจบ คำขอแปลภาษาหรืออ่านเอกสารนับจนกว่า JSON จะตอบกลับ และการเชื่อมต่อสดนับตั้งแต่อัปเกรดจนปิด เมื่อบัญชีถือครบทุกช่องของผลิตภัณฑ์ใด คำขอใหม่ของผลิตภัณฑ์นั้นตอบ 429 concurrency_limited และไม่มีการคิดค่าบริการ

การตอบกลับ concurrency_limited ไม่มีเฮดเดอร์ retry-after เพราะการรอจะจบเมื่อคำขอของคุณเองเสร็จหนึ่งรายการ ให้ส่งซ้ำหลังมีคำขอเสร็จ หรือปิดการเชื่อมต่อสดที่ไม่ใช้แล้ว สังเกต x-ratelimit-remaining ในตัวอย่าง: หน้าต่างคำขอยังเหลือโควตา และ 429 ครั้งนี้เป็นเรื่องช่องคำขอที่ค้างอยู่

429 response
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
x-ratelimit-limit: 60
x-ratelimit-remaining: 41
x-ratelimit-reset: 1785762420

{"title": "concurrency_limited", "status": 429}

อยู่ใต้ลิมิต#

ลิมิตทั้งสองตัวนับจำนวนคำขอ ขนาดของแต่ละคำขอไม่มีผล ควรรวมงานให้เหลือจำนวนคำขอน้อยที่สุด คำขอแปลภาษาที่ส่งอาร์เรย์หลายท่อนนับเป็นหนึ่งคำขอต่อหน้าต่างเวลาและถือหนึ่งช่อง คำขอ TTS ที่ส่งทั้งย่อหน้านับเป็นหนึ่งคำขอ ส่วนการเรียกทีละประโยคนับทีละคำขอ

ทุกคีย์ใช้ลิมิตของบัญชีร่วมกัน การเพิ่มคีย์จึงไม่เพิ่มโควตา ให้เว้นจังหวะส่งซ้ำตาม retry-after การเปิด WebSocket สดก็ถูกปฏิเสธด้วย 429 ได้เหมือนคำขอสังเคราะห์ทั่วไป จากลิมิตตัวใดก็ได้

จัดการการตอบกลับ 429#

สถานะ 429 มีได้สองโค้ด และ title คือตัวแยก rate_limited แปลว่าหน้าต่างต่อนาทีหมดโควตา ให้รอตามเฮดเดอร์ retry-after ส่วน concurrency_limited แปลว่าทุกช่องของผลิตภัณฑ์นั้นถูกถือครบ ให้ส่งซ้ำเมื่อคำขอของคุณเสร็จหนึ่งรายการ ตัวช่วยรอแล้วส่งซ้ำง่าย ๆ ครอบคลุมทั้งสองกรณีสำหรับงานส่วนใหญ่

429 response
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
retry-after: 12
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785762420

{"title": "rate_limited", "status": 429}
TypeScript
async function withRetry(request: () => Promise<Response>): Promise<Response> {
  for (;;) {
    const response = await request();
    if (response.status !== 429) return response;
    // rate_limited sends retry-after. concurrency_limited does not,
    // and a short wait covers a slot freeing up.
    const seconds = Number(response.headers.get("retry-after") ?? "1");
    await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
  }
}