REST API · v1

Một token. Mọi endpoint.

Một HTTP API gọn gàng, hướng resource cho campaign, list, subscriber, automation, sending server và billing khách hàng. Xác thực bằng một token duy nhất, truy vấn JSON, ship trong vài phút. API mà plugin dùng cũng chính là API mà client ngoài dùng — không có endpoint hạng hai.

Bạn có thể xây gì

SaaS frontend Mobile app Đồng bộ CRM Trigger automation Dashboard reseller
REQUEST POST /api/v1/campaigns HEADERS Authorization: Bearer ACELLE_TOKEN Content-Type: application/json BODY { "list_uid": "a3b9..." "name": "Welcome" "subject": "Hi friend" "from_name": "Acme" "from_email": "hi@..." "track_open": true "html": "<h1>…" } HTTPS your.acelle.com RESPONSE 200 OK { "campaign": { "uid": "abc123" "name": "Welcome" "subject": "Hi friend" "status": "ready" "track_open": true "created_at": "2026-05-06T…" "links": { "self": "/api/v1…" } } }

VÌ SAO LÀ API NÀY

Không bất ngờ. Không endpoint hạng hai.
Cùng API mà plugin của bạn dùng.

Auth bằng token

Mỗi request mang một bearer token duy nhất. Sinh ra theo từng user từ Profile → API token. Truyền qua header Authorization: Bearer hoặc query string ?api_token=. Thu hồi và xoay vòng bất cứ lúc nào.

Hướng resource

Mọi khái niệm là một resource với verb đoán được. GET /lists trả về collection, POST /lists tạo mới, PATCH /lists/:uid cập nhật, DELETE /lists/:uid xoá. Sub-resource lồng nhau tự nhiên: /lists/:uid/subscribers.

Giống hệt plugin dùng

Không có chia tách nội bộ-vs-bên ngoài. Endpoint mà UI của AcelleMail gọi, endpoint mà plugin của bạn mở rộng, và endpoint mà client ngoài đọc — y hệt nhau. Xem plugin SDK →

Endpoint tự host

Base URL là server của chính bạn — https://your-acelle.example.com/api/v1/. Không proxy nhà cung cấp, không rate limit dùng chung, không phí theo từng request. Throughput tuỳ phần cứng của bạn.

BẮT ĐẦU NHANH

Từ con số không tới response đầu tiên trong bốn bước.

Mỗi bản cài AcelleMail tự host API riêng tại /api/v1/. Thay your-acelle.example.com bằng hostname bản cài của bạn.

STEP 1

Tạo một token

Đăng nhập vào bản cài AcelleMail của bạn. Mở menu profile và nhấn API token. Copy giá trị — nó là duy nhất theo từng user và gắn với quyền của user đó.

# In your shell:
$ export ACELLE_TOKEN=paste-your-token-here
$ export ACELLE_BASE=https://your-acelle.example.com
STEP 2

Xác minh token

Gọi /me. Nếu token hợp lệ bạn nhận lại bản ghi user của mình. Nếu không, bạn nhận 401 — kiểm tra lại token và base URL.

$ curl $ACELLE_BASE/api/v1/me \
    -H "Authorization: Bearer $ACELLE_TOKEN"

{ "id": 1, "email": "you@…", "uid": "…" }
STEP 3

Tạo một list

Resource được tạo bằng POST. Các trường body bắt buộc cho một mailing list là name, from_email, from_name, subject, cộng một khối thông tin liên hệ.

$ curl -X POST $ACELLE_BASE/api/v1/lists \
    -H "Authorization: Bearer $ACELLE_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name":       "Newsletter",
      "from_name":  "Acme",
      "from_email": "hi@acme.com",
      "subject":    "Welcome"
    }'
STEP 4

Thêm một subscriber

Dùng UID của list từ bước 3. Custom field được truyền dưới dạng param viết hoa (FIRST_NAME, LAST_NAME, …) khớp với cấu hình field của list.

$ curl -X POST $ACELLE_BASE/api/v1/subscribers \
    -H "Authorization: Bearer $ACELLE_TOKEN" \
    -d list_uid=$LIST_UID \
    -d EMAIL=alice@example.com \
    -d FIRST_NAME=Alice \
    -d tag=newsletter,beta

RESOURCE

Tám resource. Hơn bốn mươi endpoint. Mọi verb bạn mong đợi.

Tất cả endpoint dưới đây nằm trong namespace /api/v1/ và yêu cầu xác thực token auth:api trừ khi ghi chú khác. Các thao tác vòng đời (run, pause, resume) được phơi ra dưới dạng sub-route POST. Tải log sẽ stream file CSV bên dưới.

Xác thực

