API v1.2
เส้น API ทั้งหมด

คู่มือเชื่อมต่อ JaideeMail API

ให้ระบบของคุณสร้างอีเมล ดูจำนวนข้อความ และเปิดอ่านอีเมล (รวมถึงรหัส OTP) ได้อัตโนมัติ ข้อมูลชุดเดียวกับที่เห็นในหลังบ้าน JaideeMail ของคุณ — สร้างผ่าน API ก็เห็นในหลังบ้านทันที และกลับกัน

Base URL

https://jaideemail.com/api/v1

ยืนยันตัวตน

X-Api-Key: <คีย์>

รูปแบบข้อมูล

JSON (UTF-8)

จำกัดการเรียก

60 ครั้ง/นาที ต่อคีย์

เริ่มต้นใน 3 ขั้นตอน

  1. 1

    ขอ API Key

    ติดต่อทีมงาน JaideeMail ให้ออกคีย์ให้บัญชีของคุณ คีย์ขึ้นต้นด้วย jdm_ และแสดงให้เห็นครั้งเดียว

  2. 2

    ส่งคีย์ทุกคำขอ

    ใส่ใน header X-Api-Key (หรือ Authorization: Bearer) ทุกครั้งที่เรียก

  3. 3

    ลองเรียก /me

    ถ้าได้ข้อมูลบัญชีกลับมา แปลว่าเชื่อมต่อสำเร็จ พร้อมใช้งานเส้นอื่นต่อ

ทดสอบการเชื่อมต่อ
curl -X GET "https://jaideemail.com/api/v1/me" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"

API Key และสิทธิ์

ส่งคีย์มาใน header X-Api-Key หรือ Authorization: Bearer <คีย์> อย่างใดอย่างหนึ่ง แต่ละคีย์ผูกกับบัญชีลูกค้าเดียว เห็นเฉพาะอีเมลของบัญชีนั้น

สิทธิ์ ชื่อในระบบ ทำอะไรได้
ดูอีเมล emails.read ดูรายการอีเมล รายละเอียด และจำนวนข้อความ
สร้าง/แก้ไขอีเมล emails.write สร้างอีเมลใหม่ตามโควตา และแก้ประเภท ชื่อกำกับ หรือข้อมูลกำกับ
อ่านข้อความ messages.read เปิดอ่านเนื้อหาอีเมล รหัส OTP และทำเครื่องหมายอ่านแล้ว
  • เก็บคีย์ไว้ฝั่งเซิร์ฟเวอร์เท่านั้น ห้ามใส่ในโค้ดหน้าเว็บหรือแอปมือถือที่ผู้ใช้เปิดดูได้
  • จำกัดให้ใช้ได้เฉพาะ IP ของเซิร์ฟเวอร์คุณได้ แจ้งทีมงานพร้อม IP ที่ต้องการ
  • ถ้าคีย์หลุด แจ้งทีมงานให้ยกเลิกแล้วออกคีย์ใหม่ได้ทันที

รูปแบบข้อมูล

ผลลัพธ์
อยู่ใน data เสมอ รายการแบบแบ่งหน้ามี meta (current_page, per_page, total, last_page, has_more) วนดึงหน้าถัดไปจนกว่า has_more เป็น false
วันเวลา
ISO 8601 เขตเวลาไทย เช่น 2026-10-08T09:41:27+07:00 · ส่งค่า since/until เป็นเขตเวลาไหนก็ได้ ระบบแปลงให้
ระบุอีเมลใน URL
ตรง {email} ใส่ได้ทั้งไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001)
ค่า true/false
ใน query ใช้ 1/0 หรือ true/false ก็ได้ เช่น unread=1
ข้อความภาษาไทย
message ใน error เป็นภาษาไทย แสดงให้ผู้ใช้อ่านได้เลย ส่วน code เป็นภาษาอังกฤษไว้ให้โปรแกรมตัดสินใจ

เส้น API ทั้งหมด

ทุกเส้นขึ้นต้นด้วย https://jaideemail.com/api/v1

