Contacts, segments và topics
Trước khi gửi chiến dịch email, bạn cần biết gửi cho ai. Hạ Tầng tổ chức người nhận giống cách Resend đang làm:
- Contact: mỗi địa chỉ email là một contact duy nhất trong doanh nghiệp (không phân biệt hoa thường), có họ tên, thuộc tính tuỳ chỉnh và cờ "huỷ đăng ký mọi email".
- Segment: nhóm contact cố định để gửi chiến dịch email. Một contact thuộc được nhiều segment; xoá segment không xoá contact. Trước đây segment gọi là audience, và API
/audiencesvẫn chạy. - Topic: loại email, như khuyến mãi hay bản tin hằng tuần, mà từng người nhận tự chọn nhận hoặc bỏ trên trang tuỳ chọn.
Trong dashboard, mọi thứ nằm ở Email → Danh sách nhận, trong các tab Contacts, Segments, Topics, Thuộc tính và Danh sách chặn.
Trước khi bắt đầu
Các endpoint contact, segment, topic và thuộc tính cần key có email:write.
Thêm contact
- cURL
- Node.js
- Python
- PHP
curl -X POST https://api.hatang.dev/contacts \
-H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"first_name": "Lan",
"last_name": "Trần",
"properties": { "plan": "pro" },
"segments": [{ "id": "aud_0199e6c17a2b7f009c1e3f6a2b1d9e10" }],
"topics": [{ "id": "topic_0199e6c17a2c7c418f0e61f1b2a3c4d5", "subscription": "opt_in" }]
}'
# { "object": "contact", "id": "con_…" }
const { data, error } = await hatang.contacts.create({
first_name: "Lan",
last_name: "Trần",
properties: { plan: "pro" },
segments: [{ id: "aud_0199e6c17a2b7f009c1e3f6a2b1d9e10" }],
topics: [{ id: "topic_0199e6c17a2c7c418f0e61f1b2a3c4d5", subscription: "opt_in" }],
});
requests.post(
"https://api.hatang.dev/contacts",
headers={"Authorization": f"Bearer {os.environ['HATANG_API_KEY']}"},
json={
"first_name": "Lan",
"properties": {"plan": "pro"},
"segments": [{"id": "aud_0199e6c17a2b7f009c1e3f6a2b1d9e10"}],
},
)
$client->post('/contacts', [
'headers' => ['Authorization' => 'Bearer ' . getenv('HATANG_API_KEY')],
'json' => [
'first_name' => 'Lan',
'properties' => ['plan' => 'pro'],
'segments' => [['id' => 'aud_0199e6c17a2b7f009c1e3f6a2b1d9e10']],
],
]);
| Trường | Mô tả |
|---|---|
email | Bắt buộc. Không trùng trong doanh nghiệp. |
first_name, last_name | Mỗi trường tối đa 100 ký tự. |
unsubscribed | true huỷ đăng ký mọi email cho contact. |
properties | Giá trị của các thuộc tính đã khai báo. null xoá một giá trị. |
segments | Tối đa 50 { "id" } để thêm contact vào. |
topics | Tối đa 50 cặp { "id", "subscription" }, trong đó subscription là opt_in hoặc opt_out. |
POST /contacts tạo contact, hoặc cập nhật nếu địa chỉ đã tồn tại, và trả về id. Webhook contact.created, contact.updated và contact.deleted bắn khi contact thay đổi. Contact mới cũng khởi động các automation dùng sự kiện hatang:contact.created; xem Automations.
Trong dashboard bạn cũng có thể Thêm liên hệ từng người hoặc Nhập CSV. Dòng đầu của CSV là tiêu đề cột, gồm các cột tuỳ chọn: email, first_name, last_name, unsubscribed và khoá các thuộc tính của bạn. Cột lạ bị bỏ qua, địa chỉ đã có thì được cập nhật. Khách hàng trong CRM cũng đồng bộ sang được (Khách hàng → Đồng bộ sang Email); đồng bộ không bao giờ đăng ký lại cho người đã huỷ đăng ký.
Thuộc tính tuỳ chỉnh
Khai báo thuộc tính trước khi gán cho contact. Thuộc tính có kiểu string hoặc number, kèm giá trị dự phòng tuỳ chọn:
curl -X POST https://api.hatang.dev/contact-properties \
-H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
-d '{ "key": "plan", "type": "string", "fallback_value": "free" }'
- Khoá gồm chữ, số và
_, tối đa 50 ký tự. Giá trị chuỗi tối đa 2.000 ký tự. - Gán thuộc tính chưa khai báo trả về
422. Thuộc tínhnumbertừ chối giá trị không phải số. - Về sau chỉ đổi được giá trị dự phòng (
PATCH /contact-properties/{id}). Xoá thuộc tính sẽ xoá giá trị đó khỏi mọi contact.
Dùng thuộc tính trong chiến dịch email và email của automation dạng {{{contact.plan}}}, cùng với {{{contact.first_name}}}, {{{contact.last_name}}} và {{{contact.email}}}. Contact chưa có giá trị thì lấy giá trị mặc định tại chỗ ({{{contact.plan|free}}}), rồi tới giá trị dự phòng của thuộc tính.
Segments
curl -X POST https://api.hatang.dev/segments \
-H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "Khách hàng 2026" }'
# { "object": "segment", "id": "aud_…", "name": "Khách hàng 2026", "created_at": "…" }
curl -X POST https://api.hatang.dev/contacts/[email protected]/segments/aud_0199e6c17a2b7f009c1e3f6a2b1d9e10 \
-H "Authorization: Bearer $HATANG_API_KEY"
Tên segment tối đa 100 ký tự. Id segment bắt đầu bằng aud_, vì segment chính là audience trước đây.
Topics và trang tuỳ chọn
curl -X POST https://api.hatang.dev/topics \
-H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "Khuyến mãi", "description": "Giảm giá và mã ưu đãi", "default_subscription": "opt_in", "visibility": "public" }'
| Trường | Mô tả |
|---|---|
name | Tối đa 50 ký tự. |
description | Tối đa 200 ký tự, hiện trên trang tuỳ chọn. |
default_subscription | opt_in: contact nhận cho tới khi tự bỏ. opt_out: contact chỉ nhận sau khi tự đăng ký. Không đổi được sau khi tạo. |
visibility | public hiện topic cho mọi người trên trang tuỳ chọn. private (mặc định) chỉ hiện với contact đang nhận topic đó. |
Topic lọc thư như sau:
- Chiến dịch email có
topic_idchỉ tới những contact đang nhận topic đó. POST /emailscótopic_idbỏ qua người nhận đã rời topic; họ được ghi nhận là bị chặn (suppressed). Địa chỉ chưa là contact thì theo giá trị mặc định của topic.- Lựa chọn của một contact xem ở
GET /contacts/{id}/topicsvà đổi bằngPATCH /contacts/{id}/topics:
-H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
-d '[{ "id": "topic_0199e6c17a2c7c418f0e61f1b2a3c4d5", "subscription": "opt_out" }]'
Link {{{UNSUBSCRIBE_URL}}} trong chiến dịch email mở trang tuỳ chọn, nơi người nhận bật tắt từng topic hoặc huỷ đăng ký mọi email. Chỉ mở trang thì không thay đổi gì, nên các bộ quét link không vô tình huỷ đăng ký ai. Trang hiển thị tiếng Anh nếu trình duyệt ưu tiên tiếng Anh, còn lại là tiếng Việt. Đặt tiêu đề, mô tả, logo và màu ở Cài đặt email → Trang huỷ đăng ký. Cách huỷ đăng ký một chạm hoạt động xem ở Chiến dịch email.
Tham chiếu API
| Endpoint | Mô tả |
|---|---|
POST /contacts, GET /contacts | Tạo hoặc cập nhật contact; liệt kê contact (limit, after, segment_id, q). |
GET, PATCH, DELETE /contacts/{id hoặc email} | Một contact. |
GET /contacts/{id}/segments, POST hoặc DELETE /contacts/{id}/segments/{segment_id} | Thành viên segment. |
GET, PATCH /contacts/{id}/topics | Lựa chọn topic. |
POST /segments, GET /segments, GET, PATCH, DELETE /segments/{id}, GET /segments/{id}/contacts | Segment. GET /segments/{id} có thêm contact_count. |
POST /topics, GET /topics, GET, PATCH, DELETE /topics/{id} | Topic. |
POST /contact-properties, GET /contact-properties, PATCH, DELETE /contact-properties/{id} | Thuộc tính. |
/audiences, /audiences/{id}/contacts | API audience cũ, giữ lại cho các client Resend và Hạ Tầng đang dùng. Một audience là một segment. |
SDK Node.js có các lệnh tương ứng trong hatang.contacts, hatang.segments, hatang.topics, hatang.contactProperties và hatang.audiences.