Tích hợp API

Mailemdi cung cấp bộ Public API v1 đầy đủ để bạn kết nối hệ thống của mình — quản lý liên hệ, gửi chiến dịch, ghi danh automation, gửi email giao dịch và nhận sự kiện qua webhook. Mọi dữ liệu đều được giới hạn trong phạm vi workspace của API key.

Xác thực & lấy API key

Mọi request đều xác thực qua header X-API-Key. Lấy khóa tại Cài đặt → API keys trong bảng điều khiển. Khóa chỉ hiển thị đầy đủ một lần khi tạo — hãy lưu lại nơi an toàn và không để lộ ở phía trình duyệt.

curl https://app.mailemdi.io.vn/api/v1/stats \
  -H "X-API-Key: <API_KEY_CỦA_BẠN>"

Thiếu hoặc sai khóa sẽ trả về 401 với thân phản hồi{ "error": "...", "code": "INVALID_API_KEY" }.

Giới hạn tần suất

Tối đa 120 request/phút cho mỗi API key. Vượt hạn mức sẽ bị từ chối — hãy thêm cơ chế chờ & thử lại (backoff) ở phía bạn.

Base URL & phản hồi

Tất cả endpoint nằm dưới /api/v1. Phản hồi luôn bọc trong { "data": ... }; các endpoint danh sách kèm thêm pagination (page, limit, total, pages).

Các nhóm endpoint

API v1 gồm các nhóm sau. Dấu · chỉ rằng cùng một đường dẫn hỗ trợ nhiều phương thức.

Liên hệ

Liệt kê, tạo (đơn lẻ hoặc hàng loạt ≤1000/lần), xem, cập nhật và xóa liên hệ.

  • GET /contacts
  • POST /contacts
  • POST /contacts/bulk
  • GET·PATCH·DELETE /contacts/{id}

Chiến dịch

Liệt kê, xem chi tiết kèm số liệu mở/click/bounce, và kích hoạt gửi.

  • GET /campaigns
  • GET /campaigns/{id}
  • POST /campaigns/{id}/send

Danh sách

Tạo/xóa danh sách và thêm/bớt liên hệ trong từng danh sách.

  • GET·POST /lists
  • GET·DELETE /lists/{id}
  • GET·POST·DELETE /lists/{id}/contacts

Phân khúc

Đọc các phân khúc (segment) đã định nghĩa trong workspace.

  • GET /segments
  • GET /segments/{id}

Mẫu email

Quản lý mẫu email; xem 1 mẫu trả về đầy đủ HTML.

  • GET·POST /templates
  • GET·PATCH·DELETE /templates/{id}

Thẻ

Tạo, liệt kê, xem và xóa thẻ (tag) gắn vào liên hệ.

  • GET·POST /tags
  • GET·DELETE /tags/{id}

Automation

Liệt kê automation, xem các bước và ghi danh liên hệ vào luồng.

  • GET /automations
  • GET /automations/{id}
  • POST /automations/{id}/enroll

Email giao dịch

Gửi email giao dịch (transactional) theo từng yêu cầu và xem lịch sử gửi.

  • POST /transactional
  • GET /transactional/logs

Webhook

Đăng ký, cập nhật, xóa webhook nhận sự kiện theo thời gian thực.

  • GET·POST /webhooks
  • PATCH·DELETE /webhooks/{id}

Suppression

Quản lý danh sách chặn gửi (hard bounce, khiếu nại, thủ công).

  • GET·POST /suppressions
  • DELETE /suppressions/{id}

Thống kê

Số liệu tổng quan của workspace trong một lời gọi.

  • GET /stats

Ví dụ thực tế

Lấy danh sách liên hệ

Hỗ trợ các tham số truy vấn page, limit (tối đa 200), statusq (tìm theo email).

curl "https://app.mailemdi.io.vn/api/v1/contacts?limit=50&q=gmail.com" \
  -H "X-API-Key: <API_KEY_CỦA_BẠN>"

# Phản hồi
{
  "data": [
    {
      "id": "ct_...",
      "email": "nguoinhan@example.com",
      "firstName": "An",
      "lastName": "Nguyễn",
      "company": "Công ty ABC",
      "status": "SUBSCRIBED",
      "engagementScore": 42,
      "createdAt": "2026-06-25T03:00:00.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 1, "pages": 1 }
}

Tạo một liên hệ mới

Chỉ email là bắt buộc; các trường khác (firstName, lastName, company, phone, source, customFields) tùy chọn. Email trùng sẽ trả 409DUPLICATE.

curl -X POST https://app.mailemdi.io.vn/api/v1/contacts \
  -H "X-API-Key: <API_KEY_CỦA_BẠN>" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "khachhang@example.com",
    "firstName": "An",
    "company": "Công ty ABC",
    "source": "website",
    "customFields": { "goi": "Pro" }
  }'

# Phản hồi 201
{ "data": { "id": "ct_...", "email": "khachhang@example.com", "status": "SUBSCRIBED" } }

Webhook

Đăng ký một URL để nhận sự kiện theo thời gian thực qua POST /webhooks (URL phải dùng http/https). Khi tạo, hệ thống sinh một secret dạng whsec_…chỉ trả về một lần duy nhất — hãy lưu lại để xác minh chữ ký. Các lần gọi GET sau chỉ thấy bản đã che.

curl -X POST https://app.mailemdi.io.vn/api/v1/webhooks \
  -H "X-API-Key: <API_KEY_CỦA_BẠN>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://he-thong-cua-ban.com/webhook",
    "events": ["email.opened", "email.clicked"]
  }'

# Phản hồi 201 — lưu lại "secret"!
{ "data": { "id": "wh_...", "url": "...", "events": ["email.opened","email.clicked"],
            "isActive": true, "secret": "whsec_..." } }

Xác minh chữ ký HMAC

Mỗi lần gửi, Mailemdi gắn header X-Webhook-Event X-Webhook-Signature dạng sha256=<hex>. Chữ ký là HMAC-SHA256 của nguyên văn thân JSON với khóa là secret của bạn. Hãy tính lại và so khớp trước khi tin payload. (Hệ thống thử lại tối đa 3 lần, mỗi lần chờ tối đa 5 giây.)

POST /webhook  HTTP/1.1
Content-Type: application/json
X-Webhook-Event: email.opened
X-Webhook-Signature: sha256=9f86d081...

{
  "event": "email.opened",
  "timestamp": "2026-06-25T03:00:00.000Z",
  "data": { "contactId": "ct_...", "email": "..." }
}

# Node.js — xác minh
import { createHmac } from "crypto";
const expected = "sha256=" + createHmac("sha256", WEBHOOK_SECRET)
  .update(rawBody)        // dùng đúng chuỗi thân thô, chưa parse
  .digest("hex");
const hopLe = expected === req.headers["x-webhook-signature"];

Các sự kiện hỗ trợ

  • contact.subscribedLiên hệ mới đăng ký / được tạo
  • contact.unsubscribedLiên hệ hủy đăng ký
  • email.sentEmail đã được gửi đi
  • email.openedNgười nhận mở email
  • email.clickedNgười nhận bấm liên kết
  • email.bouncedEmail bị trả về (bounce)

Tài liệu đầy đủ

Xem mô tả chi tiết từng endpoint, hoặc tải đặc tả OpenAPI 3.1 để import vào Postman, Insomnia hay Swagger.