บัญชี
GET /me ข้อมูลบัญชีและโควตา
อีเมล
GET /emails แสดงอีเมลทั้งหมด
POST /emails สร้างอีเมล
GET /emails/check ตรวจชื่ออีเมลก่อนสร้าง
GET /emails/{email} ดูอีเมล
PATCH /emails/{email} แก้ไขประเภท/ชื่อกำกับ/ข้อมูลกำกับ
GET /emails/{email}/count จำนวนข้อความของอีเมล
ข้อความ
GET /emails/{email}/messages ข้อความในอีเมลนี้
GET /emails/{email}/messages/latest ข้อความล่าสุด (รอรหัส OTP)
GET /messages ข้อความทุกอีเมล
GET /messages/{id} เปิดอ่านอีเมล
POST /messages/{id}/read ทำเครื่องหมายอ่านแล้ว
POST /messages/{id}/unread ทำเครื่องหมายยังไม่อ่าน
GET /me

ข้อมูลบัญชีและโควตา

ใช้ทดสอบว่าต่อ API ได้ และเช็คโควตาอีเมลกับวันหมดอายุก่อนสร้างอีเมล

สิทธิ์ที่ต้องมี: คีย์ใดก็ได้

ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/me" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "company_name": "บริษัท ตัวอย่าง จำกัด",
        "username": "example.co",
        "contact_name": "คุณสมศรี",
        "is_active": true,
        "package": {
            "id": 2,
            "name": "ธุรกิจ"
        },
        "expires_at": "2027-03-31",
        "is_expired": false,
        "days_until_expiry": 174,
        "mailbox_domain": "jaideemail.com",
        "email_quota": {
            "used": 48,
            "limit": 200,
            "remaining": 152,
            "can_create": true
        }
    },
    "meta": {
        "messages": {
            "total": 1290,
            "unread": 7
        },
        "api_key": {
            "name": "ระบบ ERP",
            "prefix": "jdm_Ab12CdEf",
            "abilities": [
                "emails.read",
                "emails.write",
                "messages.read"
            ]
        }
    }
}
GET /emails

แสดงอีเมลทั้งหมด

รายการอีเมลทั้งหมดของบัญชี พร้อมจำนวนข้อความและจำนวนที่ยังไม่อ่าน แบ่งหน้าละไม่เกิน 100 รายการ

สิทธิ์ที่ต้องมี: ดูอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
q query string ค้นจากอีเมลหรือชื่อกำกับ
type query string employer (นายจ้าง) หรือ employee (ลูกจ้าง)
flag query string กรองตามข้อมูลกำกับ: change_employer (เปลี่ยนนายจ้าง), resignation (แจ้งออกจากงาน), permit_renewal (ต่ออายุใบอนุญาตทำงาน), other (อื่นๆ)
unread query boolean 1 = เฉพาะอีเมลที่มีข้อความยังไม่อ่าน
sort query string latest (ค่าเริ่มต้น), oldest, address, last_received
per_page query integer จำนวนต่อหน้า 1-100 (ค่าเริ่มต้น 20)
page query integer หน้าที่ต้องการ เริ่มที่ 1
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails?type=employee&per_page=20" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": [
        {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "local_part": "worker001",
            "type": "employee",
            "type_label": "ลูกจ้าง",
            "label": "สมชาย ใจดี",
            "flag": null,
            "flag_label": null,
            "is_active": true,
            "messages_count": 3,
            "unread_count": 1,
            "last_received_at": "2026-10-08T09:41:27+07:00",
            "created_at": "2026-10-01T10:15:00+07:00",
            "updated_at": "2026-10-01T10:15:00+07:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1,
        "last_page": 1,
        "has_more": false
    }
}
POST /emails

สร้างอีเมล

สร้างอีเมลใหม่ตามโควตาแพ็กเกจ ใช้กฎเดียวกับการสร้างในหลังบ้านของลูกค้า อีเมลพร้อมรับข้อความทันที