Tất cả endpoint có xác thực chấp nhận token qua header Authorization: Bearer (ưu tiên) hoặc query parameter ?api_token= (legacy). Dùng POST /user/login để đổi email/password lấy token mới từ một client lập trình.

POST/user/loginĐổi email + password lấy một API token. Endpoint public.
GET/meTrả về bản ghi của user đã xác thực. Dùng cái này để xác minh một token.
POST/login-tokenSinh một URL đăng nhập một lần để user nhấn vào là vào thẳng trạng thái đã đăng nhập.

Lists

Mailing list là container chính cho subscriber. Mỗi list đi kèm một sender identity mặc định, custom field và thiết lập double-opt-in / welcome-email. Custom field được thêm bằng sub-route add-field.

GET/listsIndex phân trang của các list thuộc user của token.
POST/listsTạo một list mới. Bắt buộc: name, from_email, from_name, subject + khối liên hệ.
GET/lists/:uidLấy một list kèm field và số liệu thống kê.
PATCH/lists/:uidCập nhật metadata của list, sender identity hoặc thiết lập opt-in.
POST/lists/:uid/add-fieldThêm một custom field. Type là text, number hoặc datetime.
DELETE/lists/:uidXoá vĩnh viễn một list và toàn bộ subscriber của nó.

Subscribers

Subscriber thuộc về một list và mang giá trị custom field, tag, cùng lịch sử open/click. Status là một trong subscribed, unsubscribed hoặc unconfirmed. Thao tác tag mang tính cộng dồn và idempotent.

GET/subscribers?list_uid=…Index phân trang. Lọc với open=yes|no, click=yes|no.
POST/subscribersTạo. Bắt buộc: list_uid, EMAIL. Custom field dưới dạng param viết hoa.
GET/subscribers/:idLấy một subscriber theo id hoặc email.
GET/subscribers/email/:emailTìm mọi list có một subscriber với email này.
PATCH/subscribers/:idCập nhật field, tag hoặc status.
POST/subscribers/:id/add-tagThêm tag phân tách bằng dấu phẩy.
POST/subscribers/:id/remove-tagXoá tag phân tách bằng dấu phẩy.
PATCH/lists/:list_uid/subscribers/:id/subscribeĐánh dấu subscribed.
PATCH/lists/:list_uid/subscribers/:id/unsubscribeĐánh dấu unsubscribed.
PATCH/lists/:list_uid/subscribers/email/:email/unsubscribeUnsubscribe theo email khi bạn không có id.
DELETE/subscribers/:idXoá cứng khỏi list.

Campaigns

Campaign là đơn vị gửi. Tạo một campaign với nội dung HTML + tracking flag, chuyển qua các trạng thái run / pause / resume, rồi tải log tracking, open, click, bounce, feedback và unsubscribe dưới dạng CSV.

GET/campaignsIndex phân trang. Truyền per_page, page.
POST/campaignsTạo. Bắt buộc: list_uid, name, subject, from_*, html.
GET/campaigns/:uidLấy một campaign kèm số liệu thống kê.
PATCH/campaigns/:uidCập nhật nội dung, subject hoặc tracking flag.
POST/campaigns/:uid/runĐưa campaign vào hàng đợi để gửi.
POST/campaigns/:uid/pauseTạm dừng một campaign đang chạy.
POST/campaigns/:uid/resumeTiếp tục một campaign đang tạm dừng.
GET/campaigns/:uid/tracking-log/downloadStream file CSV tracking.
GET/campaigns/:uid/{open,click,bounce,feedback,unsubscribe}-log/downloadStream file CSV theo từng sự kiện (một route cho mỗi loại sự kiện).
DELETE/campaigns/:uidXoá một campaign (chỉ khi không đang chạy).

Automations

Automation là các luồng trực quan gồm trigger, condition và action. API phơi ra view đọc cộng hai cách kích hoạt luồng từ hệ thống ngoài: execute để chạy nguyên một automation, hoặc api/call để kích hoạt một node "API call" giữa luồng.

GET/automationsIndex các automation thuộc user của token.
POST/automations/:uid/executeKích hoạt một automation cho một subscriber. Hữu ích cho các luồng transactional.
POST/automations/:uid/api/callBắn một trigger node "API call" giữa luồng với payload tuỳ chỉnh.

Sending servers

Sending server là các transport cấu hình được (SMTP, Amazon SES, SendGrid, Mailgun, Postmark, driver tuỳ chỉnh từ plugin). Quản lý chúng theo lập trình khi cấp phát tenant mới hoặc xoay vòng credential.

GET/sending_serversIndex các sending server đã cấu hình.
POST/sending_serversTạo một sending server mới. Cấu hình theo driver nằm dưới settings.
GET/sending_servers/:uidLấy một sending server.
PATCH/sending_servers/:uidCập nhật settings hoặc xoay vòng credential.
DELETE/sending_servers/:uidGỡ một sending server (campaign tham chiếu tới nó phải được định tuyến lại trước).

