Mailketing API v2 v2.0.2
Kirim email transaksional, cek kredit, kelola sender, list subscriber, dan tambah subscriber — melalui satu API REST yang sederhana.
https://api.mailketing.co.id/api/v2
# Authentication
Semua endpoint memerlukan API token. Token bisa dikirim melalui 4 cara berikut (sesuai prioritas):
| Priority | Metode | Contoh |
|---|---|---|
| 1 | Header Authorization: Bearer <token> | -H "Authorization: Bearer xxx" |
| 2 | Header X-Api-Token | -H "X-Api-Token: xxx" |
| 3 | Query param ?api_token= | ?api_token=xxx |
| 4 | JSON body {"api_token": "xxx"} | -d '{"api_token":"xxx"}' |
# Response Format
Semua response mengikuti format standar berikut:
| Field | Type | Selalu Ada | Deskripsi |
|---|---|---|---|
success | boolean | Ya | true untuk sukses, false untuk error |
data | object / null | Ya | Payload response (null jika error) |
message | string | Ya | Pesan yang bisa dibaca manusia |
errors | object | Tidak | Hanya ada saat validasi gagal. Key = field, value = pesan error |
{
"success": true,
"data": { ... },
"message": "OK"
}
{
"success": false,
"data": null,
"message": "Validation failed",
"errors": {
"email": "Email must be a valid email"
}
}
# Rate Limiting
Rate limiting hanya diterapkan pada request yang gagal (misalnya token invalid atau validasi input gagal). Request yang sukses tidak di-rate limit.
| Jenis Request | Maksimal | Per |
|---|---|---|
| Request gagal (401 / 402 / 403 / 404 / 422 / 500) | 30 | menit per IP |
Response headers saat rate limit: X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After
# Endpoints
Berikut kelima endpoint yang tersedia. Setiap contoh dapat disalin dalam berbagai bahasa.
Mengirim email transaksional via SMTP relay. Domain pengirim harus sudah diverifikasi di Mailketing.
Request
curl -X POST "https://api.mailketing.co.id/api/v2/send" \
-H "Content-Type: application/json" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-d '{
"from_name": "John Doe",
"from_email": "john@verified-domain.com",
"subject": "Hello World",
"recipient": "target@example.com",
"content": "<html><body><h1>Hello</h1><p>Email content</p></body></html>"
}'
<?php
$payload = [
'from_name' => 'John Doe',
'from_email' => 'john@verified-domain.com',
'subject' => 'Hello World',
'recipient' => 'target@example.com',
'content' => '<html><body><h1>Hello</h1></body></html>',
];
$ch = curl_init('https://api.mailketing.co.id/api/v2/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: YOUR_API_TOKEN',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch('https://api.mailketing.co.id/api/v2/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN',
},
body: JSON.stringify({
from_name: 'John Doe',
from_email: 'john@verified-domain.com',
subject: 'Hello World',
recipient: 'target@example.com',
content: '<html><body><h1>Hello</h1></body></html>',
}),
});
const data = await response.json();
console.log(data);
const res = await fetch('https://api.mailketing.co.id/api/v2/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN',
},
body: JSON.stringify({
from_name: 'John Doe',
from_email: 'john@verified-domain.com',
subject: 'Hello World',
recipient: 'target@example.com',
content: '<html><body><h1>Hello</h1></body></html>',
}),
});
const data = await res.json();
console.log(data);
import requests
url = "https://api.mailketing.co.id/api/v2/send"
headers = {
"Content-Type": "application/json",
"X-Api-Token": "YOUR_API_TOKEN",
}
payload = {
"from_name": "John Doe",
"from_email": "john@verified-domain.com",
"subject": "Hello World",
"recipient": "target@example.com",
"content": "<html><body><h1>Hello</h1></body></html>",
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Request Fields
| Field | Required | Type | Max | Deskripsi |
|---|---|---|---|---|
from_name | Ya | string | 255 | Nama pengirim |
from_email | Ya | 255 | Email pengirim — domain harus terverifikasi di Mailketing | |
subject | Ya | string | 998 | Subject email |
recipient | Ya | 255 | Email penerima | |
content | Ya | string | 300KB | Konten email. HTML (mengandung <html>) = unlimited, Plain text = max 300KB |
attach1 | Tidak | url | - | URL attachment 1 (di-download server lalu di-attach ke email) |
attach2 | Tidak | url | - | URL attachment 2 |
attach3 | Tidak | url | - | URL attachment 3 |
message_id otomatis untuk setiap email (format <api.{random}@sender-domain>) dan mengembalikannya di response data.message_id. Jika field message_id tetap dikirim, nilainya diabaikan. Simpan nilai dari response untuk mencocokkan event webhook (open, bounce).Success Response (200)
{
"success": true,
"data": {
"message_id": "<api.a1b2c3d4e5f67890123456@verified-domain.com>"
},
"message": "Email queued successfully"
}
Error Responses
| HTTP | Message | Penyebab |
|---|---|---|
| 401 | Invalid API token | Token tidak ditemukan / salah |
| 402 | Insufficient credits | Kredit habis, silakan top-up |
| 403 | Unknown sender domain | Domain from_email belum diverifikasi di menu Add Domain |
| 422 | Validation failed | Input tidak valid — cek field errors untuk detail |
| 429 | Rate limit exceeded | Terlalu banyak request gagal (30 gagal/menit per IP) |
Mendapatkan sisa kredit akun.
Request
curl "https://api.mailketing.co.id/api/v2/credits?api_token=YOUR_API_TOKEN"
# Alternatif via header
curl "https://api.mailketing.co.id/api/v2/credits" \
-H "X-Api-Token: YOUR_API_TOKEN"
<?php
$ch = curl_init('https://api.mailketing.co.id/api/v2/credits');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Token: YOUR_API_TOKEN'],
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch(
'https://api.mailketing.co.id/api/v2/credits',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await response.json();
console.log(data);
const res = await fetch(
'https://api.mailketing.co.id/api/v2/credits',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await res.json();
console.log(data);
import requests
url = "https://api.mailketing.co.id/api/v2/credits"
headers = {"X-Api-Token": "YOUR_API_TOKEN"}
response = requests.get(url, headers=headers)
print(response.json())
Success Response (200)
{
"success": true,
"data": {
"credits": 1500,
"email": "user@example.com"
},
"message": "OK"
}
Mendapatkan semua email pengirim yang sudah diverifikasi untuk akun ini.
Request
curl "https://api.mailketing.co.id/api/v2/senders?api_token=YOUR_API_TOKEN"
<?php
$ch = curl_init('https://api.mailketing.co.id/api/v2/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Token: YOUR_API_TOKEN'],
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch(
'https://api.mailketing.co.id/api/v2/senders',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await response.json();
console.log(data);
const res = await fetch(
'https://api.mailketing.co.id/api/v2/senders',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await res.json();
console.log(data);
import requests
url = "https://api.mailketing.co.id/api/v2/senders"
headers = {"X-Api-Token": "YOUR_API_TOKEN"}
response = requests.get(url, headers=headers)
print(response.json())
Success Response (200)
{
"success": true,
"data": {
"senders": [
{ "email": "noreply@domain-a.com" },
{ "email": "support@domain-b.com" }
]
},
"message": "OK"
}
Mendapatkan semua list subscriber milik akun (tidak termasuk list internal "ALL CONTACT").
Request
curl "https://api.mailketing.co.id/api/v2/lists?api_token=YOUR_API_TOKEN"
<?php
$ch = curl_init('https://api.mailketing.co.id/api/v2/lists');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Token: YOUR_API_TOKEN'],
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch(
'https://api.mailketing.co.id/api/v2/lists',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await response.json();
console.log(data);
const res = await fetch(
'https://api.mailketing.co.id/api/v2/lists',
{ headers: { 'X-Api-Token': 'YOUR_API_TOKEN' } }
);
const data = await res.json();
console.log(data);
import requests
url = "https://api.mailketing.co.id/api/v2/lists"
headers = {"X-Api-Token": "YOUR_API_TOKEN"}
response = requests.get(url, headers=headers)
print(response.json())
Success Response (200)
{
"success": true,
"data": {
"lists": [
{ "list_id": 1, "list_name": "Newsletter" },
{ "list_id": 2, "list_name": "Pelanggan VIP" },
{ "list_id": 3, "list_name": "Leads Facebook" }
]
},
"message": "OK"
}
list_id dari response ini untuk endpoint POST /subscribers.Menambahkan subscriber ke list. Jika email sudah ada di list tersebut, return status already_exists (tetap HTTP 200, bukan error).
Request
curl -X POST "https://api.mailketing.co.id/api/v2/subscribers" \
-H "Content-Type: application/json" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-d '{
"list_id": 1,
"email": "subscriber@example.com",
"first_name": "John",
"last_name": "Doe",
"mobile": "08123456789",
"birth_date": "1990-01-15",
"city": "Jakarta",
"country": "Indonesia"
}'
<?php
$payload = [
'list_id' => 1,
'email' => 'subscriber@example.com',
'first_name' => 'John',
'last_name' => 'Doe',
'mobile' => '08123456789',
'city' => 'Jakarta',
];
$ch = curl_init('https://api.mailketing.co.id/api/v2/subscribers');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: YOUR_API_TOKEN',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const response = await fetch('https://api.mailketing.co.id/api/v2/subscribers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN',
},
body: JSON.stringify({
list_id: 1,
email: 'subscriber@example.com',
first_name: 'John',
last_name: 'Doe',
mobile: '08123456789',
city: 'Jakarta',
}),
});
const data = await response.json();
console.log(data);
const res = await fetch('https://api.mailketing.co.id/api/v2/subscribers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN',
},
body: JSON.stringify({
list_id: 1,
email: 'subscriber@example.com',
first_name: 'John',
last_name: 'Doe',
mobile: '08123456789',
city: 'Jakarta',
}),
});
const data = await res.json();
console.log(data);
import requests
url = "https://api.mailketing.co.id/api/v2/subscribers"
headers = {
"Content-Type": "application/json",
"X-Api-Token": "YOUR_API_TOKEN",
}
payload = {
"list_id": 1,
"email": "subscriber@example.com",
"first_name": "John",
"last_name": "Doe",
"mobile": "08123456789",
"city": "Jakarta",
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Request Fields
| Field | Required | Type | Max | Deskripsi |
|---|---|---|---|---|
list_id | Ya | integer | - | ID list tujuan (dari GET /lists) |
email | Ya | 255 | Email subscriber | |
first_name | Tidak | string | 255 | Nama depan — hanya alphanumeric & spasi |
last_name | Tidak | string | 255 | Nama belakang — hanya alphanumeric & spasi |
mobile | Tidak | string | 30 | Nomor HP — auto-normalize ke format 628... |
birth_date | Tidak | date | - | Format YYYY-MM-DD |
city | Tidak | string | 100 | Kota |
country | Tidak | string | 100 | Negara |
company | Tidak | string | 255 | Perusahaan |
post_code | Tidak | string | 20 | Kode pos |
state | Tidak | string | 100 | Provinsi / state |
title | Tidak | string | 100 | Title (Mr / Mrs / etc) |
phone | Tidak | string | 30 | Nomor telepon |
fax | Tidak | string | 30 | Nomor fax |
field_name dan value = string.Contoh:
"alamat_lengkap": "Jl. Sudirman No. 1"Mobile Normalization
Nomor yang dikirim akan dinormalisasi otomatis:
| Input | Output |
|---|---|
08123456789 | 628123456789 |
+62 812-3456-789 | 628123456789 |
8123456789 | 628123456789 |
Success Response — Subscriber Baru (200)
{
"success": true,
"data": {
"email_list_id": 123,
"list_id": 1,
"status": "added"
},
"message": "Subscriber added to list 1"
}
Success Response — Sudah Ada (200)
{
"success": true,
"data": {
"email_list_id": null,
"list_id": 1,
"status": "already_exists"
},
"message": "Subscriber already in list 1"
}
Error Responses
| HTTP | Message | Penyebab |
|---|---|---|
| 401 | Invalid API token | Token tidak ditemukan |
| 404 | List not found | list_id tidak ditemukan atau bukan milik akun ini |
| 422 | Validation failed | Input tidak valid — cek field errors |
| 429 | Rate limit exceeded | Terlalu banyak request gagal (30 gagal/menit per IP) |
# Corporate API
Corporate API adalah fitur khusus untuk akun dengan status bisnisapi = 1. Dengan Corporate API, kamu dapat menggunakan domain ESP milikmu sendiri sebagai relay pengiriman email.
Endpoint Corporate API hanya dapat diakses oleh akun yang memiliki
bisnisapi = 1. Hubungi support Mailketing untuk mengaktifkan fitur ini.
Prasyarat
- Akun dengan
bisnisapi = 1 - esp_domain sudah di-set melalui halaman Sender Information → tombol Set Default
- DNS record SPF dan DKIM sudah dikonfigurasi pada domain sender
Alur Verifikasi Domain
- Set
esp_domaindi dashboard (misal:balaschat.my.id) - Tambahkan SPF record pada domain sender:
include:spf.balaschat.my.id - Tambahkan CNAME record:
corp._domainkey.regrow.id→dkim.balaschat.my.id - Panggil
POST /corporate/verify-senderuntuk memverifikasi
# 1 · Verify Sender Domain
/api/v2/corporate/verify-sender
Memverifikasi konfigurasi DNS (SPF dan DKIM) untuk domain sender yang akan digunakan via Corporate API. Endpoint ini tidak mengirim email — hanya memvalidasi bahwa DNS sudah terkonfigurasi dengan benar.
Request Body
| Field | Type | Required | Deskripsi |
|---|---|---|---|
email | string | Ya | Email sender yang akan diverifikasi, misal contoh@regrow.id |
Contoh Request
curl -X POST "https://api.mailketing.co.id/api/v2/corporate/verify-sender" \
-H "Content-Type: application/json" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-d '{
"email": "contoh@regrow.id"
}'
<?php
$ch = curl_init('https://api.mailketing.co.id/api/v2/corporate/verify-sender');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: YOUR_API_TOKEN',
],
CURLOPT_POSTFIELDS => json_encode(['email' => 'contoh@regrow.id']),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
const res = await fetch('https://api.mailketing.co.id/api/v2/corporate/verify-sender', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN'
},
body: JSON.stringify({ email: 'contoh@regrow.id' })
});
const data = await res.json();
console.log(data);
import requests
response = requests.post(
'https://api.mailketing.co.id/api/v2/corporate/verify-sender',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={'email': 'contoh@regrow.id'}
)
print(response.json())
Response — Sukses (SPF & DKIM valid)
{
"success": true,
"data": {
"domain": "regrow.id",
"esp_domain": "balaschat.my.id",
"spf": {
"valid": true,
"found": "v=spf1 include:spf.balaschat.my.id ~all"
},
"dkim": {
"valid": true,
"host": "corp._domainkey.regrow.id"
}
},
"message": "Domain sender valid. Domain regrow.id siap digunakan untuk mengirimkan email via Corporate API."
}
Response — SPF tidak valid
{
"success": false,
"data": null,
"message": "Verifikasi domain gagal. Silahkan perbaiki konfigurasi DNS berikut: SPF: ...",
"errors": {
"domain": "regrow.id",
"esp_domain": "balaschat.my.id",
"spf": {
"valid": false,
"found": "v=spf1 ~all",
"guide": "Tambahkan atau update TXT record pada domain regrow.id dengan value: v=spf1 include:spf.balaschat.my.id ~all",
"suggested_value": "v=spf1 include:spf.balaschat.my.id ~all"
},
"dkim": {
"valid": true,
"host": "corp._domainkey.regrow.id"
}
}
}
Response — DKIM tidak valid
{
"success": false,
"data": null,
"message": "Verifikasi domain gagal. ...",
"errors": {
"domain": "regrow.id",
"esp_domain": "balaschat.my.id",
"spf": {
"valid": true,
"found": "v=spf1 include:spf.balaschat.my.id ~all"
},
"dkim": {
"valid": false,
"host": "corp._domainkey.regrow.id",
"guide": "Tambahkan CNAME record: host = corp._domainkey.regrow.id, value = dkim.balaschat.my.id",
"cname_host": "corp._domainkey.regrow.id",
"cname_value": "dkim.balaschat.my.id"
}
}
}
Response — Bukan akun corporate
{
"success": false,
"data": null,
"message": "Kamu tidak memiliki akses Corporate API. Fitur ini hanya tersedia untuk akun corporate."
}
Response — esp_domain belum di-set
{
"success": false,
"data": null,
"message": "esp_domain belum di-set. Silahkan set default ESP domain terlebih dahulu melalui dashboard Sender Information."
}
Panduan Setup DNS
| Type | Host | Value | Keterangan |
|---|---|---|---|
TXT |
regrow.id |
v=spf1 include:spf.<esp_domain> ~all |
Ganti <esp_domain> dengan nilai esp_domain kamu |
CNAME |
corp._domainkey.regrow.id |
dkim.<esp_domain> |
Selector yang digunakan: corp |
# 2 · Send Email
/api/v2/corporate/send
Mengirim email transaksional via Corporate API. Email di-queue ke sendemailcorv2. from_email harus menggunakan domain yang sama dengan esp_domain yang sudah di-set.
Request Body
| Field | Type | Required | Deskripsi |
|---|---|---|---|
from_name | string | Ya | Nama pengirim |
from_email | string | Ya | Email pengirim — domain harus match esp_domain |
subject | string | Ya | Subject email |
recipient | string | Ya | Email penerima |
content | string | Ya | Konten email (HTML atau plain text) |
attach1 | string (URL) | Tidak | URL attachment 1 |
attach2 | string (URL) | Tidak | URL attachment 2 |
attach3 | string (URL) | Tidak | URL attachment 3 |
Contoh Request
curl -X POST "https://api.mailketing.co.id/api/v2/corporate/send" \
-H "Content-Type: application/json" \
-H "X-Api-Token: YOUR_API_TOKEN" \
-d '{
"from_name": "John Doe",
"from_email": "john@regrow.id",
"subject": "Hello from Corporate API",
"recipient": "target@example.com",
"content": "<h1>Hello!</h1><p>Email via Corporate API.</p>"
}'
<?php
$ch = curl_init('https://api.mailketing.co.id/api/v2/corporate/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: YOUR_API_TOKEN',
],
CURLOPT_POSTFIELDS => json_encode([
'from_name' => 'John Doe',
'from_email' => 'john@regrow.id',
'subject' => 'Hello from Corporate API',
'recipient' => 'target@example.com',
'content' => '<h1>Hello!</h1><p>Email via Corporate API.</p>',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
const res = await fetch('https://api.mailketing.co.id/api/v2/corporate/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Token': 'YOUR_API_TOKEN'
},
body: JSON.stringify({
from_name: 'John Doe',
from_email: 'john@regrow.id',
subject: 'Hello from Corporate API',
recipient: 'target@example.com',
content: '<h1>Hello!</h1><p>Email via Corporate API.</p>'
})
});
console.log(await res.json());
import requests
response = requests.post(
'https://api.mailketing.co.id/api/v2/corporate/send',
headers={'X-Api-Token': 'YOUR_API_TOKEN'},
json={
'from_name': 'John Doe',
'from_email': 'john@regrow.id',
'subject': 'Hello from Corporate API',
'recipient': 'target@example.com',
'content': '<h1>Hello!</h1><p>Email via Corporate API.</p>'
}
)
print(response.json())
Response — Sukses
{
"success": true,
"data": {
"message_id": "<corp.a1b2c3d4e5f6@regrow.id>"
},
"message": "Email queued successfully via Corporate API"
}
Response — from_email domain tidak match esp_domain
{
"success": false,
"data": null,
"message": "from_email domain (gmail.com) harus match dengan esp_domain (regrow.id).",
"errors": {
"from_email": "Domain harus regrow.id"
}
}
# HTTP Status Codes
# Changelog
| Version | Tanggal | Perubahan |
|---|---|---|
| 2.0.2 | 2026-10-23 | message_id tidak bisa diisi sendiri (/send dan /corporate/send) — selalu dibuat otomatis oleh Mailketing dan dikembalikan di response |
| 2.0.1 | 2026-08-10 | Rate limiting diubah: hanya request gagal yang di-rate limit (30/menit per IP); request sukses tidak |
| 2.0.0 | 2026-08-10 | Initial release: send, credits, senders, lists, subscribers |