APIOTA ให้บริการ REST API สำหรับจัดการ OTA updates ของ ESP32 อย่างครบวงจร ทุก request ส่งไปที่ base URL ด้านล่าง และรับ response เป็น JSON
https://apiota.net
Request ทุกตัวต้องมี Content-Type: application/json สำหรับ POST/PUT body ส่วน GET ส่ง parameters เป็น query string
ESP32 ยืนยันตัวตนด้วย device_id และ device_secret ที่ได้รับตอน register ส่วน Admin API ใช้ pk_ provisioning keys
ใส่ device_id และ device_secret เป็น query parameter หรือ request body ในทุก API call
// ตัวอย่าง ESP32 Arduino String url = "https://apiota.net/api/check-update"; url += "?device_id=" + String(DEVICE_ID); url += "&version=" + String(CURRENT_VERSION); url += "&device_secret=" + String(DEVICE_SECRET);
สำหรับ register อุปกรณ์ใหม่อัตโนมัติ ใช้ pk_ key ที่สร้างจาก Dashboard
// Register device ด้วย pk_ key POST /api/register { "device_id": "esp32-prod-001", "device_secret": "your_device_secret", "pk_key": "pk_live_xxxxxxxxxxxx", "firmware_ver": "1.0.0" }
Endpoints ทั้งหมดที่ให้บริการ แบ่งตามหมวดหมู่
ตรวจสอบว่า server ทำงานปกติ ไม่ต้องการ authentication
{
"status": "ok",
"version": "1.0.1",
"uptime": 86400
}อุปกรณ์ใช้ endpoint นี้เพื่อตรวจว่ามี firmware version ใหม่หรือไม่ ESP32 ควร poll ทุก 5–15 นาที
| Parameter | Type | Required | Description |
|---|---|---|---|
| device_id | string | required | Device ID ที่ลงทะเบียนไว้ |
| version | string | required | Firmware version ปัจจุบัน เช่น 1.0.9 |
| device_secret | string | required | Secret key ของอุปกรณ์ |
// มี update ใหม่ { "update": true, "version": "1.1.0", "url": "https://apiota.net/api/firmware/fw-1.1.0.bin", "sha256": "a3f8b2c1...", "size": 524288, "channel": "stable" } // ไม่มี update { "update": false }
อัปโหลดไฟล์ .bin firmware ส่งเป็น multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| file | file (.bin) | required | ไฟล์ firmware .bin |
| version | string | required | Version string เช่น 1.2.0 |
| channel | string | optional | stable / beta / dev (default: stable) |
| project_id | string | optional | โปรเจกต์ที่เชื่อมโยง |
# curl ตัวอย่าง curl -X POST https://apiota.net/api/firmware/upload \ -F "file=@firmware-1.2.0.bin" \ -F "version=1.2.0" \ -F "channel=stable"
ดาวน์โหลดไฟล์ firmware binary โดยตรง ESP32 ใช้ URL นี้ใน OTA update process
| Parameter | Type | Description |
|---|---|---|
| filename | string | ชื่อไฟล์ .bin ที่ได้รับจาก check-update |
GET /api/firmware/fw-1.1.0-stable.bin
→ Returns: application/octet-streamลงทะเบียนอุปกรณ์ใหม่ด้วย provisioning key ใช้ใน ESP32 ตอน boot ครั้งแรก
| Field | Type | Required | Description |
|---|---|---|---|
| device_id | string | required | Device ID ไม่ซ้ำกัน |
| device_secret | string | required | Secret key ที่กำหนดเอง |
| pk_key | string | required | Provisioning key (pk_live_...) |
| firmware_ver | string | optional | Firmware version ปัจจุบัน |
{
"success": true,
"device_id": "esp32-prod-001",
"registered_at": "2026-05-17T10:30:00Z"
}ESP32 ส่ง status update ระหว่าง OTA process มี 8 สถานะ: pending → checking → downloading → verifying → flashing → rebooting → done / failed
| Field | Type | Required | Description |
|---|---|---|---|
| device_id | string | required | |
| device_secret | string | required | |
| status | string | required | OTA status ปัจจุบัน |
| from_version | string | optional | Version เดิม |
| to_version | string | optional | Version ใหม่ |
| message | string | optional | ข้อความเพิ่มเติม / error message |
ดึง JSON config ที่ตั้งค่าไว้สำหรับอุปกรณ์นั้น
| Parameter | Type | Required | Description |
|---|---|---|---|
| device_id | string | required | |
| device_secret | string | required |
{
"config": {
"interval": 5000,
"log_level": "info",
"retry_count": 3
},
"updated_at": "2026-05-17T08:00:00Z"
}ตัวอย่าง code สำหรับ Arduino / ESP-IDF เพื่อ integrate กับ APIOTA
// config.h — ตั้งค่าหลัก #define DEVICE_ID "esp32-prod-001" #define DEVICE_SECRET "your_device_secret" #define CURRENT_VERSION "1.0.9" #define OTA_SERVER "https://apiota.net" #define OTA_INTERVAL 300000 // 5 นาที (ms)
void checkOTA() { HTTPClient http; String url = String(OTA_SERVER) + "/api/check-update"; url += "?device_id=" + String(DEVICE_ID); url += "&version=" + String(CURRENT_VERSION); url += "&device_secret=" + String(DEVICE_SECRET); http.begin(url); int code = http.GET(); if (code == 200) { DynamicJsonDocument doc(1024); deserializeJson(doc, http.getString()); if (doc["update"] == true) { String fwUrl = doc["url"]; sendOTALog("downloading", doc["version"]); performOTA(fwUrl); } } http.end(); }
void sendOTALog(String status, String toVer = "") { HTTPClient http; http.begin(String(OTA_SERVER) + "/api/ota-log"); http.addHeader("Content-Type", "application/json"); DynamicJsonDocument body(256); body["device_id"] = DEVICE_ID; body["device_secret"] = DEVICE_SECRET; body["status"] = status; body["from_version"] = CURRENT_VERSION; if (toVer.length() > 0) body["to_version"] = toVer; String out; serializeJson(body, out); http.POST(out); http.end(); }
API ใช้ HTTP status codes มาตรฐาน response body มี error field อธิบายปัญหา
| HTTP Code | Error | Description |
|---|---|---|
| 200 | OK | สำเร็จ |
| 400 | Bad Request | ขาด parameter หรือ format ไม่ถูกต้อง |
| 401 | Unauthorized | device_secret ไม่ถูกต้อง หรือ device_id ไม่พบ |
| 403 | Forbidden | เกินขีดจำกัดของแผน หรืออุปกรณ์ถูกบล็อก |
| 404 | Not Found | ไม่พบ resource ที่ขอ |
| 413 | Payload Too Large | ไฟล์ firmware ใหญ่เกิน limit ของแผน |
| 429 | Rate Limited | ส่ง request เร็วเกินไป รอ 60 วินาทีแล้วลองใหม่ |
| 500 | Server Error | Server error ติดต่อ support |
// ตัวอย่าง Error response { "error": "DEVICE_NOT_FOUND", "message": "device_id not registered", "status": 401 }
รายละเอียด release ทุก version รวมถึงข้อมูลสำหรับ rollback firmware เก็บไว้ในหน้า Internal Changelog (หลังบ้าน)
📋 ดู Internal Changelog →