สิทธิ์ที่ต้องมี: สร้าง/แก้ไขอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
address จำเป็น body (JSON) string ชื่อหน้า @ (เช่น worker001) หรืออีเมลเต็ม (worker001@jaideemail.com) ยาว 6-25 ตัว ใช้ได้ a-z 0-9 . _ - ขึ้นต้น-ลงท้ายด้วยตัวอักษรหรือตัวเลข
type จำเป็น body (JSON) string employer (นายจ้าง) หรือ employee (ลูกจ้าง)
label body (JSON) string ชื่อกำกับ เช่น ชื่อแรงงานที่ใช้อีเมลนี้ (ไม่เกิน 255 ตัว)
flag body (JSON) string ข้อมูลกำกับ เลือกได้ค่าเดียว (ไม่ส่ง = ไม่ระบุ): change_employer (เปลี่ยนนายจ้าง), resignation (แจ้งออกจากงาน), permit_renewal (ต่ออายุใบอนุญาตทำงาน), other (อื่นๆ)
ตัวอย่างคำขอ (curl)
curl -X POST "https://jaideemail.com/api/v1/emails" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"address":"worker001","type":"employee","label":"สมชาย ใจดี","flag":"change_employer"}'
ตัวอย่างผลลัพธ์ · HTTP 201
{
    "data": {
        "id": 12,
        "address": "worker001@jaideemail.com",
        "local_part": "worker001",
        "type": "employee",
        "type_label": "ลูกจ้าง",
        "label": "สมชาย ใจดี",
        "flag": "change_employer",
        "flag_label": "เปลี่ยนนายจ้าง",
        "is_active": true,
        "messages_count": 0,
        "unread_count": 0,
        "last_received_at": null,
        "created_at": "2026-10-01T10:15:00+07:00",
        "updated_at": "2026-10-01T10:15:00+07:00"
    }
}
  • ชื่อซ้ำ ชื่อสงวน หรือรูปแบบผิด ตอบ 422 (validation_failed) พร้อมเหตุผลใน errors.address
  • บัญชีหมดอายุ ตอบ 403 (account_expired) · โควตาเต็ม ตอบ 403 (quota_exceeded)
  • ลบอีเมลผ่าน API ไม่ได้ ต้องให้ทีมงานลบให้ (เหมือนในหลังบ้านของลูกค้า)
GET /emails/check

ตรวจชื่ออีเมลก่อนสร้าง

ตรวจว่าชื่อนี้ใช้ได้และยังว่างไหม โดยยังไม่สร้างจริง พร้อมบอกว่าโควตายังพอหรือเปล่า

สิทธิ์ที่ต้องมี: ดูอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
address จำเป็น query string ชื่อหน้า @ หรืออีเมลเต็มที่ต้องการตรวจ
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails/check?address=worker002" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "address": "worker002@jaideemail.com",
        "local_part": "worker002",
        "available": true,
        "reason": null,
        "can_create": true,
        "quota_reason": null
    }
}
GET /emails/{email}

ดูอีเมล

รายละเอียดของอีเมลหนึ่งรายการ พร้อมจำนวนข้อความ

สิทธิ์ที่ต้องมี: ดูอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email จำเป็น ใน URL string ไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001) ก็ได้
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails/worker001" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 12,
        "address": "worker001@jaideemail.com",
        "local_part": "worker001",
        "type": "employee",
        "type_label": "ลูกจ้าง",
        "label": "สมชาย ใจดี",
        "flag": null,
        "flag_label": null,
        "is_active": true,
        "messages_count": 3,
        "unread_count": 1,
        "last_received_at": "2026-10-08T09:41:27+07:00",
        "created_at": "2026-10-01T10:15:00+07:00",
        "updated_at": "2026-10-01T10:15:00+07:00"
    }
}
PATCH /emails/{email}

แก้ไขประเภท/ชื่อกำกับ/ข้อมูลกำกับ

แก้ประเภท ชื่อกำกับ หรือข้อมูลกำกับ ส่งเฉพาะค่าที่ต้องการเปลี่ยน ค่าที่ไม่ได้ส่งคงเดิม เปลี่ยนชื่ออีเมลไม่ได้

