[{"data":1,"prerenderedAt":537},["ShallowReactive",2],{"docs-nav":3,"docs-\u002Fdocs\u002Fauthentication":35,"docs-surround-\u002Fdocs\u002Fauthentication":530},[4,9,13,18,22,26,30],{"path":5,"title":6,"category":7,"order":8},"\u002Fdocs","Introduction","intro",1,{"path":10,"title":11,"category":7,"order":12},"\u002Fdocs\u002Fgetting-started","เริ่มต้นใช้งาน",10,{"path":14,"title":15,"category":16,"order":17},"\u002Fdocs\u002Fauthentication","Authentication","core",20,{"path":19,"title":20,"category":16,"order":21},"\u002Fdocs\u002Fapi","API Reference",25,{"path":23,"title":24,"category":16,"order":25},"\u002Fdocs\u002Fwebhooks","Webhooks",30,{"path":27,"title":28,"category":16,"order":29},"\u002Fdocs\u002Fsecurity","Security & PDPA",50,{"path":31,"title":32,"category":33,"order":34},"\u002Fdocs\u002Fchangelog","Changelog","meta",90,{"id":36,"title":15,"badge":37,"body":38,"category":16,"description":523,"extension":524,"meta":525,"navigation":526,"order":17,"path":14,"seo":527,"stem":528,"updatedAt":37,"__hash__":529},"docs\u002Fdocs\u002Fauthentication.md",null,{"type":39,"value":40,"toc":514},"minimark",[41,45,50,62,87,97,101,112,126,140,176,180,187,290,313,320,334,354,358,372,382,392,396,399,510],[42,43,44],"p",{},"SlipBolt มี 2 ชนิด credential — ใช้แยกตามบทบาท",[46,47,49],"h2",{"id":48},"bearer-jwt-dashboard-liff","Bearer JWT (Dashboard \u002F LIFF)",[42,51,52,53,57,58,61],{},"ผู้ใช้ login ที่ ",[54,55,56],"code",{},"app.slip-bolt.com"," แล้วได้ JWT access token (TTL 15 นาที) + refresh cookie (",[54,59,60],{},"sb_rt"," · 7 วัน · หมุนทุกครั้งที่ใช้)",[63,64,69],"pre",{"className":65,"code":66,"language":67,"meta":68,"style":68},"language-http shiki shiki-themes github-light github-dark","Authorization: Bearer eyJhbGciOiJIUzI1NiIs...\n","http","",[54,70,71],{"__ignoreMap":68},[72,73,75,79,83],"span",{"class":74,"line":8},"line",[72,76,78],{"class":77},"s9eBZ","Authorization",[72,80,82],{"class":81},"szBVR",":",[72,84,86],{"class":85},"sZZnC"," Bearer eyJhbGciOiJIUzI1NiIs...\n",[88,89,90,94],"ul",{},[91,92,93],"li",{},"Refresh อัตโนมัติเมื่อ access token หมดอายุ → useApi composable จัดให้ทั้งหมด",[91,95,96],{},"เหมาะกับ browser \u002F mobile app",[46,98,100],{"id":99},"api-key-server-to-server","API Key (Server-to-server)",[42,102,103,104,108,109],{},"สร้างที่ ",[105,106,107],"strong",{},"Settings → API Keys"," — รูปแบบ ",[54,110,111],{},"sk_live_\u003C32 chars>",[113,114,116],"callout",{"type":115},"warning",[42,117,118,121,122,125],{},[105,119,120],{},"ต้องใช้แพ็ก Starter ขึ้นไป"," — ช่วงทดลองใช้ฟรี (Trial) ออก API key ไม่ได้\nและคีย์ที่ออกไว้ตอนอยู่แพ็กที่จ่ายเงิน จะถูกปฏิเสธด้วย ",[54,123,124],{},"403"," ทันทีที่แพ็กหมดอายุ\nหรือร้านถูกพักใช้งาน (ตรวจทุกคำขอ ไม่ใช่แค่ตอนออกคีย์)",[63,127,129],{"className":65,"code":128,"language":67,"meta":68,"style":68},"Authorization: Bearer sk_live_a1b2c3d4...\n",[54,130,131],{"__ignoreMap":68},[72,132,133,135,137],{"class":74,"line":8},[72,134,78],{"class":77},[72,136,82],{"class":81},[72,138,139],{"class":85}," Bearer sk_live_a1b2c3d4...\n",[88,141,142,145,151,170],{},[91,143,144],{},"ไม่หมดอายุ จนกว่าจะ revoke",[91,146,147,150],{},[105,148,149],{},"สูงสุด 5 คีย์ที่ยังไม่ถูกเพิกถอนต่อร้าน"," — เพิกถอนใบที่ไม่ใช้ก่อนจึงจะออกใบใหม่ได้",[91,152,153,154,157,158,161,162,165,166],{},"มี scope จำกัด (default: ",[54,155,156],{},"verify"," · เพิ่ม ",[54,159,160],{},"read","\u002F",[54,163,164],{},"webhook"," ได้ที่ Settings → API Keys) — ดู ",[167,168,20],"a",{"href":169},"\u002Fdocs\u002Fapi#scopes",[91,171,172,173],{},"เก็บใน server environment variable เท่านั้น ",[105,174,175],{},"อย่าใส่ในโค้ด frontend",[46,177,179],{"id":178},"สิทธิ์ต่อแพ็ก-โควตา-ที่นั่ง-line-api","สิทธิ์ต่อแพ็ก (โควตา · ที่นั่ง · LINE · API)",[42,181,182,183,186],{},"ร้านแรกช่วงทดลอง 7 วันได้สิทธิ์แถว ",[105,184,185],{},"Trial เท่านั้น"," — ไม่ใช่แพ็กที่เลือกตอน onboarding",[188,189,190,215],"table",{},[191,192,193],"thead",{},[194,195,196,200,203,206,209,212],"tr",{},[197,198,199],"th",{},"Plan",[197,201,202],{},"สลิป\u002Fเดือน",[197,204,205],{},"ที่นั่ง",[197,207,208],{},"กลุ่ม LINE",[197,210,211],{},"LINE OA",[197,213,214],{},"REST API",[216,217,218,237,255,273],"tbody",{},[194,219,220,224,227,230,232,234],{},[221,222,223],"td",{},"Trial",[221,225,226],{},"50",[221,228,229],{},"1",[221,231,229],{},[221,233,229],{},[221,235,236],{},"❌",[194,238,239,242,245,247,249,252],{},[221,240,241],{},"Starter",[221,243,244],{},"500",[221,246,229],{},[221,248,229],{},[221,250,251],{},"3",[221,253,254],{},"✅",[194,256,257,260,263,266,268,271],{},[221,258,259],{},"Pro",[221,261,262],{},"1,500",[221,264,265],{},"5",[221,267,251],{},[221,269,270],{},"10",[221,272,254],{},[194,274,275,278,281,284,286,288],{},[221,276,277],{},"Business",[221,279,280],{},"5,000",[221,282,283],{},"ไม่จำกัด",[221,285,270],{},[221,287,283],{},[221,289,254],{},[42,291,292,293,296,297,300,301,304,305,308,309,312],{},"โควตาสลิปเป็น ",[105,294,295],{},"pool เดียวกับสลิปที่เข้าทาง LINE"," — ใช้ช่องไหนก็หักจากก้อนเดียวกัน\nอ่านยอดคงเหลือได้ที่ ",[54,298,299],{},"GET \u002Fapi\u002Fv1\u002Fquota"," · ",[54,302,303],{},"GET \u002Fapi\u002Fv1\u002Fme"," หรือ header ",[54,306,307],{},"X-Slipbolt-Quota-*","\n(ดู ",[167,310,20],{"href":311},"\u002Fdocs\u002Fapi#get-apiv1me",")",[46,314,316,319],{"id":315},"sk_test_-เลนทดสอบ",[54,317,318],{},"sk_test_"," — เลนทดสอบ",[42,321,322,323,325,326,329,330,333],{},"คีย์ที่ขึ้นต้นด้วย ",[54,324,318],{}," ",[105,327,328],{},"ไม่กินโควตาสลิปรายเดือนของร้าน"," ใช้ต่อ integration\nได้โดยไม่เปลืองของที่จ่ายเงินมา · response มี ",[54,331,332],{},"\"environment\": \"test\""," กำกับ",[113,335,336],{"type":115},[42,337,338,341,342,345,346,349,350,353],{},[105,339,340],{},"เลนทดสอบมีเพดาน 200 ครั้ง\u002Fร้าน\u002Fเดือน"," — เพราะมันยังตรวจสลิปกับธนาคารจริงทุกครั้ง\n(ไม่ใช่ของจำลอง) เกินเพดานได้ ",[54,343,344],{},"402"," พร้อม ",[54,347,348],{},"code: \"TEST_QUOTA_EXCEEDED\""," (สถานะเดียวกับตอนโควตาของร้านหมด — ทางออกคือย้ายไปคีย์ ",[54,351,352],{},"sk_live_",") · นับทุกคำขอ\nที่ยิงเข้ามา ไม่ใช่เฉพาะที่สำเร็จ เพราะค่าใช้จ่ายเกิดตั้งแต่ตอนยิง",[46,355,357],{"id":356},"rate-limit-เท่ากันทุกแพ็ก","Rate limit (เท่ากันทุกแพ็ก)",[42,359,360,363,364,367,368,371],{},[105,361,362],{},"120 req\u002Fmin ต่อ 1 API key"," — นับแบบ fixed window ราย 1 นาที และ",[105,365,366],{},"ไม่ได้แยกตามแพ็ก","\nมีเพดานรวมของ endpoint ",[54,369,370],{},"POST \u002Fapi\u002Fv1\u002Fverify"," อีกชั้นที่ 240 req\u002Fmin",[42,373,374,375,378,379],{},"เกิน → ",[54,376,377],{},"429 Too Many Requests"," + header ",[54,380,381],{},"Retry-After: \u003Cseconds>",[113,383,385],{"type":384},"info",[42,386,387,388,391],{},"ต้องการเพดานสูงกว่านี้ ติดต่อทีมงาน — ปรับได้ที่ฝั่งเซิร์ฟเวอร์ (",[54,389,390],{},"API_KEY_RATE_LIMIT_PER_MIN",")\nไม่ใช่การอัปเกรดแพ็ก",[46,393,395],{"id":394},"error-responses","Error responses",[42,397,398],{},"ทุก error envelope เป็นรูปแบบเดียวกัน:",[63,400,404],{"className":401,"code":402,"language":403,"meta":68,"style":68},"language-json shiki shiki-themes github-light github-dark","{\n  \"success\": false,\n  \"error\": \"Unauthorized\",\n  \"message\": \"Invalid API key\",\n  \"statusCode\": 401,\n  \"path\": \"\u002Fapi\u002Fv1\u002Fverify\",\n  \"requestId\": \"req_abc123\",\n  \"timestamp\": \"2026-05-25T12:30:45+07:00\"\n}\n","json",[54,405,406,412,428,441,454,467,480,493,504],{"__ignoreMap":68},[72,407,408],{"class":74,"line":8},[72,409,411],{"class":410},"sVt8B","{\n",[72,413,415,419,422,425],{"class":74,"line":414},2,[72,416,418],{"class":417},"sj4cs","  \"success\"",[72,420,421],{"class":410},": ",[72,423,424],{"class":417},"false",[72,426,427],{"class":410},",\n",[72,429,431,434,436,439],{"class":74,"line":430},3,[72,432,433],{"class":417},"  \"error\"",[72,435,421],{"class":410},[72,437,438],{"class":85},"\"Unauthorized\"",[72,440,427],{"class":410},[72,442,444,447,449,452],{"class":74,"line":443},4,[72,445,446],{"class":417},"  \"message\"",[72,448,421],{"class":410},[72,450,451],{"class":85},"\"Invalid API key\"",[72,453,427],{"class":410},[72,455,457,460,462,465],{"class":74,"line":456},5,[72,458,459],{"class":417},"  \"statusCode\"",[72,461,421],{"class":410},[72,463,464],{"class":417},"401",[72,466,427],{"class":410},[72,468,470,473,475,478],{"class":74,"line":469},6,[72,471,472],{"class":417},"  \"path\"",[72,474,421],{"class":410},[72,476,477],{"class":85},"\"\u002Fapi\u002Fv1\u002Fverify\"",[72,479,427],{"class":410},[72,481,483,486,488,491],{"class":74,"line":482},7,[72,484,485],{"class":417},"  \"requestId\"",[72,487,421],{"class":410},[72,489,490],{"class":85},"\"req_abc123\"",[72,492,427],{"class":410},[72,494,496,499,501],{"class":74,"line":495},8,[72,497,498],{"class":417},"  \"timestamp\"",[72,500,421],{"class":410},[72,502,503],{"class":85},"\"2026-05-25T12:30:45+07:00\"\n",[72,505,507],{"class":74,"line":506},9,[72,508,509],{"class":410},"}\n",[511,512,513],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":68,"searchDepth":430,"depth":430,"links":515},[516,517,518,519,521,522],{"id":48,"depth":414,"text":49},{"id":99,"depth":414,"text":100},{"id":178,"depth":414,"text":179},{"id":315,"depth":414,"text":520},"sk_test_ — เลนทดสอบ",{"id":356,"depth":414,"text":357},{"id":394,"depth":414,"text":395},"Bearer JWT (dashboard) vs API key (server-to-server) — เลือกใช้แบบไหนเมื่อไร","md",{},true,{"title":15,"description":523},"docs\u002Fauthentication","8Zoq-FkoQ5tF2RJCdJMWOCiSh56jSZRaCoH6zP3Fr70",[531,534],{"title":20,"path":19,"stem":532,"description":533},"docs\u002Fapi","Public REST API สำหรับ integrator — ตรวจสลิป, อ่านโควตา, รูปแบบ error + status ครบทุก endpoint",{"title":32,"path":31,"stem":535,"description":536},"docs\u002Fchangelog","ฟีเจอร์ใหม่ + การเปลี่ยนแปลงสำคัญของ SlipBolt API",1789321307442]