Mailketing API v2 v2.0.1

Kirim email transaksional, cek kredit, kelola sender, list subscriber, dan tambah subscriber — melalui satu API REST yang sederhana.

Base URL https://api.mailketing.co.id/api/v2

# Authentication

Semua endpoint memerlukan API token. Token bisa dikirim melalui 4 cara berikut (sesuai prioritas):

PriorityMetodeContoh
1Header Authorization: Bearer <token>-H "Authorization: Bearer xxx"
2Header X-Api-Token-H "X-Api-Token: xxx"
3Query param ?api_token=?api_token=xxx
4JSON body {"api_token": "xxx"}-d '{"api_token":"xxx"}'
Token kamu dapat diambil dari Dashboard Mailketing → menu API Integration. Jangan pernah membagikan token ke orang lain.

# Response Format

Semua response mengikuti format standar berikut:

FieldTypeSelalu AdaDeskripsi
successbooleanYatrue untuk sukses, false untuk error
dataobject / nullYaPayload response (null jika error)
messagestringYaPesan yang bisa dibaca manusia
errorsobjectTidakHanya 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 RequestMaksimalPer
Request gagal (401 / 402 / 403 / 404 / 422 / 500)30menit 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.

POST /send

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

FieldRequiredTypeMaxDeskripsi
from_nameYastring255Nama pengirim
from_emailYaemail255Email pengirim — domain harus terverifikasi di Mailketing
subjectYastring998Subject email
recipientYaemail255Email penerima
contentYastring300KBKonten email. HTML (mengandung <html>) = unlimited, Plain text = max 300KB
message_idTidakstring255Custom tracking ID. Jika kosong: auto-generate <api.{random}@sender-domain>. Jika diisi, otomatis dibungkus angle brackets (<my-id@domain>)
attach1Tidakurl-URL attachment 1 (di-download server lalu di-attach ke email)
attach2Tidakurl-URL attachment 2
attach3Tidakurl-URL attachment 3

Success Response (200)

{
  "success": true,
  "data": {
    "message_id": "<api.a1b2c3d4e5f67890123456@verified-domain.com>"
  },
  "message": "Email queued successfully"
}

Error Responses

HTTPMessagePenyebab
401Invalid API tokenToken tidak ditemukan / salah
402Insufficient creditsKredit habis, silakan top-up
403Unknown sender domainDomain from_email belum diverifikasi di menu Add Domain
422Validation failedInput tidak valid — cek field errors untuk detail
429Rate limit exceededTerlalu banyak request gagal (30 gagal/menit per IP)
GET /credits

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"
}
GET /senders

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"
}
GET /lists

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"
}
Tips: gunakan list_id dari response ini untuk endpoint POST /subscribers.
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

FieldRequiredTypeMaxDeskripsi
list_idYainteger-ID list tujuan (dari GET /lists)
emailYaemail255Email subscriber
first_nameTidakstring255Nama depan — hanya alphanumeric & spasi
last_nameTidakstring255Nama belakang — hanya alphanumeric & spasi
mobileTidakstring30Nomor HP — auto-normalize ke format 628...
birth_dateTidakdate-Format YYYY-MM-DD
cityTidakstring100Kota
countryTidakstring100Negara
companyTidakstring255Perusahaan
post_codeTidakstring20Kode pos
stateTidakstring100Provinsi / state
titleTidakstring100Title (Mr / Mrs / etc)
phoneTidakstring30Nomor telepon
faxTidakstring30Nomor fax
Custom fields: Jika list memiliki custom fields, kirimkan dengan key = field_name dan value = string.
Contoh: "alamat_lengkap": "Jl. Sudirman No. 1"

Mobile Normalization

Nomor yang dikirim akan dinormalisasi otomatis:

InputOutput
08123456789628123456789
+62 812-3456-789628123456789
8123456789628123456789

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

HTTPMessagePenyebab
401Invalid API tokenToken tidak ditemukan
404List not foundlist_id tidak ditemukan atau bukan milik akun ini
422Validation failedInput tidak valid — cek field errors
429Rate limit exceededTerlalu 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.

Akses Terbatas
Endpoint Corporate API hanya dapat diakses oleh akun yang memiliki bisnisapi = 1. Hubungi support Mailketing untuk mengaktifkan fitur ini.

Prasyarat

  1. Akun dengan bisnisapi = 1
  2. esp_domain sudah di-set melalui halaman Sender Information → tombol Set Default
  3. DNS record SPF dan DKIM sudah dikonfigurasi pada domain sender

Alur Verifikasi Domain

  1. Set esp_domain di dashboard (misal: balaschat.my.id)
  2. Tambahkan SPF record pada domain sender: include:spf.balaschat.my.id
  3. Tambahkan CNAME record: corp._domainkey.regrow.id → dkim.balaschat.my.id
  4. Panggil POST /corporate/verify-sender untuk memverifikasi

# 1 · Verify Sender Domain

POST /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

FieldTypeRequiredDeskripsi
emailstringYaEmail 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

TypeHostValueKeterangan
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
Tips: Perubahan DNS bisa memerlukan waktu propagasi hingga 24–48 jam. Gunakan tools seperti MXToolbox atau Google Dig untuk mengecek status record DNS sebelum memanggil endpoint ini.

# 2 · Send Email

POST /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

FieldTypeRequiredDeskripsi
from_namestringYaNama pengirim
from_emailstringYaEmail pengirim — domain harus match esp_domain
subjectstringYaSubject email
recipientstringYaEmail penerima
contentstringYaKonten email (HTML atau plain text)
message_idstringTidakCustom message ID untuk tracking (opsional)
attach1string (URL)TidakURL attachment 1
attach2string (URL)TidakURL attachment 2
attach3string (URL)TidakURL 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

200
OK
Request berhasil
204
No Content
OPTIONS preflight success
400
Bad Request
Request malformed
401
Unauthorized
API token missing atau invalid
402
Payment Required
Kredit habis
403
Forbidden
Sender domain tidak terverifikasi
404
Not Found
Resource tidak ditemukan
422
Unprocessable Entity
Validasi input gagal
429
Too Many Requests
Terlalu banyak request gagal — hanya request gagal yang di-rate limit (30/menit per IP)
500
Internal Server Error
Server error

# Changelog

VersionTanggalPerubahan
2.0.12026-08-10Rate limiting diubah: hanya request gagal yang di-rate limit (30/menit per IP); request sukses tidak
2.0.02026-08-10Initial release: send, credits, senders, lists, subscribers