สิทธิ์ที่ต้องมี: สร้าง/แก้ไขอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email จำเป็น ใน URL string ไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001) ก็ได้
type body (JSON) string employer หรือ employee
label body (JSON) string ชื่อกำกับใหม่ ส่ง null เพื่อล้าง
flag body (JSON) string ข้อมูลกำกับใหม่ ส่ง null เพื่อล้าง (ไม่ระบุ): change_employer (เปลี่ยนนายจ้าง), resignation (แจ้งออกจากงาน), permit_renewal (ต่ออายุใบอนุญาตทำงาน), other (อื่นๆ)
ตัวอย่างคำขอ (curl)
curl -X PATCH "https://jaideemail.com/api/v1/emails/worker001" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"label":"สมชาย ใจดี (กะเช้า)","flag":"resignation"}'
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 12,
        "address": "worker001@jaideemail.com",
        "local_part": "worker001",
        "type": "employee",
        "type_label": "ลูกจ้าง",
        "label": "สมชาย ใจดี (กะเช้า)",
        "flag": "resignation",
        "flag_label": "แจ้งออกจากงาน",
        "is_active": true,
        "messages_count": 3,
        "unread_count": 1,
        "last_received_at": "2026-10-08T09:41:27+07:00",
        "created_at": "2026-10-01T10:15:00+07:00",
        "updated_at": "2026-10-01T10:15:00+07:00"
    }
}
  • ล้างข้อมูลกำกับ: ส่ง {"flag": null} · ไม่ได้ส่ง flag มาเลย ค่าเดิมไม่เปลี่ยน
GET /emails/{email}/count

จำนวนข้อความของอีเมล

นับข้อความทั้งหมด ยังไม่อ่าน และอ่านแล้ว — เบา เหมาะกับการเช็คเป็นระยะว่ามีจดหมายใหม่ไหม

สิทธิ์ที่ต้องมี: ดูอีเมล

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email จำเป็น ใน URL string ไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001) ก็ได้
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails/worker001/count" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "email_id": 12,
        "address": "worker001@jaideemail.com",
        "total": 3,
        "unread": 1,
        "read": 2,
        "last_received_at": "2026-10-08T09:41:27+07:00"
    }
}
GET /emails/{email}/messages

ข้อความในอีเมลนี้

รายการข้อความของอีเมลเดียว ใหม่สุดก่อน (แสดงตัวอย่างเนื้อหาและรหัส OTP ไม่รวมเนื้อหาเต็ม)

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email จำเป็น ใน URL string ไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001) ก็ได้
unread query boolean 1 = เฉพาะที่ยังไม่อ่าน
q query string ค้นจากหัวข้อ ผู้ส่ง หรือเนื้อหา
from query string กรองผู้ส่ง เช่น doe.go.th
since query datetime ตั้งแต่เวลานี้ (ISO 8601)
until query datetime ถึงเวลานี้ (ISO 8601)
per_page query integer จำนวนต่อหน้า 1-100 (ค่าเริ่มต้น 20)
page query integer หน้าที่ต้องการ เริ่มที่ 1
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails/worker001/messages?unread=1" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": [
        {
            "id": 345,
            "email": {
                "id": 12,
                "address": "worker001@jaideemail.com",
                "type": "employee",
                "label": "สมชาย ใจดี"
            },
            "from": {
                "address": "noreply@doe.go.th",
                "name": "กรมการจัดหางาน"
            },
            "subject": "รหัสยืนยันตัวตน (OTP)",
            "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
            "otp_code": "482913",
            "is_read": false,
            "read_at": null,
            "received_at": "2026-10-08T09:41:27+07:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1,
        "last_page": 1,
        "has_more": false
    }
}
GET /emails/{email}/messages/latest

ข้อความล่าสุด (รอรหัส OTP)

