Mail API ASG
Layanan pengirim email untuk aplikasi internal PT ASG (erp.asg.co.id, kasir, dan lainnya) melalui Google Workspace. Aplikasi cukup memanggil API ini, tanpa perlu menyimpan kredensial SMTP sendiri.
Autentikasi
Setiap aplikasi mendapat kunci API sendiri dari admin server. Kirim kunci lewat header:
Authorization: Bearer mak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
atau X-Api-Key: mak_…. Semua permintaan memakai Content-Type: application/json dan Accept: application/json.
Endpoint
| Metode | Path | Fungsi |
|---|---|---|
| POST | /api/v1/otp | Kirim kode OTP ke satu penerima (antrean prioritas) |
| POST | /api/v1/email | Kirim email bebas (HTML/teks) atau dengan template |
| GET | /api/v1/email/{id} | Status satu email |
| GET | /api/v1/email | Riwayat email aplikasi Anda (?status=, ?per_halaman=, ?page=) |
| GET | /api/v1/ping | Cek kunci API, pengirim, dan kuota hari ini |
| GET | /api/health | Cek layanan (tanpa kunci) |
Kirim OTP
curl -X POST https://mail-api.asg.co.id/api/v1/otp \
-H "Authorization: Bearer $MAILAPI_KUNCI" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-d '{
"kepada": "budi@contoh.co.id",
"kode": "482913",
"nama_penerima": "Budi",
"nama_aplikasi": "ERP ASG",
"berlaku_menit": 5,
"keperluan": "masuk ke ERP ASG"
}'
| Field | Keterangan |
|---|---|
kepada | wajib, satu alamat email |
kode | wajib, 3–16 karakter huruf/angka/tanda minus |
nama_penerima, nama_aplikasi, berlaku_menit, keperluan, subjek | opsional, mengisi template OTP |
metadata | opsional, objek bebas (≤ 4 KB), dikembalikan apa adanya |
kirim_langsung | opsional, true = kirim saat itu juga dan tunggu hasilnya |
Isi email OTP (berisi kode) dihapus dari database setelah terkirim.
Kirim email bebas
POST /api/v1/email
{
"kepada": ["budi@contoh.co.id", {"email": "sari@contoh.co.id", "nama": "Sari"}],
"cc": "Atasan <atasan@contoh.co.id>",
"bcc": [],
"balas_ke": "admin@asg.co.id",
"nama_pengirim": "ERP ASG",
"subjek": "Invoice INV-2026-001",
"html": "<p>Terlampir invoice Anda.</p>",
"teks": "Terlampir invoice Anda.",
"lampiran": [{"nama": "INV-2026-001.pdf", "mime": "application/pdf", "isi_base64": "JVBERi0..."}],
"metadata": {"invoice_id": 123}
}
| Field | Keterangan |
|---|---|
kepada | wajib; string, "Nama <email>", objek {email, nama}, atau array campuran |
cc, bcc | opsional, format sama; total penerima maks. 50 |
subjek | wajib bila tanpa template |
html / teks | minimal salah satu (bila tanpa template); HTML maks. 1024 KB |
lampiran | maks. 10 berkas, total 15 MB (setelah decode base64) |
nama_pengirim, balas_ke | opsional; alamat pengirim ditetapkan admin per aplikasi |
template + data | opsional, lihat di bawah |
Template bawaan
"template": "umum" membungkus isi dengan kop dan tombol:
{
"kepada": "budi@contoh.co.id",
"template": "umum",
"data": {
"judul": "Pengajuan disetujui",
"salam": "Halo Budi,",
"isi": "Pengajuan pembelian PO-0012 telah disetujui.",
"tombol_teks": "Buka ERP",
"tombol_url": "https://erp.asg.co.id/pembelian/12",
"penutup": "Terima kasih."
}
}
isi berupa teks biasa; gunakan isi_html untuk HTML. "template": "otp" memakai data.kode, data.berlaku_menit, dan seterusnya, sama seperti /api/v1/otp.
Respons
Email masuk antrean dan dikirim oleh worker dalam beberapa detik. Respons 202:
{
"data": {
"id": "01JB7X3Q9W2Z5M8K4N6P0R1S2T",
"status": "antri",
"jenis": "otp",
"kepada": [{"email": "budi@contoh.co.id", "nama": "Budi"}],
"subjek": "Kode verifikasi ERP ASG",
"percobaan": 0,
"galat": null,
"dibuat_at": "2026-10-28T10:00:00+07:00",
"terkirim_at": null
}
}
Status: antri → diproses → terkirim, atau gagal setelah 5 kali percobaan (jeda 30 dtk, 2 mnt, 10 mnt, 30 mnt). Dengan kirim_langsung: true, respons 201 berarti sudah terkirim.
| Kode | Arti |
|---|---|
| 401 | kunci API salah/kosong |
| 403 | klien dinonaktifkan |
| 422 | validasi gagal, rincian di errors |
| 429 | melewati batas per menit atau per hari |
Mencegah kiriman ganda
Sertakan header Idempotency-Key: <id-unik> (mis. id transaksi). Permintaan ulang dengan kunci yang sama mengembalikan email yang sudah ada tanpa mengirim lagi.
Contoh Laravel (aplikasi klien)
// .env: MAILAPI_URL=https://mail-api.asg.co.id MAILAPI_KUNCI=mak_...
$res = Http::withToken(env('MAILAPI_KUNCI'))
->acceptJson()->timeout(10)
->post(env('MAILAPI_URL').'/api/v1/otp', [
'kepada' => $user->email,
'nama_penerima' => $user->name,
'kode' => $otp,
'nama_aplikasi' => 'ERP ASG',
'berlaku_menit' => 5,
]);
if ($res->failed()) {
report(new RuntimeException('Mail API: '.$res->body()));
}