Thêm một transport mới (Postal MTA, HTTP API tuỳ chỉnh, …) là một REGISTRY hook — ship nó dưới dạng plugin thay vì vá core.

Customers ADMIN

Endpoint Customer chỉ dành cho token admin. Dùng chúng để cấp phát tài khoản tenant, quản lý subscription, đổi plan, hoặc sinh URL đăng nhập một lần cho support/impersonation.

GET/customersIndex phân trang của tất cả customer.
POST/customersTạo một customer + tài khoản user mới.
GET/customers/by-email/:emailTra cứu một customer theo email.
PATCH/customers/:uidCập nhật profile / liên hệ / quota của customer.
PATCH/customers/:uid/{enable,disable}Tạm ngưng hoặc kích hoạt lại quyền truy cập mà không xoá dữ liệu.
POST/customers/:uid/change-plan/:plan_uidĐổi customer sang một plan khác (tính phí, prorate, gia hạn subscription).
POST/customers/:uid/assign-plan/:plan_uidGán một plan mà không qua luồng billing (admin ghi đè).
POST/customers/:uid/subscription/updateCập nhật tham số của một subscription đang hoạt động.
POST/login-tokenSinh một URL đăng nhập một lần cho customer mục tiêu.

Subscriptions ADMIN

Subscription gắn một customer với một plan + chu kỳ billing. Dùng các endpoint này khi tích hợp với hệ thống billing ngoài hoặc kiểm toán doanh thu định kỳ.

GET/subscriptionsIndex của tất cả subscription đang hoạt động.
POST/subscriptionsTạo một bản ghi subscription (thường do webhook gateway của bạn điều khiển).
GET/subscriptions/:uidLấy một subscription kèm lịch sử gia hạn.
PATCH/subscriptions/:uidĐiều chỉnh quota, chu kỳ hoặc ngày kết thúc.

Files

Tải lên hình ảnh và các asset khác để dùng trong nội dung campaign. Endpoint chấp nhận multipart/form-data và trả về một public URL bạn có thể tham chiếu trong body HTML.

POST/file/uploadTải lên một file. Trả về { "url": "..." }.

Plugin & nâng cấp ADMIN

Cài plugin theo lập trình từ một download URL, chạy nâng cấp core từ xa trong luồng request hai bước (để bước 2 chạy trên một PHP worker mới), hoặc làm mới license. Hữu ích cho người vận hành fleet quản lý nhiều tenant AcelleMail.

POST/plugins/installCài một plugin từ một download URL.
POST/upgrade/runBắt đầu một nâng cấp core từ xa (tải về + giải nén).
POST/upgrade/run-fileÁp dụng một bước migration.
POST/upgrade/finalizeHoàn tất một nâng cấp. Phải được gọi như một request mới sau run.
POST/license/refreshLàm mới thông tin license CodeCanyon (giống Admin → License).

WEBHOOK

Đẩy sự kiện ra, thay vì polling để lấy chúng.

AcelleMail cung cấp hai bề mặt webhook. Webhook vòng đời bắn khi customer + subscription + automation chuyển trạng thái và được cấu hình toàn cục. Ping tracking theo từng recipient bắn khi có open / click / unsubscribe và được cấu hình theo từng campaign. Cả hai đều retry khi thất bại với backoff theo cấp số nhân.

Webhook vòng đời

Chuyển trạng thái customer + subscription

Cấu hình một lần tại Admin → Settings → Webhooks. Mỗi webhook là một name + event + cấu hình HTTP gửi ra (URL, method, header, body template). Sáu sự kiện đi kèm trong core:

new_customerparams: customer_id
new_subscriptioncustomer_id, plan_id
change_plancustomer_id, old_plan_id, new_plan_id
cancel_subscriptioncustomer_id, plan_id
terminate_subscriptioncustomer_id, plan_id
automation_webhookautomation_id (bắn từ các node API call)

Chính sách retry theo từng webhook: retry_times cấu hình được (mặc định 2) và retry_after_seconds (mặc định 900). Lần gửi thất bại được ghi log, retry và hiển thị trong log webhook của admin.

Plugin có thể đăng ký thêm sự kiện qua pattern EVENT hook — ví dụ acelle/ai bắn ai_task_completed từ listener tuỳ chỉnh của nó.

Tracking theo từng recipient

Open, click, unsubscribe

Cấu hình theo từng campaign hoặc từng email-template tại Tracking → Webhooks. Ba loại sự kiện bắn khi recipient tương tác với message:

openrecipient đã mở email (tracking pixel)
clickrecipient đã nhấn một link được track
unsubscriberecipient đã nhấn link unsubscribe

