API Documentation
v1 Stableยินดีต้อนรับเข้าสู่ระบบ API ของ PRO AI Vision แพลตฟอร์มที่ช่วยให้นักพัฒนาสามารถอ่านเลขมิเตอร์ไฟฟ้า เลขมิเตอร์น้ำ และเลขห้อง ได้อย่างแม่นยำด้วยเทคโนโลยี Vision AI ระบบของเราถูกออกแบบมาเพื่อความเสถียรและใช้งานง่ายสำหรับหอพักและบ้านเช่า
memory Vision AI Backend
https://core.vision.proiot.xyz/api/v1
Endpoint สำหรับการประมวลผลรูปภาพเพื่อดึงข้อมูลด้วย AI
rocket_launch เริ่มต้นใช้งาน
- สมัครและ Login ผ่าน Vision Web
- ไปที่ API Keys (
/api-keys) - กดสร้าง API Key ใหม่ และตั้งชื่อ (เช่น
production) - คัดลอกและเก็บ API Key ทันที — ระบบจะแสดงครั้งเดียวเท่านั้น
- ตรวจสอบว่ามี เครดิตคงเหลือ > 0 ก่อนเรียก API
รูปแบบ API Key:
sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
lock การยืนยันตัวตน (Authentication)
ทุก endpoint (ยกเว้น /health) ต้องส่ง header X-API-Key เพื่อยืนยันตัวตน
X-API-Key
HEADER: X-API-Key: {your_key}เหมาะสำหรับการเรียกใช้แบบ Server-to-Server โดยคุณสามารถสร้าง Key ได้จาก Dashboard ของ Vision Web
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files=@meter_photo.jpg"
| เงื่อนไข | ผลลัพธ์ |
|---|---|
ไม่ส่ง X-API-Key |
HTTP 401 |
| API Key ไม่ถูกต้องหรือถูกปิดใช้งาน | HTTP 401 — Invalid or inactive API key |
| เครดิตไม่พอ (≤ 0) | HTTP 403 — Insufficient credits |
| API Key ต้องอยู่ในสถานะ active | เปิด/ปิดได้จากหน้า Dashboard → API Keys |
data_object รูปแบบ Response
สำเร็จ (HTTP 200)
{
"success": true,
"data": { },
"message": "ข้อความ"
}
ล้มเหลว
{
"success": false,
"message": "ข้อความ error",
"errors": {
"field": ["รายละเอียด"]
}
}
ฟิลด์ errors จะมีเฉพาะกรณี validation error (HTTP 422)
API Endpoints
| Method | Path | Auth | คำอธิบาย |
|---|---|---|---|
| GET | /health | ไม่ต้อง | ตรวจสอบสถานะบริการ |
| GET | /api/v1/quota | X-API-Key | ตรวจเครดิตคงเหลือ |
| POST | /api/v1/extract/electric | X-API-Key | อ่านมิเตอร์ไฟฟ้า |
| POST | /api/v1/extract/water | X-API-Key | อ่านมิเตอร์น้ำ |
health_and_safety GET /health — Health Check
GETรายละเอียด
ตรวจสอบว่าบริการทำงานอยู่
ไม่ต้องส่ง API Key
curl https://core.vision.proiot.xyz/health
Response 200
{
"success": true,
"data": null,
"message": "Service is running"
}
account_balance_wallet GET /api/v1/quota — เครดิตคงเหลือ
GETรายละเอียด
Auth
X-API-Key
คืนค่า
เครดิตคงเหลือ (credits_remaining)
curl https://core.vision.proiot.xyz/api/v1/quota \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{
"success": true,
"data": {
"credits_remaining": 18
},
"message": "Quota retrieved successfully"
}
photo_camera เคล็ดลับการถ่ายรูป
ถ่าย 1 รูป หลายมิเตอร์ — ระบบตรวจจับมิเตอร์ทุกตัวในรูปเดียวและคืนผลเป็น array ใน data
ใช้วิธีนี้เพื่อลดจำนวนไฟล์และประหยัดเครดิต (หักตามจำนวนไฟล์ ไม่ใช่จำนวนมิเตอร์)
| แนวทาง | รายละเอียด |
|---|---|
| แนะนำ | จัดให้มิเตอร์อยู่ในเฟรมเดียวกัน ชัดเจน อ่านเลขได้ |
| จำนวนต่อรูป | ไม่เกิน 5–8 ตัวต่อรูป เพื่อความแม่นยำ |
| หลีกเลี่ยง | รูปมืด เบลอ มิเตอร์ซ้อนทับกันจนอ่านไม่ได้ |
ตัวอย่าง: อาคาร 20 ห้อง — ถ่าย 4 รูป (มิเตอร์ 5 ตัว/รูป) แทน 20 รูป → ใช้เครดิต 4 แทน 20
electric_bolt POST /api/v1/extract/electric
POSTอ่านมิเตอร์ไฟฟ้า — Content-Type: multipart/form-data
หลายมิเตอร์ต่อรูปได้ — แนะนำไม่เกิน 4–6 ตัวต่อรูป
Parameters
file[] — รูปมิเตอร์ไฟ (1–20 ไฟล์)
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files=@electric.jpg"
Example Response
{
"success": true,
"data": {
"total": 1,
"success_count": 1,
"failed_count": 0,
"results": [{
"rid": 1,
"filename": "electric.jpg",
"success": true,
"data": [{
"id": 1,
"room_no": "660",
"label": "MEA No. 920",
"value": 4035.7,
"box": [50, 100, 200, 300]
}],
"error": null
}],
"credits_remaining": 14
},
"message": "Meter extraction completed"
}
water_drop POST /api/v1/extract/water
POSTอ่านเลขหลักดำ (ลบ.ม.) จากมิเตอร์น้ำ — ไม่รวมเลขแดง/หน่วยย่อย
Parameters
file[] — รูปมิเตอร์น้ำ (1–20 ไฟล์)
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/water" \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files=@water1.jpg" \
-F "files=@water2.jpg"
Example Response
{
"success": true,
"data": {
"total": 2,
"success_count": 2,
"failed_count": 0,
"results": [{
"rid": 1,
"filename": "water1.jpg",
"success": true,
"data": [{
"id": 1,
"room_no": "660",
"label": null,
"value": 12345,
"box": [120, 80, 350, 280]
}]
}],
"credits_remaining": 15
},
"message": "Meter extraction completed"
}
crop_free วาดกรอบ Bounding Box ฝั่ง Client
API คืนพิกัด box เป็น [ymin, xmin, ymax, xmax]
แบบ normalized 0–1000 — แนะนำให้วาดกรอบบนรูปต้นฉบับฝั่ง client
เพื่อไม่ใช้พื้นที่จัดเก็บบนเซิร์ฟเวอร์
| พิกัด | สูตรแปลง (ใช้ขนาดรูปต้นฉบับ) |
|---|---|
| real_ymin | (ymin / 1000) × height |
| real_xmin | (xmin / 1000) × width |
| real_ymax | (ymax / 1000) × height |
| real_xmax | (xmax / 1000) × width |
นำ results[].data[] จาก response มาวาดกรอบสีแดงพร้อม label
room_no / value แล้วเซฟหรือแสดงรูปฝั่งคุณเอง
# pip install pillow
from PIL import Image, ImageDraw, ImageFont
def draw_boxes(image_path: str, meters: list, output_path: str = "boxed.jpg") -> str:
"""box = [ymin, xmin, ymax, xmax] normalized 0–1000"""
img = Image.open(image_path).convert("RGB")
draw = ImageDraw.Draw(img)
w, h = img.size
line_width = max(3, int(w * 0.003))
try:
font = ImageFont.load_default(size=int(h * 0.02))
except TypeError:
font = ImageFont.load_default()
for item in meters:
box = item.get("box")
if not box or len(box) != 4:
continue
ymin, xmin, ymax, xmax = box
x1 = int((xmin / 1000) * w)
y1 = int((ymin / 1000) * h)
x2 = int((xmax / 1000) * w)
y2 = int((ymax / 1000) * h)
draw.rectangle([x1, y1, x2, y2], outline="red", width=line_width)
room = item.get("room_no") or "N/A"
value = item.get("value")
label = f"Room: {room} | Val: {value}"
label_h = max(14, int(h * 0.03))
draw.rectangle([x1, y1 - label_h, x1 + int(w * 0.25), y1], fill="red")
draw.text((x1 + 5, y1 - label_h + 2), label, fill="white", font=font)
img.save(output_path, format="JPEG", quality=90)
return output_path
# ใช้กับผลลัพธ์จาก API
# meters = response["data"]["results"][0]["data"]
# draw_boxes("electric.jpg", meters, "electric_boxed.jpg")
05 ระบบเครดิต
| รายการ | รายละเอียด |
|---|---|
| อัตราหัก | จำนวนไฟล์ × อัตราต่อบริการ (default 1 เครดิต/ไฟล์) |
| ช่วงหัก | หักล่วงหน้าก่อนประมวลผล |
| คืนเครดิต | ไฟล์ที่ประมวลผลล้มเหลวจะคืนเครดิตอัตโนมัติ |
| ตรวจสอบยอด | GET /api/v1/quota |
ข้อจำกัด
| รายการ | ค่า |
|---|---|
| ขนาดไฟล์สูงสุด | 10 MB/ไฟล์ |
| จำนวนไฟล์ต่อ request | สูงสุด 20 ไฟล์ |
| มิเตอร์ต่อรูป (แนะนำ) | 5–8 ตัว/รูป |
| ขนาดรูป | resize อัตโนมัติถ้าด้านยาวเกิน 1536 px |
| Timeout ต่อไฟล์ | 60 วินาที (อาจได้ HTTP 504) |
| รูปแบบไฟล์ | JPEG, PNG ฯลฯ |
06 รหัส HTTP ที่พบบ่อย
401 Unauthorized
ไม่ส่ง API Key หรือ Key ไม่ถูกต้อง/ถูกปิด
403 Forbidden
เครดิตไม่พอ (Insufficient credits)
400 Bad Request
ไฟล์ใหญ่เกิน / batch เกิน 20 / รูปอ่านไม่ได้
422 Unprocessable Entity
Validation error (เช่น ไม่ส่ง files)
504 Gateway Timeout
AI timeout — หากทุกไฟล์ใน request timeout จะได้ error ทั้ง request
ตัวอย่าง error response
{
"success": false,
"message": "Insufficient credits: 2 available, 5 required (5 files x 1 credit/file)"
}
code ตัวอย่างโค้ด (รวม)
# Health check
curl https://core.vision.proiot.xyz/health
# เครดิตคงเหลือ
curl https://core.vision.proiot.xyz/api/v1/quota \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# มิเตอร์ไฟ
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/electric" \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files=@meter.jpg"
# มิเตอร์น้ำ
curl -X POST "https://core.vision.proiot.xyz/api/v1/extract/water" \
-H "X-API-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files=@meter.jpg"
คำถามที่พบบ่อย
Q: สร้าง API Key ได้ที่ไหน?
A: Login เข้า Vision Web → Dashboard → API Keys → สร้าง key ใหม่ หรือ คลิกที่นี่
Q: ลืมเก็บ API Key ทำอย่างไร?
A: ลบ key เดิมและสร้างใหม่ — ระบบไม่แสดง key เต็มซ้ำ
Q: ทำไมได้ 403?
A: เครดิตไม่พอ — ตรวจด้วย GET /api/v1/quota
Q: อัปโหลดหลายรูปใน request เดียวได้ไหม?
A: ได้ สูงสุด 20 ไฟล์ — ส่ง field files ซ้ำหลายครั้ง
Q: ถ่ายรูปเดียวที่มีหลายมิเตอร์ได้ไหม?
A: ได้ — ระบบตรวจจับทุกมิเตอร์ในรูป แนะนำไม่เกิน 5–8 ตัวต่อรูป