ข้อความล่าสุดฉบับเต็มของอีเมลนี้ ส่ง since เป็นเวลาที่กดขอรหัส จะได้เฉพาะข้อความที่เข้ามาหลังจากนั้น ยังไม่มีตอบ data: null

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email จำเป็น ใน URL string ไอดี (12) อีเมลเต็ม (worker001@jaideemail.com) หรือชื่อหน้า @ (worker001) ก็ได้
since query datetime เอาเฉพาะข้อความที่เข้ามาตั้งแต่เวลานี้ เช่น 2026-10-08T09:40:00+07:00
from query string กรองผู้ส่ง (บางส่วนของอีเมลหรือชื่อผู้ส่ง) เช่น doe.go.th
unread query boolean 1 = เฉพาะที่ยังไม่อ่าน
mark_read query boolean ค่าเริ่มต้น 1 = เปิดแล้วนับว่าอ่าน · ส่ง 0 ถ้าไม่ต้องการ
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/emails/worker001/messages/latest?since=2026-10-08T09:40:00%2B07:00" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 345,
        "email": {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "type": "employee",
            "label": "สมชาย ใจดี"
        },
        "from": {
            "address": "noreply@doe.go.th",
            "name": "กรมการจัดหางาน"
        },
        "subject": "รหัสยืนยันตัวตน (OTP)",
        "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
        "otp_code": "482913",
        "is_read": true,
        "read_at": "2026-10-08T09:41:35+07:00",
        "received_at": "2026-10-08T09:41:27+07:00",
        "body": "รหัส OTP ของคุณคือ 482913\nใช้ได้ภายใน 5 นาที",
        "body_html": "<p>รหัส OTP ของคุณคือ <b>482913</b></p><p>ใช้ได้ภายใน 5 นาที</p>",
        "has_html": true
    }
}
  • เรียกซ้ำทุก 3-5 วินาทีจนกว่าจะได้ข้อความ (หรือใช้ webhook แทนการเรียกซ้ำ)
  • ในค่า since เครื่องหมาย + ของเขตเวลาต้องเข้ารหัสเป็น %2B ใน URL
GET /messages

ข้อความทุกอีเมล

รวมข้อความจากทุกอีเมลไว้ที่เดียว (เหมือนหน้ากล่องข้อความ) ใหม่สุดก่อน

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
email query string เฉพาะอีเมลนี้ (ไอดี อีเมลเต็ม หรือชื่อหน้า @)
unread query boolean 1 = เฉพาะที่ยังไม่อ่าน
q query string ค้นจากหัวข้อ ผู้ส่ง หรือเนื้อหา
from query string กรองผู้ส่ง เช่น doe.go.th
since query datetime ตั้งแต่เวลานี้ (ISO 8601)
until query datetime ถึงเวลานี้ (ISO 8601)
per_page query integer จำนวนต่อหน้า 1-100 (ค่าเริ่มต้น 20)
page query integer หน้าที่ต้องการ เริ่มที่ 1
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/messages?unread=1&per_page=50" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": [
        {
            "id": 345,
            "email": {
                "id": 12,
                "address": "worker001@jaideemail.com",
                "type": "employee",
                "label": "สมชาย ใจดี"
            },
            "from": {
                "address": "noreply@doe.go.th",
                "name": "กรมการจัดหางาน"
            },
            "subject": "รหัสยืนยันตัวตน (OTP)",
            "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
            "otp_code": "482913",
            "is_read": false,
            "read_at": null,
            "received_at": "2026-10-08T09:41:27+07:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1,
        "last_page": 1,
        "has_more": false
    }
}
  • บัญชีหมดอายุ ข้อความที่เข้ามาหลังวันหมดอายุจะไม่แสดงในทุกเส้นและไม่ส่ง webhook จนกว่าจะต่ออายุ (ระบบยังรับเก็บไว้ ต่ออายุแล้วเห็นครบ)
GET /messages/{id}

เปิดอ่านอีเมล

เนื้อหาฉบับเต็มของข้อความ ทั้งแบบข้อความล้วน (body) และ HTML (body_html) เปิดแล้วนับว่าอ่านแล้วเหมือนในหลังบ้าน

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
id จำเป็น ใน URL integer ไอดีของข้อความ (ได้จากรายการข้อความ)
mark_read query boolean ค่าเริ่มต้น 1 = นับว่าอ่านแล้ว · ส่ง 0 เพื่อเปิดดูโดยไม่เปลี่ยนสถานะ
ตัวอย่างคำขอ (curl)
curl -X GET "https://jaideemail.com/api/v1/messages/345" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 345,
        "email": {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "type": "employee",
            "label": "สมชาย ใจดี"
        },
        "from": {
            "address": "noreply@doe.go.th",
            "name": "กรมการจัดหางาน"
        },
        "subject": "รหัสยืนยันตัวตน (OTP)",
        "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
        "otp_code": "482913",
        "is_read": true,
        "read_at": "2026-10-08T09:41:35+07:00",
        "received_at": "2026-10-08T09:41:27+07:00",
        "body": "รหัส OTP ของคุณคือ 482913\nใช้ได้ภายใน 5 นาที",
        "body_html": "<p>รหัส OTP ของคุณคือ <b>482913</b></p><p>ใช้ได้ภายใน 5 นาที</p>",
        "has_html": true
    }
}
  • body_html ผ่านการทำความสะอาดแล้ว แต่ถ้าจะแสดงในเว็บของคุณ ควรแสดงใน iframe แบบ sandbox
