// docs / rest api
REST API
Bearer-authenticated JSON API for scan automation, scan status, and findings. Passive scans are available through REST; active scans are available for paid plans only after the domain is verified and explicitly authorized in the dashboard.
การยืนยันตัวตน
ทุก request ต้องมี bearer token ใน header Authorization Tokens ออกให้จาก Account → API tokens; plaintext จะแสดงให้คุณเห็นเพียงครั้งเดียวตอนสร้าง การ revoke token จะคืน 401 ใน call ถัดไป
curl -H "Authorization: Bearer fxv_..." \
https://fixvibe.app/api/v1/scansรูปแบบ token: fxv_ ตามด้วยอักขระ base64url 43 ตัว เก็บ at rest เป็น SHA-256 hash; plaintext ไม่เคย persist ฝั่ง server
ขีดจำกัดอัตรา
สอง windows ในทุก authenticated request: 10 req/sec burst และ 60 req/min steady ทั้งคู่ keyed ด้วย bearer hash การบังคับใช้ quota (เพดาน scans ต่อเดือน) ซ้อนอยู่ด้านบน — ดู โควตาและขีดจำกัด
การแบ่งหน้า
List endpoints (/api/v1/scans, /api/v1/findings) ใช้ cursor-based pagination โดย key บน (created_at, id) แบบ descending ส่ง ?cursor=<next_cursor> เพื่อดึงหน้าถัดไป Cursor ยังคงถูกต้องเมื่อมี concurrent writes (ไม่เกิด OFFSET skew)
รูปแบบข้อผิดพลาด
ทุก error เป็น JSON object ที่มี key error อย่างน้อยหนึ่งตัว
{ "error": "invalid_token" } // 401
{ "error": "forbidden" } // 403
{ "error": "not_found" } // 404
{ "error": "quota_exceeded", "quota": {...} } // 429
{ "error": "rate_limited", "retry_after_seconds": 47 } // 429
{ "error": "invalid_input", "issues": [...] } // 400ปลายทาง
เริ่ม scan
/api/v1/scansEnqueues a passive scan by default. For verified domains with active authorization, paid plans can request active mode. Returns immediately with a queued scan id; poll GET /api/v1/scans/[scanId] until status === "completed".
curl -X POST https://fixvibe.app/api/v1/scans \
-H "Authorization: Bearer fxv_..." \
-H "content-type: application/json" \
-d '{"target":"https://staging.example.com"}'// การตอบกลับ 200
{
"id": "8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4d",
"status": "queued",
"target": "https://staging.example.com",
"mode": "passive"
}แสดงรายการ scans ของคุณ
/api/v1/scansคืน scans ของ org ที่ผูกกับ token ที่เรียก โดยเรียงใหม่สุดก่อน แบ่งหน้าด้วย ?cursor= Default limit 50, max 100
curl -H "Authorization: Bearer fxv_..." \
"https://fixvibe.app/api/v1/scans?limit=25"// การตอบกลับ 200
{
"scans": [
{
"id": "8f1c4e2a-...",
"target_url": "https://staging.example.com",
"target_hostname": "staging.example.com",
"mode": "passive",
"status": "completed",
"started_at": "2026-05-07T14:00:00Z",
"completed_at": "2026-05-07T14:00:23Z",
"findings_count": { "critical": 1, "high": 3, "medium": 7, "low": 2, "info": 4 },
"triggered_by": "api",
"created_at": "2026-05-07T14:00:00Z"
}
],
"next_cursor": "2026-05-07T14:00:00Z:8f1c4e2a-..."
}ดึง scan
/api/v1/scans/{scanId}คืน scan envelope + per-category severity summary โดยค่าเริ่มต้น ส่ง ?include_findings=true เพื่อรับรายงานเต็ม (ใหญ่สำหรับ scans ที่มี noise มาก — ควรใช้ findings endpoint พร้อม filters)
curl -H "Authorization: Bearer fxv_..." \
https://fixvibe.app/api/v1/scans/8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4dแสดงรายการ findings
/api/v1/findingsรายการ findings ที่ filter ได้ข้ามทุก scan ใน org ของผู้เรียก Filters: severity=critical,high, check_id=secrets.patterns, since=2026-04-01T00:00:00Z แบ่งหน้าด้วย cursor
curl -H "Authorization: Bearer fxv_..." \
"https://fixvibe.app/api/v1/findings?severity=critical,high&limit=50"// การตอบกลับ 200
{
"findings": [
{
"id": "...",
"scan_id": "...",
"check_id": "secrets.js-bundle-sweep",
"severity": "critical",
"title": "Supabase service role key exposed in JS bundle",
"description": "...",
"evidence": { ... },
"remediation": "...",
"cwe_id": "CWE-798",
"created_at": "2026-05-07T14:00:23Z"
}
],
"next_cursor": null
}ข้อกำหนด OpenAPI
Spec ที่เครื่องอ่านได้ที่ /docs/api/openapi (text/yaml) ใส่เข้า codegen ที่คุณชอบ (openapi-typescript, openapi-python-client หรือ toolchain OpenAPI 3.1 ใดก็ได้) เพื่อสร้าง typed clients