Mỗi ping mang uid của campaign, email subscriber và URL được nhấn (với sự kiện click). Cấu hình bao nhiêu tracking webhook tuỳ bạn cần theo từng campaign — hữu ích để mirror song song tới analytics + CRM + data warehouse.

Sự kiện cấp sending-server (bounce, complaint, delivery) đi qua stack listener nội bộ App\SendingServers\Webhooks\* — hiển thị trong các endpoint log của campaign chứ không phải dưới dạng webhook gửi ra. Tải log CSV →

Ví dụ: payload new_subscription

POST /your-webhook-url
Content-Type: application/json
X-AcelleMail-Event: new_subscription
X-AcelleMail-Signature: sha256=…

{
  "event":       "new_subscription",
  "customer_id": 1234,
  "plan_id":     "extended-monthly",
  "fired_at":    "2026-05-06T12:34:56Z"
}

Ví dụ: payload tracking click

POST /your-webhook-url
Content-Type: application/json
X-AcelleMail-Event: click

{
  "event":         "click",
  "campaign_uid":  "abc123",
  "subscriber":    "alice@example.com",
  "url":           "https://acme.com/promo",
  "clicked_at":    "2026-05-06T12:34:56Z"
}

RESPONSE & LỖI

JSON đoán được. Status code theo quy ước.

Mọi response thành công đều là JSON. Mọi response thất bại đều là JSON, với một message ở cấp cao nhất và một map errors cho lỗi validation. Status code theo quy ước REST — bạn có thể rẽ nhánh client chỉ dựa trên code.

Code Khi nào bạn gặp
200 OKĐọc hoặc cập nhật thành công.
201 CreatedTạo thành công.
401 UnauthorizedThiếu hoặc token không hợp lệ.
403 ForbiddenToken hợp lệ, nhưng resource không phải của bạn / không phải admin.
404 Not FoundUID không tồn tại.
422 UnprocessableLỗi validation. Kiểm tra map errors trong body.
500 ServerLỗi phía server. Kiểm tra storage/logs/laravel.log.

Lỗi validation (422)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "message": "The given data was invalid.",
  "errors": {
    "from_email": [
      "The from_email field is required."
    ],
    "subject": [
      "The subject must be at most 998 characters."
    ]
  }
}

Lỗi xác thực (401)

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{ "message": "Unauthenticated." }

Pagination

Endpoint index chấp nhận per_page (mặc định 10–25 tuỳ resource) và page. Response bao gồm shape paginator chuẩn của Laravel: data[], links, meta.current_page, meta.total.

Rate limit

Rate limit là tuỳ bạn — thiết lập trên bản cài Laravel của bạn qua RouteServiceProvider. Bản dựng mặc định không có throttle API, vì bạn đang gọi server của chính mình. Thêm throttle:60,1 nếu bạn muốn.

Versioning

Phiên bản major hiện tại là v1. Endpoint mới được thêm thoải mái; thay đổi phá vỡ với endpoint hiện có sẽ ship dưới dạng v2 song song với v1. Pin client của bạn vào /api/v1/ là bạn ổn định.

CLIENT

Bất kỳ HTTP client nào. Không SDK độc quyền.

Không có SDK AcelleMail nào để cài. API nói JSON qua HTTP — dùng bất kỳ client nào stack của bạn đã có sẵn. Ba cái phổ biến nhất trong thực tế:

curl · câu lệnh một dòng

curl $ACELLE_BASE/api/v1/lists \
  -H "Authorization: Bearer $ACELLE_TOKEN" \
  | jq '.data[].name'

Laravel HTTP client

$resp = Http::withToken($token)
    ->baseUrl($base.'/api/v1')
    ->post('/subscribers', [
        'list_uid' => $listUid,
        'EMAIL'    => $email,
    ]);

return $resp->json();

Browser / Node fetch

const r = await fetch(
  `${base}/api/v1/campaigns/${uid}/run`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
    },
  }
);
const data = await r.json();

Đang xây một SDK open-source? Email cho chúng tôi — chúng tôi sẽ link nó từ trang này.

THAM CHIẾU CHÍNH THỐNG

Tham chiếu API đầy đủ, chạy được.

Mọi tham số. Mọi shape trả về. Mọi ví dụ curl chạy được. Host tại bản cài demo chính thống — cùng code mà bản cài của bạn chạy.

api.acellemail.com

Thay api.acellemail.com bằng hostname bản cài của chính bạn khi gọi.

BẮT ĐẦU XÂY DỰNG

Chạy AcelleMail. Lấy một token. Gọi một call.

License một lần. Source đầy đủ. Endpoint tự host. API đã bao gồm — không add-on, không gói rate.

Plugin SDK →