POST /messages/{id}/read

ทำเครื่องหมายอ่านแล้ว

เปลี่ยนสถานะเป็นอ่านแล้วโดยไม่ต้องดึงเนื้อหา

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
id จำเป็น ใน URL integer ไอดีของข้อความ
ตัวอย่างคำขอ (curl)
curl -X POST "https://jaideemail.com/api/v1/messages/345/read" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 345,
        "email": {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "type": "employee",
            "label": "สมชาย ใจดี"
        },
        "from": {
            "address": "noreply@doe.go.th",
            "name": "กรมการจัดหางาน"
        },
        "subject": "รหัสยืนยันตัวตน (OTP)",
        "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
        "otp_code": "482913",
        "is_read": true,
        "read_at": "2026-10-08T09:42:03+07:00",
        "received_at": "2026-10-08T09:41:27+07:00"
    }
}
POST /messages/{id}/unread

ทำเครื่องหมายยังไม่อ่าน

เปลี่ยนกลับเป็นยังไม่อ่าน ให้ทีมงานยังเห็นเป็นข้อความใหม่ในหลังบ้าน

สิทธิ์ที่ต้องมี: อ่านข้อความ

พารามิเตอร์ ส่งทาง ชนิด คำอธิบาย
id จำเป็น ใน URL integer ไอดีของข้อความ
ตัวอย่างคำขอ (curl)
curl -X POST "https://jaideemail.com/api/v1/messages/345/unread" \
  -H "X-Api-Key: jdm_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
ตัวอย่างผลลัพธ์ · HTTP 200
{
    "data": {
        "id": 345,
        "email": {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "type": "employee",
            "label": "สมชาย ใจดี"
        },
        "from": {
            "address": "noreply@doe.go.th",
            "name": "กรมการจัดหางาน"
        },
        "subject": "รหัสยืนยันตัวตน (OTP)",
        "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
        "otp_code": "482913",
        "is_read": false,
        "read_at": null,
        "received_at": "2026-10-08T09:41:27+07:00"
    }
}

ข้อผิดพลาด

ทุกข้อผิดพลาดตอบรูปแบบเดียวกัน ใช้ code ตัดสินใจในโปรแกรม และแสดง message ให้ผู้ใช้อ่าน

ตัวอย่าง · HTTP 422
{
    "message": "อีเมลนี้ถูกใช้ไปแล้ว กรุณาเปลี่ยนชื่อใหม่",
    "code": "validation_failed",
    "errors": {
        "address": [
            "อีเมลนี้ถูกใช้ไปแล้ว กรุณาเปลี่ยนชื่อใหม่"
        ]
    }
}
HTTP code ความหมาย
401 missing_api_key ไม่ได้ส่ง API Key มา
401 invalid_api_key API Key ไม่ถูกต้อง
401 revoked_api_key API Key ถูกยกเลิกแล้ว ต้องขอคีย์ใหม่
403 suspended_api_key API Key ถูกระงับชั่วคราว
403 ip_not_allowed เรียกจาก IP ที่ไม่ได้รับอนุญาตสำหรับคีย์นี้
403 account_inactive บัญชีลูกค้าถูกปิดใช้งาน
403 missing_ability คีย์นี้ไม่มีสิทธิ์ทำงานนี้
403 account_expired บัญชีหมดอายุ สร้างอีเมลเพิ่มไม่ได้ (ยังดูข้อมูลเดิมได้ แต่ไม่เห็นข้อความที่เข้ามาหลังวันหมดอายุจนกว่าจะต่ออายุ)
403 quota_exceeded ใช้อีเมลครบโควตาแพ็กเกจแล้ว
404 email_not_found ไม่พบอีเมลนี้ในบัญชี
404 message_not_found ไม่พบข้อความนี้ในบัญชี
404 not_found ไม่มีเส้นทาง API นี้
405 method_not_allowed ใช้ method ผิด เช่น ส่ง GET ไปยังเส้นที่ต้องเป็น POST
422 validation_failed ข้อมูลที่ส่งมาไม่ถูกต้อง ดูรายละเอียดใน errors
429 too_many_requests เรียกถี่เกินกำหนด รอตามเวลาใน header Retry-After

