API and trust
HTTP API
HTTP API
URL ฐาน: https://clawhub.ai (ค่าเริ่มต้น)
พาธ v1 ทั้งหมดอยู่ภายใต้ /api/v1/...
/api/... และ /api/cli/... แบบเดิมยังคงไว้เพื่อความเข้ากันได้ (ดู DEPRECATIONS.md)
OpenAPI: /api/v1/openapi.json
การนำแคตตาล็อกสาธารณะมาใช้ซ้ำ
ไดเรกทอรีของบุคคลที่สามอาจใช้เอนด์พอยต์การอ่านสาธารณะเพื่อแสดงรายการหรือค้นหา Skills ของ ClawHub โปรดแคชผลลัพธ์ ปฏิบัติตาม 429/Retry-After ลิงก์ผู้ใช้กลับไปยังรายการ ClawHub หลัก (https://clawhub.ai/<owner>/skills/<slug>) และหลีกเลี่ยงการสื่อเป็นนัยว่า ClawHub รับรองเว็บไซต์ของบุคคลที่สาม อย่าพยายามทำสำเนาเนื้อหาที่ซ่อนอยู่ เป็นส่วนตัว หรือถูกบล็อกโดยการกลั่นกรองนอกขอบเขต API สาธารณะ
ทางลัด slug บนเว็บสามารถแก้ไขข้ามตระกูลรีจิสทรีได้ แต่ไคลเอนต์ API ควรใช้ URL หลักที่เอนด์พอยต์การอ่านส่งกลับ แทนการสร้างลำดับความสำคัญของเส้นทาง ขึ้นใหม่
ขีดจำกัดอัตรา
รูปแบบการบังคับใช้:
-
คำขอแบบไม่ระบุตัวตน: บังคับใช้ต่อ IP
-
คำขอที่ยืนยันตัวตนแล้ว (Bearer token ที่ถูกต้อง): บังคับใช้ตามบัคเก็ตของผู้ใช้
-
หากไม่มีโทเค็นหรือโทเค็นไม่ถูกต้อง ลักษณะการทำงานจะย้อนกลับไปใช้การบังคับใช้ตาม IP
-
เอนด์พอยต์การเขียนที่ยืนยันตัวตนแล้วไม่ควรส่งคืนเพียง
Unauthorizedเมื่อ เซิร์ฟเวอร์ทราบสาเหตุ โทเค็นที่หายไป โทเค็นที่ไม่ถูกต้อง/ถูกเพิกถอน และ บัญชีที่ถูกลบ/แบน/ปิดใช้งานควรได้รับข้อความที่นำไปดำเนินการได้แยกกัน เพื่อให้ไคลเอนต์ CLI สามารถแจ้งผู้ใช้ได้ว่าอะไรขัดขวางการทำงาน -
อ่าน: 3000/นาทีต่อ IP, 12000/นาทีต่อคีย์
-
เขียน: 300/นาทีต่อ IP, 3000/นาทีต่อคีย์
-
ดาวน์โหลด: 1200/นาทีต่อ IP, 6000/นาทีต่อคีย์ (เอนด์พอยต์ดาวน์โหลด)
ส่วนหัว:
- ความเข้ากันได้แบบเดิม:
X-RateLimit-Limit,X-RateLimit-Reset - แบบมาตรฐาน:
RateLimit-Limit,RateLimit-Reset - เมื่อเป็น
429:X-RateLimit-Remaining: 0และRateLimit-Remaining: 0 - เมื่อเป็น
429:Retry-After
ความหมายของส่วนหัว:
X-RateLimit-Reset: จำนวนวินาที Unix epoch แบบสัมบูรณ์RateLimit-Reset: จำนวนวินาทีจนกว่าจะรีเซ็ต (ระยะหน่วง)X-RateLimit-Remaining/RateLimit-Remaining: โควตาที่เหลืออย่างแม่นยำเมื่อมีค่า คำขอแบบแบ่งชาร์ดที่สำเร็จจะละเว้นส่วนหัวนี้ แทนการส่งคืนค่าโดยรวมโดยประมาณRetry-After: จำนวนวินาทีที่ต้องรอก่อนลองใหม่ (ระยะหน่วง) เมื่อเป็น429
ตัวอย่างการตอบกลับ 429:
HTTP/2 429content-type: text/plain; charset=utf-8x-ratelimit-limit: 20x-ratelimit-remaining: 0x-ratelimit-reset: 1771404540ratelimit-limit: 20ratelimit-remaining: 0ratelimit-reset: 34retry-after: 34 เกินขีดจำกัดอัตราคำแนะนำสำหรับไคลเอนต์:
- หากมี
Retry-Afterให้รอตามจำนวนวินาทีนั้นก่อนลองใหม่ - ใช้การถอยกลับที่เพิ่มค่าความสุ่มเพื่อหลีกเลี่ยงการลองใหม่พร้อมกัน
- หากไม่มี
Retry-Afterให้ย้อนกลับไปใช้RateLimit-Reset(หรือคำนวณจากX-RateLimit-Reset)
แหล่งที่มาของ IP:
- ใช้ส่วนหัว IP ของไคลเอนต์ที่เชื่อถือได้ รวมถึง
cf-connecting-ipเฉพาะเมื่อ การปรับใช้เปิดใช้ส่วนหัวที่ส่งต่อน่าเชื่อถือไว้อย่างชัดเจน - ClawHub ใช้ส่วนหัวการส่งต่อที่เชื่อถือได้เพื่อระบุ IP ของไคลเอนต์ที่เอดจ์
- หากไม่มี IP ของไคลเอนต์ที่เชื่อถือได้ คำขอแบบไม่ระบุตัวตนจะใช้บัคเก็ตสำรอง ที่กำหนดขอบเขตตามชนิดขีดจำกัดอัตราเท่านั้น บัคเก็ตสำรองเหล่านี้ไม่รวม พาธ slug ชื่อแพ็กเกจ เวอร์ชัน สตริงการค้นหา หรือพารามิเตอร์ อาร์ติแฟกต์อื่นที่ผู้เรียกส่งมา
การตอบกลับข้อผิดพลาด
การตอบกลับข้อผิดพลาด v1 สาธารณะเป็นข้อความธรรมดาพร้อม content-type: text/plain; charset=utf-8
ซึ่งรวมถึงความล้มเหลวในการตรวจสอบความถูกต้อง (400) ทรัพยากรสาธารณะที่ไม่พบ (404) ความล้มเหลวด้านการยืนยันตัวตนและ
สิทธิ์ (401/403) ขีดจำกัดอัตรา (429) และการดาวน์โหลดที่ถูกบล็อก ไคลเอนต์
ควรอ่านเนื้อหาการตอบกลับเป็นสตริงที่มนุษย์อ่านเข้าใจได้ ระบบจะละเว้นพารามิเตอร์การค้นหาที่ไม่รู้จัก
เพื่อความเข้ากันได้ แต่พารามิเตอร์การค้นหาที่ระบบรู้จักแต่มีค่าไม่ถูกต้องจะส่งคืน
400
เอนด์พอยต์สาธารณะ (ไม่ต้องยืนยันตัวตน)
GET /api/v1/search
พารามิเตอร์การค้นหา:
q(จำเป็น): สตริงการค้นหาlimit(ไม่บังคับ): จำนวนเต็มhighlightedOnly(ไม่บังคับ):trueเพื่อกรองเฉพาะ Skills ที่ได้รับการเน้นnonSuspiciousOnly(ไม่บังคับ):trueเพื่อซ่อน Skills ที่น่าสงสัย (flagged.suspicious)nonSuspicious(ไม่บังคับ): นามแฝงแบบเดิมสำหรับnonSuspiciousOnly
การตอบกลับ:
{ "results": [ { "score": 0.123, "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "version": "1.2.3", "updatedAt": 1730000000000, "ownerHandle": "openclaw", "owner": { "handle": "openclaw", "displayName": "OpenClaw", "image": "https://example.com/avatar.png" } } ]}หมายเหตุ:
- ผลลัพธ์จะส่งคืนตามลำดับความเกี่ยวข้อง (ความคล้ายคลึงของ embedding + การเพิ่มคะแนนจากโทเค็น slug/ชื่อที่ตรงกันทั้งหมด + ค่าน้ำหนักความนิยมเล็กน้อย)
- ความเกี่ยวข้องมีน้ำหนักมากกว่าความนิยม การตรงกับโทเค็น slug หรือชื่อที่แสดงอย่างแม่นยำอาจมีอันดับสูงกว่าการตรงแบบหลวมที่มีการมีส่วนร่วมสูงกว่ามาก
- ข้อความ ASCII จะถูกแยกเป็นโทเค็นตามขอบเขตคำและเครื่องหมายวรรคตอน ตัวอย่างเช่น
personal-mapมีโทเค็นmapที่แยกเดี่ยว ขณะที่amap-jsapi-skillมีamap,jsapiและskill; ดังนั้นการค้นหาmapจึงทำให้personal-mapตรงกันในเชิงคำศัพท์มากกว่าamap-jsapi-skill - ความนิยมจะถูกปรับด้วยลอการิทึมและจำกัดเพดาน Skills ที่มีการมีส่วนร่วมสูงอาจมีอันดับต่ำกว่าเมื่อข้อความค้นหาตรงกันน้อยกว่า
- สถานะการกลั่นกรองว่าน่าสงสัยหรือซ่อนอยู่อาจทำให้ Skill ถูกนำออกจากการค้นหาสาธารณะ โดยขึ้นอยู่กับตัวกรองของผู้เรียกและสถานะการกลั่นกรองปัจจุบัน
คำแนะนำด้านการค้นพบสำหรับผู้เผยแพร่:
- ใส่คำที่ผู้ใช้จะค้นหาตามตัวอักษรไว้ในชื่อที่แสดง สรุป และแท็ก ใช้โทเค็น slug แบบแยกเดี่ยวเฉพาะเมื่อเป็นอัตลักษณ์ที่เสถียรซึ่งต้องการเก็บไว้ด้วย
- อย่าเปลี่ยนชื่อ slug เพียงเพื่อไล่ตามคำค้นหาเดียว เว้นแต่ slug ใหม่จะเป็นชื่อหลักระยะยาวที่ดีกว่า slug เก่าจะกลายเป็นนามแฝงเปลี่ยนเส้นทาง แต่ URL หลัก slug ที่แสดง และข้อมูลสรุปการค้นหาในอนาคตจะใช้ slug ใหม่
- นามแฝงจากการเปลี่ยนชื่อยังคงรองรับการแก้ไข URL เก่าและการติดตั้งที่แก้ไขผ่านรีจิสทรี แต่การจัดอันดับการค้นหาจะอิงตามข้อมูลเมตา Skill หลักหลังการเปลี่ยนชื่อถูกจัดทำดัชนีแล้ว สถิติเดิมจะยังคงอยู่กับ Skill
- หาก Skill มองไม่เห็นโดยไม่คาดคิด ให้ตรวจสอบสถานะการกลั่นกรองก่อนด้วย
clawhub inspect @owner/slugขณะเข้าสู่ระบบ ก่อนเปลี่ยนข้อมูลเมตาที่เกี่ยวข้องกับการจัดอันดับ
GET /api/v1/skills
พารามิเตอร์การค้นหา:
limit(ไม่บังคับ): จำนวนเต็ม (1–200)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้าสำหรับการเรียงลำดับที่ไม่ใช่trendingsort(ไม่บังคับ):updated(ค่าเริ่มต้น),recommended(นามแฝง:default),createdAt(นามแฝง:newest),downloads,stars(นามแฝง:rating), นามแฝงการติดตั้งแบบเดิมinstallsCurrent/installs/installsAllTimeแมปไปยังdownloads,trendingnonSuspiciousOnly(ไม่บังคับ):trueเพื่อซ่อน Skills ที่น่าสงสัย (flagged.suspicious)nonSuspicious(ไม่บังคับ): นามแฝงแบบเดิมสำหรับnonSuspiciousOnly
ค่า sort ที่ไม่ถูกต้องจะส่งคืน 400
หมายเหตุ:
recommendedใช้สัญญาณการมีส่วนร่วมและความใหม่trendingจัดอันดับตามจำนวนการติดตั้งในช่วง 7 วันที่ผ่านมา (อิงตามข้อมูลเทเลเมทรี)createdAtมีความเสถียรสำหรับการรวบรวมข้อมูล Skill ใหม่;updatedจะเปลี่ยนเมื่อ Skills เดิมได้รับการเผยแพร่ซ้ำ- เมื่อ
nonSuspiciousOnly=trueการเรียงลำดับแบบใช้เคอร์เซอร์อาจส่งคืนรายการในหนึ่งหน้าน้อยกว่าlimitเนื่องจาก Skills ที่น่าสงสัยจะถูกกรองหลังจากดึงข้อมูลหน้าแล้ว - ใช้
nextCursorเพื่อแบ่งหน้าต่อเมื่อมีค่า หน้าที่มีรายการน้อยไม่ได้หมายความว่าผลลัพธ์สิ้นสุดแล้วเสมอไป
การตอบกลับ:
{ "items": [ { "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "topics": ["Productivity"], "tags": { "latest": "1.2.3" }, "stats": {}, "createdAt": 0, "updatedAt": 0, "latestVersion": { "version": "1.2.3", "createdAt": 0, "changelog": "…" }, "metadata": { "os": ["macos"], "systems": ["aarch64-darwin"] } } ], "nextCursor": null}GET /api/v1/skills/{slug}
การตอบกลับ:
{ "skill": { "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "topics": ["Productivity"], "tags": { "latest": "1.2.3" }, "stats": {}, "createdAt": 0, "updatedAt": 0 }, "latestVersion": { "version": "1.2.3", "createdAt": 0, "changelog": "…" }, "metadata": { "os": ["macos"], "systems": ["aarch64-darwin"] }, "owner": { "handle": "steipete", "displayName": "Peter", "image": null }, "moderation": { "isSuspicious": false, "isMalwareBlocked": false, "verdict": "clean", "reasonCodes": [], "summary": null, "engineVersion": "v2.0.0", "updatedAt": 0 }}หมายเหตุ:
- slug เก่าที่สร้างโดยขั้นตอนการเปลี่ยนชื่อ/ผสานของเจ้าของจะแก้ไขไปยัง Skill หลัก
metadata.os: ข้อจำกัดระบบปฏิบัติการที่ประกาศใน frontmatter ของ Skill (เช่น["macos"],["linux"]) เป็นnullหากไม่ได้ประกาศmetadata.systems: เป้าหมายระบบ Nix (เช่น["aarch64-darwin", "x86_64-linux"]) เป็นnullหากไม่ได้ประกาศmetadataเป็นnullหาก Skill ไม่มีข้อมูลเมตาแพลตฟอร์ม- จะรวม
moderationเฉพาะเมื่อ Skill ถูกทำเครื่องหมายหรือเจ้าของกำลังดู Skill นั้น
GET /api/v1/skills/{slug}/moderation
ส่งคืนสถานะการกลั่นกรองแบบมีโครงสร้าง
การตอบกลับ:
{ "moderation": { "isSuspicious": true, "isMalwareBlocked": false, "verdict": "suspicious", "reasonCodes": ["suspicious.dynamic_code_execution"], "summary": "ตรวจพบ: suspicious.dynamic_code_execution", "engineVersion": "v2.0.0", "updatedAt": 0, "legacyReason": null, "evidence": [ { "code": "suspicious.dynamic_code_execution", "severity": "critical", "file": "index.ts", "line": 3, "message": "ตรวจพบการเรียกใช้โค้ดแบบไดนามิก", "evidence": "" } ] }}หมายเหตุ:
- เจ้าของและผู้ดูแลสามารถเข้าถึงรายละเอียดการกลั่นกรองสำหรับ Skills ที่ซ่อนอยู่
- ผู้เรียกสาธารณะจะได้รับเฉพาะ
200สำหรับ Skills ที่มองเห็นและถูกทำเครื่องหมายไว้แล้ว - หลักฐานจะถูกปกปิดสำหรับผู้เรียกสาธารณะ และจะรวมข้อความดิบเฉพาะสำหรับเจ้าของ/ผู้ดูแล
POST /api/v1/skills/{slug}/report
รายงาน Skill เพื่อให้ผู้ดูแลตรวจสอบ รายงานมีขอบเขตระดับ Skill สามารถเชื่อมโยง กับเวอร์ชันได้โดยไม่บังคับ และจะถูกส่งเข้าสู่คิวรายงาน Skill
การยืนยันตัวตน:
- ต้องใช้โทเค็น API
คำขอ:
{ "reason": "ขั้นตอนการติดตั้งที่น่าสงสัย", "version": "1.2.3" }การตอบกลับ:
{ "ok": true, "reported": true, "alreadyReported": false, "reportId": "skillReports:...", "skillId": "skills:...", "reportCount": 1}GET /api/v1/skills/-/reports
เอนด์พอยต์สำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อรับรายงาน Skill
พารามิเตอร์การค้นหา:
status(ไม่บังคับ):open(ค่าเริ่มต้น),confirmed,dismissedหรือalllimit(ไม่บังคับ): จำนวนเต็ม (1-200)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
การตอบกลับ:
{ "items": [ { "reportId": "skillReports:...", "skillId": "skills:...", "skillVersionId": "skillVersions:...", "slug": "gifgrep", "displayName": "GifGrep", "version": "1.2.3", "reason": "ขั้นตอนการติดตั้งน่าสงสัย", "status": "open", "createdAt": 1730000000000, "reporter": { "userId": "users:...", "handle": "reporter", "displayName": "ผู้รายงาน" }, "triagedAt": null, "triagedBy": null, "triageNote": null } ], "nextCursor": null, "done": true}POST /api/v1/skills/-/reports/{reportId}/triage
ปลายทางสำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อดำเนินการหรือเปิดรายงาน Skills อีกครั้ง
คำขอ:
{ "status": "confirmed", "note": "ตรวจสอบและซ่อนเวอร์ชันที่ได้รับผลกระทบแล้ว", "finalAction": "hide" }จำเป็นต้องระบุ note สำหรับ confirmed และ dismissed; สามารถละเว้นได้เมื่อตั้งค่า
status กลับเป็น open ส่ง finalAction: "hide" พร้อมกับรายงานที่คัดกรองแล้ว
เพื่อซ่อน Skills ภายในเวิร์กโฟลว์เดียวกันที่ตรวจสอบย้อนหลังได้
GET /api/v1/skills/{slug}/versions
พารามิเตอร์การสืบค้น:
limit(ไม่บังคับ): จำนวนเต็มcursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
GET /api/v1/skills/{slug}/versions/{version}
ส่งคืนข้อมูลเมตาของเวอร์ชันและรายการไฟล์
version.securityมีสถานะการยืนยันผลการสแกนที่ปรับให้เป็นมาตรฐานและรายละเอียดของเครื่องสแกน (VirusTotal + LLM) เมื่อมีข้อมูล
GET /api/v1/skills/{slug}/scan
ส่งคืนรายละเอียดการยืนยันผลการสแกนความปลอดภัยสำหรับเวอร์ชันของ Skills
พารามิเตอร์การสืบค้น:
version(ไม่บังคับ): สตริงเวอร์ชันที่เจาะจงtag(ไม่บังคับ): แปลงแท็กเป็นเวอร์ชัน (ตัวอย่างเช่นlatest)
หมายเหตุ:
- หากไม่ได้ระบุทั้ง
versionและtagระบบจะใช้เวอร์ชันล่าสุด - ประกอบด้วยสถานะการยืนยันที่ปรับให้เป็นมาตรฐานและรายละเอียดเฉพาะของเครื่องสแกน
security.hasScanResultจะเป็นtrueเฉพาะเมื่อเครื่องสแกนให้ผลการตัดสินที่ชัดเจน (clean,suspiciousหรือmalicious)moderationคือสแนปช็อตการดูแลระดับ Skills ในปัจจุบันที่ได้มาจากเวอร์ชันล่าสุด- เมื่อสืบค้นเวอร์ชันในอดีต ให้ตรวจสอบ
moderation.matchesRequestedVersionและmoderation.sourceVersionก่อนถือว่าmoderationและsecurityอยู่ในบริบทเวอร์ชันเดียวกัน
POST /api/v1/skills/-/scan
ปลายทางส่งงานที่ต้องยืนยันตัวตนสำหรับงาน ClawScan ใหม่
ระบบไม่รองรับการสแกนไฟล์อัปโหลดในเครื่องอีกต่อไป คำขอที่ใช้
multipart/form-data หรือ { "source": { "kind": "upload" } } จะส่งคืน 410
การสแกนรายการที่เผยแพร่แล้วใช้ JSON:
{ "source": { "kind": "published", "slug": "gifgrep", "version": "1.2.3" }, "update": false}หมายเหตุ:
- เพย์โหลดคำขอสแกนและรายงานที่ดาวน์โหลดได้จะหมดอายุและถูกนำออกจากที่จัดเก็บคำขอสแกนหลังพ้นระยะเวลาเก็บรักษา
- การสแกนรายการที่เผยแพร่แล้วต้องมีสิทธิ์จัดการในฐานะเจ้าของ/ผู้เผยแพร่ หรืออำนาจผู้ดูแล/ผู้ดูแลระบบของแพลตฟอร์ม
- การสแกนรายการที่เผยแพร่แล้วจะเขียนผลกลับเฉพาะเมื่อ
update: trueและการสแกนเสร็จสมบูรณ์ - การตอบกลับคือ
202พร้อม{ "ok": true, "scanId": "...", "jobId": "...", "status": "queued", "sourceKind": "published", "update": false, "queue": { "queuedAhead": 0, "queuedAheadIsEstimate": false, "position": 1, "running": 0, "runningIsEstimate": false, "note": "Scans are asynchronous and may take time to complete." } } - งานสแกนทำงานแบบอะซิงโครนัส คำขอสแกนด้วยตนเองจะได้รับลำดับความสำคัญก่อนงานเผยแพร่/เติมข้อมูลย้อนหลังตามปกติ แต่การเสร็จสิ้นยังคงขึ้นอยู่กับความพร้อมของเวิร์กเกอร์
GET /api/v1/skills/-/scan/{scanId}
ปลายทางสำรวจสถานะที่ต้องยืนยันตัวตนสำหรับงานสแกนที่ส่งแล้ว
- ส่งคืนสถานะเข้าคิว/กำลังทำงาน/สำเร็จ/ล้มเหลว
- ส่งคืน
queue.queuedAheadและqueue.positionขณะอยู่ในคิว เพื่อให้ไคลเอนต์แสดงจำนวนการสแกนด้วยตนเองที่จัดลำดับความสำคัญและอยู่ก่อนหน้าคำขอนี้ได้ คิวขนาดใหญ่มากจะถูกจำกัดและรายงานด้วยqueuedAheadIsEstimate: true - เมื่อมีข้อมูล
reportจะประกอบด้วยส่วนclawscan,skillspector,staticAnalysisและvirustotal - งานสแกนที่ล้มเหลวจะส่งคืน
status: "failed"พร้อมlastError
GET /api/v1/skills/-/scan/{scanId}/download
ปลายทางคลังรายงานที่ต้องยืนยันตัวตน
- ต้องเป็นการสแกนที่สำเร็จแล้ว การสแกนที่ยังไม่สิ้นสุดจะส่งคืน
409 - ส่งคืนไฟล์ ZIP ที่มี
manifest.json,clawscan.json,skillspector.json,static-analysis.json,virustotal.jsonและREADME.md
GET /api/v1/skills/-/scan/download/{name}?version=<version>&kind=skill|plugin
ปลายทางคลังรายงานที่จัดเก็บไว้และต้องยืนยันตัวตนสำหรับเวอร์ชันที่ส่งแล้ว
- ต้องมีสิทธิ์จัดการ Skills หรือ Plugin ในฐานะเจ้าของ/ผู้เผยแพร่ หรืออำนาจผู้ดูแล/ผู้ดูแลระบบของแพลตฟอร์ม
- ส่งคืนผลการสแกนที่จัดเก็บไว้สำหรับเวอร์ชันที่ส่งอย่างตรงกัน รวมถึงเวอร์ชันที่ถูกบล็อกหรือซ่อน
kindมีค่าเริ่มต้นเป็นskill; ใช้kind=pluginสำหรับการสแกน Plugin/แพ็กเกจ- ส่งคืน ZIP ที่มีโครงสร้างเดียวกับการดาวน์โหลดคำขอสแกน
POST /api/v1/skills/-/scan/batch
เส้นทางสแกนซ้ำแบบกลุ่มมาตรฐานสำหรับผู้ดูแลระบบเท่านั้น โดยรับเพย์โหลดรูปแบบเดียวกับ POST /api/v1/skills/-/rescan-batch แบบเดิม
POST /api/v1/skills/-/scan/batch/status
เส้นทางสถานะแบบกลุ่มมาตรฐานสำหรับผู้ดูแลระบบเท่านั้น โดยรับ { "jobIds": ["..."] } และส่งคืนตัวนับรวมแบบเดียวกับ POST /api/v1/skills/-/rescan-batch/status แบบเดิม
GET /api/v1/skills/{slug}/verify
ส่งคืนเอนเวโลปการยืนยัน Skill Card ที่ clawhub skill verify ใช้
พารามิเตอร์การสืบค้น:
version(ไม่บังคับ): สตริงเวอร์ชันที่เจาะจงtag(ไม่บังคับ): แปลงแท็กเป็นเวอร์ชัน (ตัวอย่างเช่นlatest)
หมายเหตุ:
okจะเป็นtrueเฉพาะเมื่อเวอร์ชันที่เลือกมี Skill Card ที่สร้างแล้ว ไม่ถูกการดูแลบล็อกว่าเป็นมัลแวร์ และการยืนยัน ClawScan ระบุว่าสะอาด- ข้อมูลประจำตัวของ Skills ข้อมูลประจำตัวของผู้เผยแพร่ และข้อมูลเมตาของเวอร์ชันที่เลือกเป็นฟิลด์ระดับบนสุดของเอนเวโลป (
slug,displayName,publisherHandle,version,resolvedFrom,tag,createdAt) เพื่อให้ระบบอัตโนมัติของเชลล์อ่านได้โดยไม่ต้องแกะตัวห่อหุ้มที่ซ้อนกัน securityคือผลการตัดสิน ClawScan/ความปลอดภัยระดับบนสุด ระบบอัตโนมัติควรอ้างอิงok,decision,reasonsและsecurity.statussecurity.signalsมีหลักฐานสนับสนุนจากเครื่องสแกน เช่นstaticScan,virusTotalและskillSpector- ยังคงเก็บ
security.signals.dependencyRegistryไว้เพื่อความเข้ากันได้กับการตอบกลับ v1 แต่เครื่องสแกนตรวจสอบการมีอยู่ในรีจิสทรีของการขึ้นต่อกันได้ยุติการใช้งานแล้ว และคีย์นี้จะเป็นnullเสมอ provenanceจะเป็นserver-resolved-github-importเฉพาะเมื่อ ClawHub แปลงและจัดเก็บรีโพ GitHub/ref/คอมมิต/พาธระหว่างการเผยแพร่หรือนำเข้า มิฉะนั้นจะเป็นunavailable
POST /api/v1/skills/-/security-verdicts
ส่งคืนผลการตัดสินด้านความปลอดภัยแบบย่อในปัจจุบันสำหรับเวอร์ชันของ Skills ที่ตรงกัน ปลายทาง คอลเลกชันนี้มีไว้สำหรับไคลเอนต์ที่ทราบอยู่แล้วว่าต้องแสดง Skills ของ ClawHub เวอร์ชันใดที่ติดตั้งไว้ เช่น OpenClaw Control UI
คำขอ:
{ "items": [{ "slug": "gifgrep", "version": "1.2.3" }]}หมายเหตุ:
itemsต้องมีคู่{ slug, version }ที่ไม่ซ้ำกัน 1-100 คู่- ผลลัพธ์แยกตามแต่ละรายการ การไม่พบ Skills หรือเวอร์ชันหนึ่งรายการจะไม่ทำให้การตอบกลับทั้งหมดล้มเหลว
- การตอบกลับมีเฉพาะข้อมูลความปลอดภัย โดยไม่มีข้อมูล Skill Card สถานะการสร้างการ์ด รายการไฟล์อาร์ติแฟกต์ หรือเพย์โหลดโดยละเอียดของเครื่องสแกน
security.signalsมีเฉพาะหลักฐานสนับสนุนระดับสถานะ ใช้/scanหรือหน้าตรวจสอบความปลอดภัยของ ClawHub สำหรับรายละเอียดทั้งหมดของเครื่องสแกน- ยังคงเก็บ
security.signals.dependencyRegistryไว้เพื่อความเข้ากันได้กับการตอบกลับ v1 แต่เครื่องสแกนตรวจสอบการมีอยู่ในรีจิสทรีของการขึ้นต่อกันได้ยุติการใช้งานแล้ว และคีย์นี้จะเป็นnullเสมอ - การไม่มี Skill Card ไม่ส่งผลต่อ
ok,decisionหรือreasonsของปลายทางนี้ ไคลเอนต์ควรอ่านskill-card.mdที่ติดตั้งไว้ภายในเครื่องเมื่อต้องการเนื้อหาการ์ด - ใช้
/verifyเมื่อต้องการเอนเวโลปการยืนยัน Skill Card สำหรับ Skills เดียว ใช้/cardเมื่อต้องการ Markdown ของการ์ดที่สร้างแล้ว และใช้/scanเมื่อต้องการข้อมูลโดยละเอียดของเครื่องสแกน
การตอบกลับ:
{ "schema": "clawhub.skill.security-verdicts.v1", "items": [ { "ok": true, "decision": "pass", "reasons": [], "requestedSlug": "gifgrep", "slug": "gifgrep", "displayName": "GifGrep", "publisherHandle": "steipete", "publisherDisplayName": "Peter", "requestedVersion": "1.2.3", "version": "1.2.3", "createdAt": 0, "checkedAt": 0, "skillUrl": "https://clawhub.ai/steipete/skills/gifgrep", "securityAuditUrl": "https://clawhub.ai/steipete/skills/gifgrep/security-audit?version=1.2.3", "security": { "status": "clean", "passed": true, "signals": { "staticScan": { "status": "clean", "reasonCodes": [] }, "virusTotal": null, "skillSpector": null, "dependencyRegistry": null } } }, { "ok": false, "decision": "fail", "reasons": ["version.not_found"], "requestedSlug": "missing-version", "requestedVersion": "1.0.0", "error": { "code": "version_not_found", "message": "ไม่พบเวอร์ชัน" }, "security": null } ]}GET /api/v1/skills/{slug}/file
ส่งคืนไบต์ของไฟล์ที่จัดเก็บไว้อย่างตรงกันในรูปแบบการดาวน์โหลด เพิ่ม preview=1 เพื่อขอตัวอย่างข้อความแบบเอสเคปที่มีขนาดจำกัด
สามารถดูตัวอย่างไฟล์ใดก็ได้ที่มีไบต์ UTF-8 ที่ถูกต้อง โดยไม่ขึ้นอยู่กับนามสกุลหรือข้อมูลเมตา
MIME ของไฟล์
พารามิเตอร์การสืบค้น:
path(จำเป็น)version(ไม่บังคับ)tag(ไม่บังคับ)preview=1(ไม่บังคับ; ส่งคืนtext/plainหรือ415เมื่อไบต์ไม่ใช่ UTF-8 ที่ถูกต้อง)
หมายเหตุ:
- ค่าเริ่มต้นคือเวอร์ชันล่าสุด
- ขีดจำกัดการดาวน์โหลดข้อมูลดิบ: 10MB
- ขีดจำกัดตัวอย่างข้อความ: 200KB
GET /api/v1/packages
ปลายทางแค็ตตาล็อกแบบรวมสำหรับ:
- Skills
- Plugin โค้ด
- Plugin แบบบันเดิล
พารามิเตอร์การสืบค้น:
limit(ไม่บังคับ): จำนวนเต็ม (1–100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้าfamily(ไม่บังคับ):skill,code-pluginหรือbundle-pluginchannel(ไม่บังคับ):official,communityหรือprivateisOfficial(ไม่บังคับ):trueหรือfalsesort(ไม่บังคับ):updated(ค่าเริ่มต้น),recommended,trending,downloads, นามแฝงแบบเดิมinstallscategory(ไม่บังคับ): ตัวกรองหมวดหมู่ Plugin รองรับเฉพาะเมื่อ คำขอจำกัดขอบเขตไว้ที่แพ็กเกจ Plugin (/api/v1/plugins,/api/v1/code-plugins,/api/v1/bundle-pluginsหรือปลายทางแพ็กเกจที่มีfamily=code-plugin/family=bundle-plugin) หมวดหมู่ที่ควบคุมและ นามแฝงตัวกรอง v1 แบบเดิมมีเอกสารอยู่ในGET /api/v1/plugins
หมายเหตุ:
- ค่าที่ไม่ถูกต้องสำหรับ
family,channel,isOfficial,featured,highlightedOnlyหรือsortจะส่งคืน400ระบบจะละเว้นพารามิเตอร์การสืบค้นที่ไม่รู้จัก GET /api/v1/code-pluginsและGET /api/v1/bundle-pluginsยังคงเป็นนามแฝงของตระกูลแบบคงที่- รายการ Skills ยังคงอ้างอิงรีจิสทรีของ Skills และยังเผยแพร่ได้ผ่าน
POST /api/v1/skillsเท่านั้น POST /api/v1/packagesยังคงใช้สำหรับรุ่นของ Plugin โค้ดและ Plugin แบบบันเดิลเท่านั้น- ผู้เรียกแบบไม่ระบุตัวตนจะเห็นเฉพาะช่องทางแพ็กเกจสาธารณะ
- ผู้เรียกที่ยืนยันตัวตนแล้วสามารถเห็นแพ็กเกจส่วนตัวของผู้เผยแพร่ที่ตนสังกัดในผลลัพธ์รายการ/การค้นหา
channel=privateจะส่งคืนเฉพาะแพ็กเกจที่ผู้เรียกซึ่งยืนยันตัวตนแล้วมีสิทธิ์อ่าน
GET /api/v1/packages/search
การค้นหาแค็ตตาล็อกแบบรวมสำหรับ Skills และแพ็กเกจ Plugin
พารามิเตอร์การสืบค้น:
q(จำเป็น): สตริงคำค้นlimit(ไม่บังคับ): จำนวนเต็ม (1–100)family(ไม่บังคับ):skill,code-pluginหรือbundle-pluginchannel(ไม่บังคับ):official,communityหรือprivateisOfficial(ไม่บังคับ):trueหรือfalsecategory(ไม่บังคับ): ตัวกรองหมวดหมู่ Plugin รองรับเฉพาะเมื่อ คำขอจำกัดขอบเขตไว้ที่แพ็กเกจ Plugin หมวดหมู่ที่ควบคุมและนามแฝงตัวกรอง v1 แบบเดิมมีเอกสารอยู่ในGET /api/v1/plugins
หมายเหตุ:
- ค่าที่ไม่ถูกต้องสำหรับ
family,channel,isOfficial,featuredหรือhighlightedOnlyจะส่งคืน400ระบบจะละเว้นพารามิเตอร์คำค้นที่ไม่รู้จัก - ผู้เรียกแบบไม่ระบุตัวตนจะเห็นเฉพาะช่องทางแพ็กเกจสาธารณะ
- ผู้เรียกที่ผ่านการตรวจสอบสิทธิ์สามารถค้นหาแพ็กเกจส่วนตัวของผู้เผยแพร่ที่ตนสังกัดอยู่
channel=privateจะส่งคืนเฉพาะแพ็กเกจที่ผู้เรียกซึ่งผ่านการตรวจสอบสิทธิ์มีสิทธิ์อ่าน
GET /api/v1/plugins
การเรียกดูแค็ตตาล็อกเฉพาะ Plugin ครอบคลุมแพ็กเกจ Plugin แบบโค้ดและ Plugin แบบบันเดิล
พารามิเตอร์คำค้น:
limit(ไม่บังคับ): จำนวนเต็ม (1-100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้าisOfficial(ไม่บังคับ):trueหรือfalsesort(ไม่บังคับ):recommended(ค่าเริ่มต้น),trending,downloads,updated, นามแฝงแบบเดิมinstallscategory(ไม่บังคับ): ตัวกรองหมวดหมู่ Plugin ค่าปัจจุบัน:channels,models,memory,context,voice,media,web,tools,runtime,gateway,security,other
ปลายทางการอ่านยังคงยอมรับนามแฝงตัวกรอง v1 แบบเดิม:
mcp-tooling,dataและautomationจะแปลงเป็นtoolsobservabilityและdeploymentจะแปลงเป็นgatewaydev-toolsจะแปลงเป็นruntime
trending เป็นตารางจัดอันดับการติดตั้ง/ดาวน์โหลดในช่วงเจ็ดวัน และไม่ใช้ยอดรวมตลอดเวลา
ในปลายทางรวม /api/v1/packages ค่านี้ใช้ได้เฉพาะ Plugin ให้ใช้
/api/v1/skills?sort=trending สำหรับแค็ตตาล็อก Skills
ระบบไม่ยอมรับนามแฝงแบบเดิมเป็นค่าหมวดหมู่ที่จัดเก็บหรือที่ผู้เขียนประกาศ
GET /api/v1/skills/export
การส่งออก Skills สาธารณะเวอร์ชันล่าสุดจำนวนมากสำหรับการวิเคราะห์แบบออฟไลน์
การตรวจสอบสิทธิ์:
- จำเป็นต้องใช้โทเค็น API
พารามิเตอร์คำค้น:
startDate(จำเป็น): ขอบเขตล่างเป็นมิลลิวินาที Unix สำหรับupdatedAtของ SkillendDate(จำเป็น): ขอบเขตบนเป็นมิลลิวินาที Unix สำหรับupdatedAtของ Skilllimit(ไม่บังคับ): จำนวนเต็ม (1-250), ค่าเริ่มต้น250cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้าจากการตอบกลับก่อนหน้า
การตอบกลับ:
- เนื้อหา: ไฟล์เก็บถาวร ZIP
- Skill ที่ส่งออกแต่ละรายการมีรากอยู่ที่
{publisher}/{slug}/ - Skills ที่โฮสต์ไว้จะมีไฟล์เวอร์ชันล่าสุดที่จัดเก็บ และแสดงรายการใน
_manifest.jsonพร้อมsourceRef: "public-clawhub" - Skills ปัจจุบันที่ใช้ GitHub เป็นแหล่งข้อมูลและมีการสแกน
cleanหรือsuspiciousจะมี_source_handoff.jsonพร้อมsourceRef: "public-github", ที่เก็บ, คอมมิต, พาธ, แฮชเนื้อหา และ URL ไฟล์เก็บถาวร โดยจะไม่มีไฟล์ต้นฉบับที่โฮสต์บน ClawHub - Skill แต่ละรายการมี
_export_skill_meta.json - ZIP จะมี
_manifest.jsonที่ระดับรากเสมอ - ระบบจะรวม
_errors.jsonเมื่อไม่สามารถ ส่งออก Skills หรือไฟล์บางรายการได้
ส่วนหัว:
X-Next-CursorX-Has-MoreX-Total-ReturnedX-Date-RangeX-Export-Errors
GET /api/v1/plugins/export
การส่งออกรีลีส Plugin สาธารณะเวอร์ชันล่าสุดจำนวนมากสำหรับการวิเคราะห์แบบออฟไลน์
การตรวจสอบสิทธิ์:
- จำเป็นต้องใช้โทเค็น API
พารามิเตอร์คำค้น:
startDate(จำเป็น): ขอบเขตล่างเป็นมิลลิวินาที Unix สำหรับupdatedAtของ PluginendDate(จำเป็น): ขอบเขตบนเป็นมิลลิวินาที Unix สำหรับupdatedAtของ Pluginlimit(ไม่บังคับ): จำนวนเต็ม (1-250), ค่าเริ่มต้น250cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้าจากการตอบกลับก่อนหน้าfamily(ไม่บังคับ):code-pluginหรือbundle-pluginหากละไว้จะหมายถึง Plugin ทั้งสองตระกูล
การตอบกลับ:
- เนื้อหา: ไฟล์เก็บถาวร ZIP
- Plugin ที่ส่งออกแต่ละรายการมีรากอยู่ที่
{family}/{packageName}/ - Plugin ที่ส่งออกแต่ละรายการมีไฟล์ที่จัดเก็บของรีลีสล่าสุด
- ข้อมูลเมตาการส่งออกของแต่ละ Plugin จัดเก็บไว้ที่
__clawhub_export/{family}/{packageName}/plugin_meta.json - ZIP จะมี
_manifest.jsonที่ระดับรากเสมอ - ระบบจะรวม
_errors.jsonเมื่อไม่สามารถ ส่งออก Plugin หรือไฟล์บางรายการได้
ส่วนหัว:
X-Next-CursorX-Has-MoreX-Total-ReturnedX-Date-RangeX-Export-Errors
GET /api/v1/plugins/search
การค้นหาเฉพาะ Plugin ครอบคลุมแพ็กเกจ Plugin แบบโค้ดและ Plugin แบบบันเดิล
พารามิเตอร์คำค้น:
q(จำเป็น): สตริงคำค้นlimit(ไม่บังคับ): จำนวนเต็ม (1-100)isOfficial(ไม่บังคับ):trueหรือfalsecategory(ไม่บังคับ): ตัวกรองหมวดหมู่ Plugin ค่าปัจจุบัน:channels,models,memory,context,voice,media,web,tools,runtime,gateway,security,other
หมายเหตุ:
- ระบบยอมรับนามแฝงตัวกรอง v1 แบบเดิมที่มีเอกสารอยู่ใน
GET /api/v1/pluginsเช่นกัน - การกรองหมวดหมู่เป็นตัวกรอง API จริงที่อิงกับแถวไดเจสต์หมวดหมู่ Plugin ไม่ใช่การเขียนคำค้นใหม่
- ระบบส่งคืนผลลัพธ์ตามลำดับความเกี่ยวข้อง และปัจจุบันไม่มีการแบ่งหน้า
- ตัวควบคุมการเรียงลำดับใน UI ของเบราว์เซอร์สำหรับการค้นหา Plugin จะจัดลำดับผลลัพธ์ความเกี่ยวข้องที่โหลดแล้วใหม่
ซึ่งตรงกับลักษณะการเรียกดู
/skillsในปัจจุบัน
GET /api/v1/packages/{name}
ส่งคืนข้อมูลเมตารายละเอียดแพ็กเกจ
หมายเหตุ:
- Skills สามารถแก้ไขผ่านเส้นทางนี้ในแค็ตตาล็อกรวมได้เช่นกัน
- แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกมีสิทธิ์อ่านผู้เผยแพร่ที่เป็นเจ้าของ
DELETE /api/v1/packages/{name}
ลบแพ็กเกจและรีลีสทั้งหมดแบบซอฟต์
หมายเหตุ:
- ต้องใช้โทเค็น API ของเจ้าของแพ็กเกจ เจ้าของ/ผู้ดูแลระบบขององค์กรผู้เผยแพร่ ผู้ควบคุมแพลตฟอร์ม หรือผู้ดูแลระบบแพลตฟอร์ม
GET /api/v1/packages/{name}/versions
ส่งคืนประวัติเวอร์ชัน
พารามิเตอร์คำค้น:
limit(ไม่บังคับ): จำนวนเต็ม (1–100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
หมายเหตุ:
- แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกมีสิทธิ์อ่านผู้เผยแพร่ที่เป็นเจ้าของ
GET /api/v1/packages/{name}/versions/{version}
ส่งคืนแพ็กเกจหนึ่งเวอร์ชัน รวมถึงข้อมูลเมตาของไฟล์ ความเข้ากันได้ การตรวจสอบยืนยัน ข้อมูลเมตาของอาร์ติแฟกต์ และข้อมูลการสแกน
หมายเหตุ:
version.artifact.kindคือlegacy-zipสำหรับไฟล์เก็บถาวรแพ็กเกจแบบเดิม หรือnpm-packสำหรับรีลีสที่ใช้ ClawPack- รีลีส ClawPack มีฟิลด์
npmIntegrity,npmShasumและnpmTarballNameที่เข้ากันได้กับ npm version.sha256hashเป็นข้อมูลเมตาความเข้ากันได้ที่เลิกแนะนำแล้วสำหรับไคลเอนต์รุ่นเก่า โดย แฮชไบต์ ZIP ที่ตรงกับข้อมูลที่/api/v1/packages/{name}/downloadส่งคืนทุกประการ ไคลเอนต์สมัยใหม่ควรใช้version.artifact.sha256ซึ่งระบุ อาร์ติแฟกต์รีลีสหลัก- ระบบจะรวม
version.vtAnalysis,version.llmAnalysisและversion.staticScanเมื่อมีข้อมูลการสแกน - แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกมีสิทธิ์อ่านผู้เผยแพร่ที่เป็นเจ้าของ
GET /api/v1/packages/{name}/versions/{version}/security
ส่งคืนข้อมูลสรุปความปลอดภัยและความน่าเชื่อถือของรีลีสแพ็กเกจที่ตรงกันทุกประการสำหรับไคลเอนต์ การติดตั้ง นี่คือพื้นผิวการใช้งานสาธารณะของ OpenClaw สำหรับตัดสินว่า สามารถติดตั้งรีลีสที่แก้ไขแล้วได้หรือไม่
การตรวจสอบสิทธิ์:
- ปลายทางอ่านสาธารณะ ไม่จำเป็นต้องใช้โทเค็นของเจ้าของ ผู้เผยแพร่ ผู้ควบคุม หรือผู้ดูแลระบบ
การตอบกลับ:
{ "package": { "name": "@openclaw/example-plugin", "displayName": "Example Plugin", "family": "code-plugin" }, "release": { "releaseId": "packageReleases:...", "version": "1.2.3", "artifactKind": "npm-pack", "artifactSha256": "0123456789abcdef...", "npmIntegrity": "sha512-...", "npmShasum": "0123456789abcdef0123456789abcdef01234567", "npmTarballName": "example-plugin-1.2.3.tgz", "createdAt": 1730000000000 }, "trust": { "scanStatus": "malicious", "moderationState": "quarantined", "blockedFromDownload": true, "reasons": ["manual:quarantined", "scan:malicious"], "pending": false, "stale": false }}ฟิลด์การตอบกลับ:
package.name,package.displayNameและpackage.familyระบุ แพ็กเกจรีจิสทรีที่แก้ไขแล้วrelease.releaseId,release.versionและrelease.createdAtระบุ รีลีสที่ได้รับการประเมินอย่างเจาะจงrelease.artifactKind,release.artifactSha256,release.npmIntegrity,release.npmShasumและrelease.npmTarballNameจะปรากฏเมื่อทราบค่าสำหรับ อาร์ติแฟกต์รีลีสtrust.scanStatusคือสถานะความน่าเชื่อถือที่มีผล ซึ่งได้มาจากอินพุตของเครื่องสแกน และการควบคุมรีลีสด้วยตนเองtrust.moderationStateเป็นค่าว่างได้ โดยเป็นnullเมื่อไม่มีการควบคุมรีลีส ด้วยตนเองtrust.blockedFromDownloadคือสัญญาณบล็อกการติดตั้ง OpenClaw และไคลเอนต์ การติดตั้งอื่นควรบล็อกการติดตั้งเมื่อค่านี้เป็นtrueแทนที่จะ คำนวณกฎการบล็อกใหม่จากฟิลด์เครื่องสแกนหรือการควบคุมtrust.reasonsคือรายการคำอธิบายสำหรับผู้ใช้และการตรวจสอบ รหัสเหตุผล เป็นสตริงสั้นที่คงที่ เช่นmanual:quarantined,scan:maliciousและpackage:malicioustrust.pendingหมายความว่าอินพุตความน่าเชื่อถืออย่างน้อยหนึ่งรายการยังรอการดำเนินการให้เสร็จสิ้นtrust.staleหมายความว่าข้อมูลสรุปความน่าเชื่อถือคำนวณจากอินพุตที่ล้าสมัย และ ควรถือว่าต้องรีเฟรชก่อนตัดสินใจอนุญาตด้วยความมั่นใจสูง
หมายเหตุ:
- ปลายทางนี้ระบุเวอร์ชันอย่างเจาะจง ไคลเอนต์ควรเรียกใช้หลังจากแก้ไข เวอร์ชันแพ็กเกจที่ตั้งใจจะติดตั้งแล้ว ไม่ใช่เพียงหลังจากอ่านข้อมูลเมตา แพ็กเกจล่าสุด
- แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกมีสิทธิ์อ่านผู้เผยแพร่ที่เป็นเจ้าของ - ปลายทางนี้จงใจมีขอบเขตแคบกว่าปลายทางการควบคุมของเจ้าของ/ผู้ควบคุม โดยเปิดเผยการตัดสินใจติดตั้งและคำอธิบายสาธารณะ แต่ไม่เปิดเผย ตัวตนผู้รายงาน เนื้อหารายงาน หลักฐานส่วนตัว หรือไทม์ไลน์การตรวจสอบ ภายใน
GET /api/v1/packages/{name}/versions/{version}/artifact
ส่งคืนข้อมูลเมตาตัวแก้ไขอาร์ติแฟกต์ที่ระบุชัดเจนสำหรับแพ็กเกจหนึ่งเวอร์ชัน
หมายเหตุ:
- แพ็กเกจเวอร์ชันเดิมจะส่งคืนอาร์ติแฟกต์
legacy-zipและ ZIP แบบเดิมdownloadUrl - เวอร์ชัน ClawPack จะส่งคืนอาร์ติแฟกต์
npm-pack, ฟิลด์ความสมบูรณ์ของ npm,tarballUrlและ URL ความเข้ากันได้กับ ZIP แบบเดิม - นี่คือพื้นผิวตัวแก้ไขของ OpenClaw ซึ่งหลีกเลี่ยงการคาดเดารูปแบบไฟล์เก็บถาวรจาก URL ที่ใช้ร่วมกัน
GET /api/v1/packages/{name}/versions/{version}/artifact/download
ดาวน์โหลดอาร์ติแฟกต์ของเวอร์ชันผ่านพาธตัวแก้ไขที่ระบุชัดเจน
หมายเหตุ:
- เวอร์ชัน ClawPack สตรีมไบต์
.tgzของ npm-pack ที่อัปโหลดไว้แบบตรงทุกประการ - เวอร์ชัน ZIP แบบเดิมเปลี่ยนเส้นทางไปยัง
/api/v1/packages/{name}/download?version= - ใช้บักเก็ตอัตราการดาวน์โหลด
GET /api/v1/packages/{name}/readiness
ส่งคืนความพร้อมที่คำนวณแล้วสำหรับการใช้งานโดย OpenClaw ในอนาคต
การตรวจสอบความพร้อมครอบคลุม:
- สถานะช่องทางอย่างเป็นทางการ
- ความพร้อมใช้งานของเวอร์ชันล่าสุด
- ความพร้อมใช้งานของอาร์ติแฟกต์ npm-pack ของ ClawPack
- ไดเจสต์ของอาร์ติแฟกต์
- ที่มาของรีโพซิทอรีต้นทางและคอมมิต
- ข้อมูลเมตาความเข้ากันได้กับ OpenClaw
- เป้าหมายโฮสต์
- สถานะการสแกน
การตอบกลับ:
{ "package": { "name": "@openclaw/example-plugin", "displayName": "Plugin ตัวอย่าง", "family": "code-plugin", "isOfficial": true, "latestVersion": "1.2.3" }, "ready": false, "checks": [ { "id": "clawpack", "label": "อาร์ติแฟกต์ ClawPack", "status": "fail", "message": "เวอร์ชันล่าสุดมีเฉพาะ ZIP แบบเดิม" } ], "blockers": ["clawpack"]}GET /api/v1/packages/migrations
ปลายทางสำหรับผู้ดูแลเพื่อแสดงรายการแถวการย้าย Plugin อย่างเป็นทางการของ OpenClaw
การยืนยันตัวตน:
- ต้องใช้โทเค็น API ของผู้ใช้ที่เป็นผู้ดูแลหรือผู้ดูแลระบบ
พารามิเตอร์คิวรี:
phase(ไม่บังคับ):planned,published,clawpack-ready,legacy-zip-only,metadata-ready,blocked,ready-for-openclawหรือall(ค่าเริ่มต้น)limit(ไม่บังคับ): จำนวนเต็ม (1-100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
การตอบกลับ:
{ "items": [ { "migrationId": "officialPluginMigrations:...", "bundledPluginId": "core.search", "packageName": "@openclaw/search-plugin", "packageId": "packages:...", "owner": "platform", "sourceRepo": "openclaw/openclaw", "sourcePath": "plugins/search", "sourceCommit": "abc123", "phase": "blocked", "blockers": ["ไม่มี ClawPack"], "hostTargetsComplete": true, "scanClean": false, "moderationApproved": false, "runtimeBundlesReady": false, "notes": null, "createdAt": 1760000000000, "updatedAt": 1760000000000 } ], "nextCursor": null, "done": true}POST /api/v1/packages/migrations
ปลายทางสำหรับผู้ดูแลระบบเพื่อสร้างหรืออัปเดตแถวการย้าย Plugin อย่างเป็นทางการ
การยืนยันตัวตน:
- ต้องใช้โทเค็น API ของผู้ใช้ที่เป็นผู้ดูแลระบบ
เนื้อหาคำขอ:
{ "bundledPluginId": "core.search", "packageName": "@openclaw/search-plugin", "owner": "platform", "sourceRepo": "openclaw/openclaw", "sourcePath": "plugins/search", "sourceCommit": "abc123", "phase": "blocked", "blockers": ["ไม่มี ClawPack"], "hostTargetsComplete": true, "scanClean": false, "moderationApproved": false, "runtimeBundlesReady": false, "notes": "กำลังรอผู้เผยแพร่อัปโหลด"}หมายเหตุ:
bundledPluginIdจะถูกปรับเป็นตัวพิมพ์เล็กและเป็นคีย์ upsert แบบคงที่packageNameจะถูกปรับรูปแบบเป็นชื่อ npm โดยแพ็กเกจอาจยังไม่มีสำหรับการย้าย ที่วางแผนไว้- ส่วนนี้ติดตามเฉพาะความพร้อมในการย้าย โดยไม่แก้ไข OpenClaw หรือสร้าง ClawPack
GET /api/v1/packages/moderation/queue
ปลายทางสำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อจัดการคิวรีวิวรุ่นแพ็กเกจ
การยืนยันตัวตน:
- ต้องใช้โทเค็น API ของผู้ใช้ที่เป็นผู้ดูแลหรือผู้ดูแลระบบ
พารามิเตอร์คิวรี:
status(ไม่บังคับ):open(ค่าเริ่มต้น),blocked,manualหรือalllimit(ไม่บังคับ): จำนวนเต็ม (1-100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
ความหมายของสถานะ:
open: รุ่นที่น่าสงสัย เป็นอันตราย รอดำเนินการ ถูกกักกัน ถูกเพิกถอน หรือถูกรายงานblocked: รุ่นที่ถูกกักกัน ถูกเพิกถอน หรือเป็นอันตรายmanual: รุ่นใดก็ตามที่มีการแทนค่าการตรวจสอบโดยผู้ดูแลด้วยตนเองall: รุ่นใดก็ตามที่มีการแทนค่าด้วยตนเอง สถานะการสแกนไม่สะอาด หรือรายงานแพ็กเกจ
การตอบกลับ:
{ "items": [ { "packageId": "packages:...", "releaseId": "packageReleases:...", "name": "@openclaw/example-plugin", "displayName": "Plugin ตัวอย่าง", "family": "code-plugin", "channel": "community", "isOfficial": false, "version": "1.2.3", "createdAt": 1730000000000, "artifactKind": "npm-pack", "scanStatus": "malicious", "moderationState": "quarantined", "moderationReason": "การรีวิวด้วยตนเอง", "sourceRepo": "openclaw/example-plugin", "sourceCommit": "abc123", "reportCount": 2, "lastReportedAt": 1730000001000, "reasons": ["manual:quarantined", "scan:malicious", "reports:2"] } ], "nextCursor": null, "done": true}POST /api/v1/packages/{name}/report
รายงานแพ็กเกจให้ผู้ดูแลตรวจสอบ รายงานมีผลในระดับแพ็กเกจและอาจ เชื่อมโยงกับเวอร์ชันได้ รายงานจะเข้าสู่คิวการตรวจสอบ แต่จะไม่ซ่อนหรือ บล็อกการดาวน์โหลดโดยอัตโนมัติ ผู้ดูแลควรใช้การตรวจสอบรุ่นเพื่อ อนุมัติ กักกัน หรือเพิกถอนอาร์ติแฟกต์
การยืนยันตัวตน:
- ต้องใช้โทเค็น API
คำขอ:
{ "reason": "ไบนารีแบบเนทีฟที่น่าสงสัย", "version": "1.2.3" }การตอบกลับ:
{ "ok": true, "reported": true, "alreadyReported": false, "packageId": "packages:...", "releaseId": "packageReleases:...", "reportCount": 1}GET /api/v1/packages/reports
ปลายทางสำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อรับรายงานแพ็กเกจ
การยืนยันตัวตน:
- ต้องใช้โทเค็น API ของผู้ใช้ที่เป็นผู้ดูแลหรือผู้ดูแลระบบ
พารามิเตอร์คิวรี:
status(ไม่บังคับ):open(ค่าเริ่มต้น),confirmed,dismissedหรือalllimit(ไม่บังคับ): จำนวนเต็ม (1-100)cursor(ไม่บังคับ): เคอร์เซอร์การแบ่งหน้า
การตอบกลับ:
{ "items": [ { "reportId": "packageReports:...", "packageId": "packages:...", "releaseId": "packageReleases:...", "name": "@openclaw/example-plugin", "displayName": "Plugin ตัวอย่าง", "family": "code-plugin", "version": "1.2.3", "reason": "ไบนารีแบบเนทีฟที่น่าสงสัย", "status": "open", "createdAt": 1730000000000, "reporter": { "userId": "users:...", "handle": "reporter", "displayName": "ผู้รายงาน" }, "triagedAt": null, "triagedBy": null, "triageNote": null } ], "nextCursor": null, "done": true}GET /api/v1/packages/{name}/moderation
ปลายทางสำหรับเจ้าของ/ผู้ดูแลเพื่อดูข้อมูลการตรวจสอบแพ็กเกจ
การยืนยันตัวตน:
- ต้องใช้โทเค็น API ของเจ้าของแพ็กเกจ สมาชิกผู้เผยแพร่ ผู้ดูแล หรือ ผู้ใช้ที่เป็นผู้ดูแลระบบ
การตอบกลับ:
{ "package": { "packageId": "packages:...", "name": "@openclaw/example-plugin", "displayName": "Plugin ตัวอย่าง", "family": "code-plugin", "channel": "community", "isOfficial": false, "reportCount": 2, "lastReportedAt": 1730000001000, "scanStatus": "malicious" }, "latestRelease": { "releaseId": "packageReleases:...", "version": "1.2.3", "artifactKind": "npm-pack", "scanStatus": "malicious", "moderationState": "quarantined", "moderationReason": "การรีวิวด้วยตนเอง", "blockedFromDownload": true, "reasons": ["manual:quarantined", "scan:malicious", "reports:2"], "createdAt": 1730000000000 }}POST /api/v1/packages/reports/{reportId}/triage
ปลายทางสำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อปิดหรือเปิดรายงานแพ็กเกจอีกครั้ง
คำขอ:
{ "status": "confirmed", "note": "ตรวจสอบและกักกันรุ่นที่ได้รับผลกระทบแล้ว", "finalAction": "quarantine"}ต้องระบุ note สำหรับ confirmed และ dismissed แต่อาจละเว้นได้เมื่อ
ตั้งค่า status กลับเป็น open ส่ง finalAction: "quarantine" หรือ
finalAction: "revoke" พร้อมรายงานที่ยืนยันแล้วเพื่อใช้การตรวจสอบรุ่นภายใน
เวิร์กโฟลว์เดียวกันที่ตรวจสอบย้อนหลังได้
การตอบกลับ:
{ "ok": true, "reportId": "packageReports:...", "packageId": "packages:...", "status": "confirmed", "reportCount": 0}POST /api/v1/packages/{name}/versions/{version}/moderation
ปลายทางสำหรับผู้ดูแล/ผู้ดูแลระบบเพื่อรีวิวรุ่นแพ็กเกจ
คำขอ:
{ "state": "quarantined", "reason": "เพย์โหลดแบบเนทีฟที่น่าสงสัย" }สถานะที่รองรับ:
approved: ตรวจสอบด้วยตนเองและอนุญาตแล้วquarantined: ถูกบล็อกระหว่างรอการติดตามผลrevoked: ถูกบล็อกหลังจากรุ่นเคยได้รับความเชื่อถือแล้ว
รุ่นที่ถูกกักกันและถูกเพิกถอนจะส่งคืน 403 จากเส้นทางดาวน์โหลดอาร์ติแฟกต์
ทุกการเปลี่ยนแปลงจะเขียนรายการลงในบันทึกการตรวจสอบ
GET /api/v1/packages/{name}/file
ส่งคืนไบต์ไฟล์แพ็กเกจที่จัดเก็บไว้แบบตรงทุกประการเพื่อดาวน์โหลด เพิ่ม preview=1 เพื่อขอตัวอย่างข้อความ
UTF-8 แบบจำกัดขนาดเดียวกับที่ใช้สำหรับไฟล์ Skills
พารามิเตอร์คิวรี:
path(จำเป็น)version(ไม่บังคับ)tag(ไม่บังคับ)preview=1(ไม่บังคับ; ส่งคืนtext/plainหรือ415เมื่อไบต์ไม่ใช่ UTF-8 ที่ถูกต้อง)
หมายเหตุ:
- ค่าเริ่มต้นคือรุ่นล่าสุด
- ใช้บักเก็ตอัตราการอ่าน ไม่ใช่บักเก็ตการดาวน์โหลด
- ขีดจำกัดการดาวน์โหลดแบบดิบ: 10MB
- ขีดจำกัดตัวอย่างข้อความ: 200KB; ไฟล์ทึบแสงจะส่งคืน
415เฉพาะคำขอตัวอย่างเท่านั้น - การสแกน VirusTotal ที่รอดำเนินการจะไม่บล็อกการอ่าน แต่รุ่นที่เป็นอันตรายอาจยังถูกระงับในส่วนอื่น
- แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกจะอ่านข้อมูลของผู้เผยแพร่ที่เป็นเจ้าของได้
GET /api/v1/packages/{name}/download
ดาวน์โหลดไฟล์เก็บถาวร ZIP แบบกำหนดผลลัพธ์แน่นอนรุ่นเดิมสำหรับรุ่นแพ็กเกจ
พารามิเตอร์คิวรี:
version(ไม่บังคับ)tag(ไม่บังคับ)
หมายเหตุ:
- ค่าเริ่มต้นคือรุ่นล่าสุด
- Skills เปลี่ยนเส้นทางไปยัง
GET /api/v1/download - ไฟล์เก็บถาวรของ Plugin/แพ็กเกจเป็นไฟล์ zip ที่มีรูท
package/เพื่อให้ไคลเอนต์ OpenClaw รุ่นเก่ายังคงทำงานได้ - เส้นทางนี้รองรับเฉพาะ ZIP และไม่สตรีมไฟล์ ClawPack
.tgz - การตอบกลับมีส่วนหัว
ETag,Digest,X-ClawHub-Artifact-TypeและX-ClawHub-Artifact-Sha256สำหรับการตรวจสอบความสมบูรณ์ของตัวแก้ไข - ข้อมูลเมตาที่มีเฉพาะในรีจิสทรีจะไม่ถูกแทรกลงในไฟล์เก็บถาวรที่ดาวน์โหลด
- การสแกน VirusTotal ที่รอดำเนินการจะไม่บล็อกการดาวน์โหลด แต่รุ่นที่เป็นอันตรายจะส่งคืน
403 - แพ็กเกจส่วนตัวจะส่งคืน
404เว้นแต่ผู้เรียกจะเป็นเจ้าของ
GET /api/npm/{package}
ส่งคืน packument ที่เข้ากันได้กับ npm สำหรับเวอร์ชันแพ็กเกจที่ใช้ ClawPack
หมายเหตุ:
- แสดงรายการเฉพาะเวอร์ชันที่มี tarball npm-pack ของ ClawPack อัปโหลดไว้
- จงใจละเว้นเวอร์ชันแบบเดิมที่มีเฉพาะ ZIP
dist.tarball,dist.integrityและdist.shasumใช้ฟิลด์ที่เข้ากันได้กับ npm เพื่อให้ผู้ใช้ชี้ npm ไปยังมิเรอร์ได้หากต้องการ- packument ของแพ็กเกจแบบมีขอบเขตรองรับทั้ง
/api/npm/@scope/nameและพาธคำขอ/api/npm/@scope%2Fnameที่เข้ารหัสตามรูปแบบของ npm
GET /api/npm/{package}/-/{tarball}.tgz
สตรีมไบต์ tarball ของ ClawPack ที่อัปโหลดไว้แบบตรงทุกประการสำหรับไคลเอนต์มิเรอร์ npm
หมายเหตุ:
- ใช้บักเก็ตอัตราการดาวน์โหลด
- ส่วนหัวการดาวน์โหลดมี SHA-256 ของ ClawHub พร้อมข้อมูลเมตา integrity/shasum ของ npm
- การตรวจสอบและการตรวจสิทธิ์เข้าถึงแพ็กเกจส่วนตัวยังคงมีผล
GET /api/v1/resolve
CLI ใช้เพื่อจับคู่ลายนิ้วมือในเครื่องกับเวอร์ชันที่รู้จัก
พารามิเตอร์คิวรี:
slug(จำเป็น)hash(จำเป็น): sha256 เลขฐานสิบหก 64 อักขระของลายนิ้วมือบันเดิล
การตอบกลับ:
{ "slug": "gifgrep", "match": { "version": "1.2.2" }, "latestVersion": { "version": "1.2.3" } }GET /api/v1/download
ดาวน์โหลด ZIP ของเวอร์ชัน skill ที่โฮสต์ไว้ หรือส่งคืนข้อมูลส่งต่อไปยังซอร์ส GitHub สำหรับ
skill ปัจจุบันที่ใช้ GitHub เป็นแหล่งข้อมูล ซึ่งผ่านการสแกน clean หรือ suspicious และไม่มีเวอร์ชัน
ที่โฮสต์ไว้
พารามิเตอร์การค้นหา:
slug(จำเป็น)version(ไม่บังคับ): สตริง semvertag(ไม่บังคับ): ชื่อแท็ก (เช่นlatest)
หมายเหตุ:
- หากไม่ได้ระบุทั้ง
versionและtagระบบจะใช้เวอร์ชันล่าสุด - เวอร์ชันที่ลบแบบ soft-delete จะส่งคืน
410 - การส่งต่อ skill ที่ใช้ GitHub เป็นแหล่งข้อมูลจะไม่พร็อกซีหรือทำสำเนาไบต์ การตอบกลับ JSON
ประกอบด้วย
sourceRef: "public-github",repo,commit,path,contentHashและarchiveUrl; สถานะการสแกน/สถานะปัจจุบันเป็นเงื่อนไขควบคุม และไม่รวมอยู่ในข้อมูลเมตาของเพย์โหลด เมื่อสำเร็จ - สถิติการดาวน์โหลดจะนับข้อมูลระบุตัวตนที่ไม่ซ้ำกันต่อวันตาม UTC (
userIdเมื่อโทเค็น API ถูกต้อง มิฉะนั้นใช้ IP)
เอ็นด์พอยต์การยืนยันตัวตน (Bearer token)
เอ็นด์พอยต์ทั้งหมดต้องใช้:
Authorization: Bearer clh_...GET /api/v1/whoami
ตรวจสอบความถูกต้องของโทเค็นและส่งคืนแฮนเดิลของผู้ใช้
POST /api/v1/skills
เผยแพร่เวอร์ชันใหม่
- แนะนำให้ใช้:
multipart/form-dataพร้อม JSONpayload+ บล็อบfiles[] - ยอมรับเนื้อหา JSON ที่มี
files(อ้างอิงด้วย storageId) เช่นกัน - ฟิลด์เพย์โหลดที่ไม่บังคับ:
ownerHandleเมื่อระบุ API จะค้นหาผู้เผยแพร่นั้น ทางฝั่งเซิร์ฟเวอร์ และกำหนดให้ผู้ดำเนินการต้องมีสิทธิ์เข้าถึงผู้เผยแพร่ - ฟิลด์เพย์โหลดที่ไม่บังคับ:
migrateOwnerเมื่อtrueพร้อมownerHandleskill ที่มีอยู่สามารถย้ายไปยังเจ้าของรายนั้นได้ หากผู้ดำเนินการเป็นผู้ดูแลระบบ/เจ้าของของผู้เผยแพร่ทั้ง รายปัจจุบันและรายเป้าหมาย หากไม่เลือกใช้ตัวเลือกนี้ การเปลี่ยนเจ้าของ จะถูกปฏิเสธ
POST /api/v1/packages
เผยแพร่รีลีส code-plugin หรือ bundle-plugin
- ต้องยืนยันตัวตนด้วย Bearer token
- ต้องมี
multipart/form-data - ฟิลด์แบบฟอร์มที่อนุญาต ได้แก่
payload, บล็อบfilesที่ระบุซ้ำ หรือข้อมูลอ้างอิง tarballclawpackหนึ่งรายการclawpackอาจเป็นบล็อบ.tgzหรือรหัสพื้นที่จัดเก็บที่ขั้นตอน upload-url ส่งคืน การเผยแพร่ด้วย storage-id ที่จัดเตรียมไว้ต้องระบุclawpackUploadTicketที่ส่งคืนพร้อม URL อัปโหลดนั้นด้วย - ใช้
filesหรือclawpackอย่างใดอย่างหนึ่งเท่านั้น ห้ามใช้ทั้งคู่ในคำขอเดียวกัน - เนื้อหา JSON และข้อมูลเมตา
payload.files/payload.artifactที่ผู้เรียกเป็นผู้ระบุจะถูกปฏิเสธ - คำขอเผยแพร่แบบ multipart โดยตรงจำกัดไว้ที่ 18MB ส่วน tarball ของ ClawPack สามารถใช้ขั้นตอน upload-url ได้จนถึงขีดจำกัด tarball 120MB
- ฟิลด์เพย์โหลดที่ไม่บังคับ:
ownerHandleเมื่อระบุ มีเพียงผู้ดูแลระบบเท่านั้นที่เผยแพร่ในนามของเจ้าของรายนั้นได้
ประเด็นสำคัญของการตรวจสอบความถูกต้อง:
familyต้องเป็นcode-pluginหรือbundle-plugin- แพ็กเกจ Plugin ต้องมี
openclaw.plugin.jsonการอัปโหลด.tgzของ ClawPack ต้อง มีรายการนี้ที่package/openclaw.plugin.json - code plugin ต้องมี
package.json, ข้อมูลเมตาของรีโพซิทอรีซอร์ส, ข้อมูลเมตาของคอมมิตซอร์ส, ข้อมูลเมตาของสคีมาการกำหนดค่า,openclaw.compat.pluginApiและopenclaw.build.openclawVersion openclaw.hostTargetsและopenclaw.environmentเป็นข้อมูลเมตาที่ไม่บังคับ- เฉพาะผู้เผยแพร่องค์กร
openclawและผู้เผยแพร่ส่วนบุคคลของสมาชิกองค์กรopenclawปัจจุบันเท่านั้นที่เผยแพร่ไปยังช่องทางofficialได้ - การเผยแพร่ในนามของผู้อื่นยังคงตรวจสอบสิทธิ์การใช้ช่องทางอย่างเป็นทางการกับบัญชีเจ้าของเป้าหมาย
DELETE /api/v1/skills/{slug} / POST /api/v1/skills/{slug}/undelete
ลบแบบ soft-delete / กู้คืน skill (เจ้าของ ผู้ควบคุม หรือผู้ดูแลระบบ)
เนื้อหา JSON ที่ไม่บังคับ:
{ "reason": "ระงับไว้เพื่อการควบคุมเนื้อหาระหว่างรอการตรวจสอบทางกฎหมาย" }เมื่อระบุ reason ระบบจะจัดเก็บเป็นหมายเหตุการควบคุมของ skill และคัดลอกลงในบันทึกการตรวจสอบ
การลบแบบ soft-delete ที่เจ้าของเป็นผู้ดำเนินการจะสงวน slug ไว้ 30 วัน หลังจากนั้นผู้เผยแพร่
รายอื่นสามารถอ้างสิทธิ์ slug ได้ การตอบกลับการลบจะมี slugReservedUntil เมื่อมีการหมดอายุนี้
การซ่อนโดยผู้ควบคุม/ผู้ดูแลระบบและการนำออกด้วยเหตุผลด้านความปลอดภัยจะไม่หมดอายุในลักษณะนี้
การตอบกลับการลบ:
{ "ok": true, "slugReservedUntil": 1730000000000 }รหัสสถานะ:
200: สำเร็จ401: ไม่ได้รับอนุญาต403: ถูกห้าม404: ไม่พบ skill/ผู้ใช้500: ข้อผิดพลาดภายในเซิร์ฟเวอร์
POST /api/v1/users/publisher
สำหรับผู้ดูแลระบบเท่านั้น ตรวจสอบให้แน่ใจว่ามีผู้เผยแพร่องค์กรสำหรับแฮนเดิล หากแฮนเดิลยังชี้ไปยัง
ผู้ใช้ร่วม/ผู้เผยแพร่ส่วนบุคคลแบบเดิม เอ็นด์พอยต์จะย้ายข้อมูลดังกล่าวไปเป็นผู้เผยแพร่องค์กรก่อน
สำหรับองค์กรที่สร้างใหม่ ให้ระบุ memberHandle; ผู้ดูแลระบบที่ดำเนินการจะไม่ถูกเพิ่มเป็นสมาชิก
memberRole มีค่าเริ่มต้นเป็น owner
- เนื้อหา:
{ "handle": "openclaw", "displayName": "OpenClaw", "memberHandle": "alice", "memberRole": "owner", "trusted": true } - การตอบกลับ:
{ "ok": true, "publisherId": "...", "handle": "openclaw", "created": true, "migrated": false, "trusted": true, "member": { "userId": "...", "handle": "alice", "role": "owner" } }
POST /api/v1/publishers
การสร้างผู้เผยแพร่องค์กรแบบบริการตนเองที่ผ่านการยืนยันตัวตน สร้างผู้เผยแพร่องค์กรใหม่และเพิ่ม ผู้เรียกเป็นเจ้าของ เอ็นด์พอยต์นี้จะไม่ย้ายแฮนเดิลผู้ใช้/ส่วนบุคคลที่มีอยู่ และจะไม่ กำหนดให้ผู้เผยแพร่เป็นที่เชื่อถือ/เป็นทางการ
- เนื้อหา:
{ "handle": "opik", "displayName": "Opik" } - การตอบกลับ:
{ "ok": true, "publisherId": "...", "handle": "opik", "created": true, "trusted": false } - ส่งคืน
409เมื่อแฮนเดิลถูกใช้โดยผู้เผยแพร่ ผู้ใช้ หรือผู้เผยแพร่ส่วนบุคคลอยู่แล้ว
POST /api/v1/users/reserve
สำหรับผู้ดูแลระบบเท่านั้น สงวน root slug และชื่อแพ็กเกจให้เจ้าของที่ชอบธรรมโดยไม่เผยแพร่ รีลีส ชื่อแพ็กเกจจะกลายเป็นแพ็กเกจตัวยึดตำแหน่งแบบส่วนตัวที่ไม่มีแถวรีลีส เพื่อให้เจ้าของรายเดิม สามารถเผยแพร่รีลีส code-plugin หรือ bundle-plugin จริงไปยังชื่อนั้นได้ในภายหลัง
- เนื้อหา:
{ "handle": "openclaw", "slugs": ["diffs"], "packageNames": ["@openclaw/diffs"], "reason": "reserved for official OpenClaw plugin" } - การตอบกลับ:
{ "ok": true, "succeeded": 2, "failed": 0, "results": [{ "kind": "slug", "name": "diffs", "ok": true, "action": "reserved" }] }
POST /api/v1/users/publisher-recovery
สำหรับผู้ดูแลระบบเท่านั้น กู้คืนผู้เผยแพร่ส่วนบุคคลให้กับข้อมูลประจำตัว GitHub OAuth ทดแทนที่ผ่านการตรวจสอบ โดยไม่แก้ไขแถวบัญชี Convex Auth คำขอต้องระบุรหัสบัญชีผู้ให้บริการ GitHub แบบแก้ไขไม่ได้ทั้งสองรายการ ส่วนแฮนเดิลที่แก้ไขได้จะใช้เป็นเงื่อนไขป้องกันสำหรับผู้ปฏิบัติงานเท่านั้น
เอ็นด์พอยต์มีค่าเริ่มต้นเป็นการทดลองทำ การนำการกู้คืนไปใช้ต้องมี dryRun: false และ
confirmIdentityVerified: true หลังจากเจ้าหน้าที่ตรวจสอบความต่อเนื่องระหว่างข้อมูลประจำตัว GitHub
ทั้งสองรายการอย่างอิสระ การกู้คืนจะปฏิเสธโดยค่าเริ่มต้นเมื่อผู้เผยแพร่ส่วนบุคคลปัจจุบันของผู้ใช้ปลายทาง
มี skill, แพ็กเกจ หรือซอร์ส skill ของ GitHub
การกู้คืนยังย้ายข้อมูลฟิลด์ ownerUserId แบบเดิมสำหรับ skill ของผู้เผยแพร่ที่กู้คืน
นามแฝง slug ของ skill, แพ็กเกจ, คำเตือนจากตัวตรวจสอบแพ็กเกจ และแถวสรุปย่อการค้นหาที่สร้างขึ้น เพื่อให้
เส้นทางเจ้าของโดยตรงสอดคล้องกับอำนาจของผู้เผยแพร่รายใหม่ การสงวนแฮนเดิลที่มีการป้องกันและยังทำงานอยู่
สำหรับแฮนเดิลที่กู้คืนจะถูกกำหนดใหม่ให้ผู้ใช้ทดแทนด้วย เพื่อให้การซิงโครไนซ์โปรไฟล์ในภายหลัง
ไม่สามารถกู้คืนอำนาจที่ขัดแย้งกันของผู้ใช้เดิมได้ แต่ละตารางหลักจำกัดไว้ที่
100 แถวต่อธุรกรรมการนำไปใช้ การกู้คืนที่ใหญ่กว่านี้ต้องใช้การย้ายเจ้าของที่ดำเนินการต่อได้ก่อน
ซอร์ส skill ของ GitHub มีขอบเขตตามผู้เผยแพร่ และจะรายงานว่าตรวจสอบแล้วแทนที่จะเขียนใหม่
- เนื้อหา:
{ "handle": "gingiris", "nextUserHandle": "gingiris-1031", "previousGitHubProviderAccountId": "123", "nextGitHubProviderAccountId": "456", "reason": "Verified account continuity for issue #2555", "confirmIdentityVerified": true, "dryRun": false } - การตอบกลับ:
{ "ok": true, "dryRun": false, "recovered": true, "publisherId": "...", "handle": "gingiris", "previousUser": { "userId": "...", "handle": "gingiris", "nextHandle": "gingiris-recovered", "githubProviderAccountId": "123", "authAccountCount": 1 }, "nextUser": { "userId": "...", "handle": "gingiris-1031", "nextHandle": "gingiris", "githubProviderAccountId": "456", "authAccountCount": 1 }, "retiredPersonalPublisher": null, "resourceOwnerMigration": { "limitPerTable": 100, "skills": 1, "skillSlugAliases": 1, "packages": 0, "packageInspectorWarnings": 0, "githubSourcesChecked": 1, "handleReservations": 1 }, "identityVerified": true, "reason": "Verified account continuity for issue #2555" }
เอ็นด์พอยต์การจัดการ slug ของเจ้าของ
POST /api/v1/skills/{slug}/rename- เนื้อหา:
{ "newSlug": "new-canonical-slug" } - การตอบกลับ:
{ "ok": true, "slug": "new-canonical-slug", "previousSlug": "old-slug" }
- เนื้อหา:
POST /api/v1/skills/{slug}/merge- เนื้อหา:
{ "targetSlug": "canonical-target-slug" } - การตอบกลับ:
{ "ok": true, "sourceSlug": "old-slug", "targetSlug": "canonical-target-slug" }
- เนื้อหา:
หมายเหตุ:
- เอ็นด์พอยต์ทั้งสองต้องยืนยันตัวตนด้วยโทเค็น API และใช้ได้เฉพาะกับเจ้าของ skill เท่านั้น
renameจะเก็บ slug ก่อนหน้าไว้เป็นนามแฝงสำหรับการเปลี่ยนเส้นทางmergeจะซ่อนรายการต้นทางและเปลี่ยนเส้นทาง slug ต้นทางไปยังรายการเป้าหมาย
เอ็นด์พอยต์การโอนความเป็นเจ้าของ
POST /api/v1/skills/{slug}/transfer- เนื้อหา:
{ "toUserHandle": "target_handle", "message": "optional" } - การตอบกลับ:
{ "ok": true, "transferId": "skillOwnershipTransfers:...", "toUserHandle": "target_handle", "expiresAt": 1730000000000 }
- เนื้อหา:
POST /api/v1/skills/{slug}/transfer/acceptPOST /api/v1/skills/{slug}/transfer/rejectPOST /api/v1/skills/{slug}/transfer/cancel- การตอบกลับ (ยอมรับ/ปฏิเสธ/ยกเลิก):
{ "ok": true, "skillSlug": "demo-skill?" }
- การตอบกลับ (ยอมรับ/ปฏิเสธ/ยกเลิก):
GET /api/v1/transfers/incomingGET /api/v1/transfers/outgoing- รูปแบบการตอบกลับ:
{ "transfers": [{ "_id": "...", "skill": { "slug": "demo", "displayName": "Demo" }, "fromUser"|"toUser": { "handle": "..." }, "message": "...", "requestedAt": 0, "expiresAt": 0 }] }
- รูปแบบการตอบกลับ:
POST /api/v1/users/ban
แบนผู้ใช้และลบ skill ที่เป็นเจ้าของแบบถาวร (เฉพาะผู้ควบคุม/ผู้ดูแลระบบ)
เนื้อหา:
{ "handle": "user_handle", "reason": "เหตุผลในการแบนที่ไม่บังคับ" }หรือ
{ "userId": "users_...", "reason": "เหตุผลในการแบนที่ไม่บังคับ" }การตอบกลับ:
{ "ok": true, "alreadyBanned": false, "deletedSkills": 3 }POST /api/v1/users/unban
ยกเลิกการแบนผู้ใช้และกู้คืน skill ที่มีสิทธิ์ (เฉพาะผู้ดูแลระบบ)
เนื้อหา:
{ "handle": "user_handle", "reason": "เหตุผลในการยกเลิกการแบนที่ไม่บังคับ" }หรือ
{ "userId": "users_...", "reason": "เหตุผลในการยกเลิกการแบนที่ไม่บังคับ" }การตอบกลับ:
{ "ok": true, "alreadyUnbanned": false, "restoredSkills": 3 }POST /api/v1/users/reclassify-ban
เปลี่ยนเหตุผลที่จัดเก็บไว้สำหรับการแบนที่มีอยู่ โดยไม่ยกเลิกการแบนหรือกู้คืน
เนื้อหา (เฉพาะผู้ดูแลระบบ) มีค่าเริ่มต้นเป็นการทดลองทำ เว้นแต่ dryRun จะเป็น false
เนื้อหา:
{ "handle": "user_handle", "reason": "สแปมจากการเผยแพร่จำนวนมาก", "dryRun": true }หรือ
{ "userId": "users_...", "reason": "สแปมจากการเผยแพร่จำนวนมาก", "dryRun": false }การตอบกลับ:
{ "ok": true, "dryRun": false, "userId": "users_...", "handle": "user_handle", "previousReason": "แบนอัตโนมัติเนื่องจากมัลแวร์", "nextReason": "สแปมจากการเผยแพร่จำนวนมาก", "changed": true}POST /api/v1/users/role
เปลี่ยนบทบาทผู้ใช้ (เฉพาะผู้ดูแลระบบ)
เนื้อหา:
{ "handle": "user_handle", "role": "moderator" }หรือ
{ "userId": "users_...", "role": "admin" }การตอบกลับ:
{ "ok": true, "role": "moderator" }GET /api/v1/users
แสดงรายการหรือค้นหาผู้ใช้ (เฉพาะผู้ดูแลระบบ)
พารามิเตอร์การค้นหา:
q(ไม่บังคับ): คำค้นหาquery(ไม่บังคับ): นามแฝงสำหรับqlimit(ไม่บังคับ): จำนวนผลลัพธ์สูงสุด (ค่าเริ่มต้น 20, สูงสุด 200)
การตอบกลับ:
{ "items": [ { "userId": "users_...", "handle": "user_handle", "displayName": "ผู้ใช้", "name": "ผู้ใช้", "role": "moderator" } ], "total": 1}POST /api/v1/stars/{slug} / DELETE /api/v1/stars/{slug}
เพิ่ม/นำดาวออก (รายการเด่น) เอ็นด์พอยต์ทั้งสองเป็นแบบ idempotent
การตอบกลับ:
{ "ok": true, "starred": true, "alreadyStarred": false }{ "ok": true, "unstarred": true, "alreadyUnstarred": false }เอ็นด์พอยต์ CLI แบบเดิม (เลิกใช้แล้ว)
ยังคงรองรับสำหรับ CLI เวอร์ชันเก่า:
GET /api/cli/whoamiPOST /api/cli/upload-urlPOST /api/cli/publishPOST /api/cli/telemetry/installPOST /api/cli/skill/deletePOST /api/cli/skill/undelete
ดูแผนการนำออกที่ DEPRECATIONS.md
POST /api/cli/upload-url ส่งคืน uploadUrl และ uploadTicket การเผยแพร่
แพ็กเกจที่จัดเตรียม tarball ของ ClawPack ต้องส่งรหัสพื้นที่จัดเก็บที่ได้เป็น
clawpack และตั๋วที่ส่งคืนเป็น clawpackUploadTicket
การค้นหารีจิสทรี (/.well-known/clawhub.json)
CLI สามารถค้นหาการตั้งค่ารีจิสทรี/การยืนยันตัวตนจากเว็บไซต์:
/.well-known/clawhub.json(JSON, แนะนำให้ใช้)/.well-known/clawdhub.json(แบบเดิม)
สคีมา:
{ "apiBase": "https://clawhub.ai", "authBase": "https://clawhub.ai", "minCliVersion": "0.0.5" }หากโฮสต์ด้วยตนเอง ให้ให้บริการไฟล์นี้ (หรือกำหนด CLAWHUB_REGISTRY อย่างชัดเจน; แบบเดิมใช้ CLAWDHUB_REGISTRY)