Rate limiting adalah mekanisme kontrol yang membatasi jumlah request ke API dalam periode waktu tertentu. Di Mailketing API v2, implementasi rate limiting sengaja dirancang berbeda dari kebanyakan API lain — memahami cara kerjanya akan membantu developer menghindari error 429 dan merancang integrasi yang lebih robust.
Cara Kerja Rate Limiting di Mailketing API v2
Perbedaan utama Mailketing API v2 dibanding API lain: rate limit hanya berlaku untuk request yang gagal, bukan semua request.
| Jenis Request | Batas | Window | Berlaku per |
|---|---|---|---|
| Request gagal (401/402/403/404/422/500) | 30 request | 1 menit | IP address |
| Request sukses (200) | Tidak dibatasi | — | — |
Artinya: jika sistem mengirim 10.000 email per jam dengan sukses, tidak akan kena rate limit sama sekali. Rate limit baru aktif jika ada bug atau kesalahan konfigurasi yang menyebabkan banyak request gagal berturut-turut.
Kenapa Hanya Request Gagal yang Di-rate Limit?
Desain ini melindungi server Mailketing dari dua skenario berbahaya:
- Credential stuffing — serangan yang mencoba ribuan kombinasi token API secara otomatis. Dengan rate limit di request gagal (401), serangan ini terhenti setelah 30 percobaan per menit per IP.
- Looping error di kode — bug di sisi developer yang menyebabkan retry tak terbatas untuk request yang memang akan selalu gagal (misalnya sender belum diverifikasi, kredit habis). Rate limit memaksa developer untuk memperbaiki root cause, bukan terus-terusan retry.
Untuk pengiriman email yang sah (request sukses), tidak ada throttling — sesuai dengan kebutuhan sistem email transaksional yang harus bisa mengirim dalam volume besar dan cepat.
Response Headers Rate Limit
Setiap response dari Mailketing API v2 menyertakan header berikut untuk membantu developer memantau status rate limit:
# Header di setiap response (sebelum kena limit)
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
# Header saat kena 429
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
Retry-After: 42Retry-After menunjukkan berapa detik harus menunggu sebelum boleh mencoba lagi. Nilainya dinamis tergantung kapan window 1 menit reset.
Contoh Response 429
{
"success": false,
"data": null,
"message": "Too Many Requests",
"errors": {}
}Implementasi Handling Rate Limit di Berbagai Bahasa
PHP
function sendEmailWithRetry(array $payload, int $maxRetries = 3): array {
$attempt = 0;
while ($attempt true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: ' . $_ENV['MAILKETING_TOKEN'],
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = json_decode(substr($response, $headerSize), true);
curl_close($ch);
if ($httpCode === 429) {
// Baca Retry-After dari header
preg_match('/Retry-After:s*(d+)/i', $headers, $matches);
$waitSeconds = isset($matches[1]) ? (int)$matches[1] : 60;
sleep($waitSeconds);
$attempt++;
continue;
}
return ['code' => $httpCode, 'body' => $body];
}
throw new RuntimeException('Max retries reached after rate limiting');
}JavaScript / Node.js
async function sendEmailWithRetry(payload, maxRetries = 3) {
for (let attempt = 0; attempt setTimeout(resolve, retryAfter * 1000));
continue;
}
return { code: res.status, body: await res.json() };
}
throw new Error('Max retries reached after rate limiting');
}Python
import requests
import time
import os
def send_email_with_retry(payload: dict, max_retries: int = 3) -> dict:
url = 'https://api.mailketing.co.id/api/v2/send'
headers = {
'Content-Type': 'application/json',
'X-Api-Token': os.environ['MAILKETING_TOKEN'],
}
for attempt in range(max_retries):
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f'Rate limited. Waiting {retry_after}s...')
time.sleep(retry_after)
continue
return {'code': response.status_code, 'body': response.json()}
raise Exception('Max retries reached after rate limiting')Best Practice Menghindari 429
Karena rate limit hanya berlaku untuk request gagal, strategi utama bukan soal membatasi kecepatan pengiriman — tapi memastikan request tidak gagal sejak awal:
- Validasi token sebelum deploy — pastikan environment variable
MAILKETING_TOKENter-set dengan benar di semua environment (development, staging, production) - Monitor saldo kredit — panggil
GET /creditssecara berkala, kirim alert internal jika kredit mendekati 0 untuk mencegah error 402 massal - Verifikasi sender sebelum go-live — pastikan semua
from_emailyang akan digunakan sudah berstatusverifiedviaGET /senders - Jangan retry tanpa kondisi — implementasikan circuit breaker: jika 5 request gagal berturut-turut dengan kode yang sama (misalnya 402), hentikan retry dan kirim alert ke tim
- Log semua error response — baca field
errorsdi response 422 untuk debug validasi input
Perbedaan Rate Limit Mailketing vs API Lain
| Aspek | API Umum | Mailketing API v2 |
|---|---|---|
| Yang di-rate limit | Semua request | Hanya request gagal |
| Dampak pada pengiriman normal | Bisa terhambat saat volume tinggi | Tidak terhambat |
| Tujuan utama | Proteksi server dari beban | Proteksi dari abuse dan looping error |
| Header informasi | X-RateLimit-Limit/Remaining | X-RateLimit-Limit/Remaining + Retry-After |
FAQ
Apakah rate limit berlaku per akun atau per IP?
Per IP address. Jika aplikasi di-deploy di beberapa server dengan IP berbeda, setiap IP mendapat kuota 30 request gagal per menit secara independen.
Apakah bisa request indexing ulang setelah kena 429?
Ya. Setelah window 1 menit reset, kuota request gagal kembali ke 30. Gunakan nilai Retry-After di response header untuk tahu kapan harus mencoba lagi.
Apakah kirim 10.000 email sekaligus akan kena rate limit?
Tidak, selama semua request berhasil (response 200). Rate limit hanya aktif jika request gagal. Untuk volume pengiriman tinggi yang sukses, tidak ada throttling dari sisi Mailketing.
Bagaimana cara test rate limit tanpa mengganggu produksi?
Gunakan token API yang salah (token dummy) di environment testing untuk memicu error 401 berulang kali hingga kena 429. Ini cara aman untuk menguji implementasi retry logic tanpa menyentuh data produksi.
Butuh akses ke Mailketing API v2 untuk diintegrasikan ke sistemmu? Daftar Mailketing gratis dan dapatkan API token langsung — kirim email transaksional, OTP, atau notifikasi dari aplikasimu dalam hitungan menit.