เรียกถี่เกินกำหนดจะได้ HTTP 429 พร้อม header Retry-After (วินาที) และคีย์จะถูกพักชั่วคราว 10 นาที ควรรอตามเวลานั้นก่อนเรียกใหม่

Webhook แจ้งอีเมลใหม่

แทนการเรียก API ถามซ้ำ ๆ ให้ระบบเราแจ้งไปที่ URL ของคุณทันทีที่มีอีเมลใหม่เข้ากล่องใดก็ได้ในบัญชี แจ้ง URL ปลายทางกับทีมงาน แล้วจะได้ webhook secret (ขึ้นต้นด้วย whsec_) ไว้ตรวจลายเซ็น

Header ความหมาย
X-JaideeMail-Event ชนิดเหตุการณ์ — message.received (อีเมลใหม่) หรือ ping (ทีมงานกดทดสอบ)
X-JaideeMail-Timestamp เวลาที่ส่ง (Unix timestamp วินาที)
X-JaideeMail-Signature sha256= ตามด้วย HMAC-SHA256 ของ "{timestamp}.{body}" ด้วย webhook secret
ตัวอย่างข้อมูลที่ส่งไป (POST JSON)
{
    "event": "message.received",
    "id": "9d4c7f3e-2b1a-4f63-9a0e-5c8d2e7b1f40",
    "sent_at": "2026-10-08T09:41:28+07:00",
    "data": {
        "id": 345,
        "email": {
            "id": 12,
            "address": "worker001@jaideemail.com",
            "type": "employee",
            "label": "สมชาย ใจดี"
        },
        "from": {
            "address": "noreply@doe.go.th",
            "name": "กรมการจัดหางาน"
        },
        "subject": "รหัสยืนยันตัวตน (OTP)",
        "preview": "รหัส OTP ของคุณคือ 482913 ใช้ได้ภายใน 5 นาที",
        "otp_code": "482913",
        "is_read": false,
        "read_at": null,
        "received_at": "2026-10-08T09:41:27+07:00",
        "body": "รหัส OTP ของคุณคือ 482913\nใช้ได้ภายใน 5 นาที",
        "api_url": "https://jaideemail.com/api/v1/messages/345"
    }
}
  • ตอบ HTTP 2xx ภายใน 5 วินาที งานที่ใช้เวลานานให้ทำต่อเบื้องหลัง
  • ระบบส่งครั้งเดียวไม่ส่งซ้ำ ถ้าปลายทางล่ม ให้ดึงย้อนหลังด้วย GET /messages?since=...
  • ใช้ id ของเหตุการณ์กันการบันทึกซ้ำ และตรวจลายเซ็นทุกครั้งก่อนเชื่อข้อมูล
ตรวจลายเซ็น · PHP
<?php
$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_JAIDEEMAIL_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_JAIDEEMAIL_SIGNATURE'] ?? '';
$secret = getenv('JAIDEEMAIL_WEBHOOK_SECRET');

$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);

// ลายเซ็นต้องตรง และคำขอต้องไม่เก่ากว่า 5 นาที (กันการยิงซ้ำ)
if (! hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);

if ($event['event'] === 'message.received') {
    $address = $event['data']['email']['address'];
    $otp = $event['data']['otp_code']; // อาจเป็น null ถ้าในอีเมลไม่มีรหัส
    // ... บันทึกหรือใช้งานต่อ
}

http_response_code(200);
ตรวจลายเซ็น · Node.js
import crypto from 'node:crypto';
import express from 'express';

const app = express();

// ต้องใช้ body ดิบ (ไม่แปลงเป็น JSON ก่อน) ลายเซ็นถึงจะตรง
app.post('/jaideemail/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const timestamp = req.get('X-JaideeMail-Timestamp') ?? '';
  const signature = req.get('X-JaideeMail-Signature') ?? '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.JAIDEEMAIL_WEBHOOK_SECRET)
    .update(`${timestamp}.${req.body}`)
    .digest('hex');

  const valid = signature.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

  if (!valid || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
    return res.sendStatus(401);
  }

  const event = JSON.parse(req.body);

  if (event.event === 'message.received') {
    console.log('อีเมลใหม่ถึง', event.data.email.address, 'OTP:', event.data.otp_code);
  }

  res.sendStatus(200);
});

app.listen(3000);

ตัวอย่าง: สร้างอีเมลแล้วรอรหัส OTP

งานที่ใช้บ่อยที่สุด — สร้างอีเมลให้แรงงาน เอาไปกรอกที่เว็บปลายทาง แล้วรอรหัส OTP ที่ส่งเข้ามา

Node.js
// Node.js 18 ขึ้นไป (มี fetch ในตัว)
const BASE_URL = 'https://jaideemail.com/api/v1';
const API_KEY = process.env.JAIDEEMAIL_API_KEY; // เก็บคีย์ไว้ฝั่งเซิร์ฟเวอร์เท่านั้น

async function api(method, path, body) {
  const res = await fetch(BASE_URL + path, {
    method,
    headers: {
      'X-Api-Key': API_KEY,
      'Accept': 'application/json',
      ...(body ? { 'Content-Type': 'application/json' } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const json = await res.json();
  if (!res.ok) throw new Error(`${json.code}: ${json.message}`);
  return json;
}

// 1) สร้างอีเมลให้แรงงาน
const { data: email } = await api('POST', '/emails', {
  address: 'worker001',
  type: 'employee',
  label: 'สมชาย ใจดี',
});

// 2) จดเวลาไว้ แล้วไปกดขอรหัส OTP ที่เว็บปลายทางด้วยอีเมลนี้
const since = new Date().toISOString();

// 3) รอรหัส OTP สูงสุด 2 นาที (ถามทุก 3 วินาที)
for (let i = 0; i < 40; i++) {
  const { data: message } = await api(
    'GET',
    `/emails/${email.id}/messages/latest?since=${encodeURIComponent(since)}`,
  );
  if (message) {
    console.log('OTP:', message.otp_code, '| หัวข้อ:', message.subject);
    break;
  }
  await new Promise((resolve) => setTimeout(resolve, 3000));
}
PHP
<?php
// PHP 8 ขึ้นไป ใช้ cURL ที่มีมากับ PHP
const BASE_URL = 'https://jaideemail.com/api/v1';

function jaidee(string $method, string $path, ?array $body = null): array
{
    $ch = curl_init(BASE_URL . $path);
    $headers = ['X-Api-Key: ' . getenv('JAIDEEMAIL_API_KEY'), 'Accept: application/json'];

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);

    if ($body !== null) {
        $headers[] = 'Content-Type: application/json';
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $json = json_decode((string) curl_exec($ch), true);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($status >= 400) {
        throw new RuntimeException($json['code'] . ': ' . $json['message']);
    }

    return $json;
}

// 1) สร้างอีเมลให้แรงงาน
$email = jaidee('POST', '/emails', [
    'address' => 'worker001',
    'type' => 'employee',
    'label' => 'สมชาย ใจดี',
])['data'];

// 2) จดเวลาไว้ แล้วไปกดขอรหัส OTP ที่เว็บปลายทางด้วยอีเมลนี้
$since = date('c');

// 3) รอรหัส OTP สูงสุด 2 นาที (ถามทุก 3 วินาที)
for ($i = 0; $i < 40; $i++) {
    $message = jaidee('GET', "/emails/{$email['id']}/messages/latest?since=" . urlencode($since))['data'];

    if ($message) {
        echo 'OTP: ' . $message['otp_code'];
        break;
    }

    sleep(3);
}