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

MetodePathFungsi
POST/api/v1/otpKirim kode OTP ke satu penerima (antrean prioritas)
POST/api/v1/emailKirim email bebas (HTML/teks) atau dengan template
GET/api/v1/email/{id}Status satu email
GET/api/v1/emailRiwayat email aplikasi Anda (?status=, ?per_halaman=, ?page=)
GET/api/v1/pingCek kunci API, pengirim, dan kuota hari ini
GET/api/healthCek 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"
  }'
FieldKeterangan
kepadawajib, satu alamat email
kodewajib, 3–16 karakter huruf/angka/tanda minus
nama_penerima, nama_aplikasi, berlaku_menit, keperluan, subjekopsional, mengisi template OTP
metadataopsional, objek bebas (≤ 4 KB), dikembalikan apa adanya
kirim_langsungopsional, 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}
}
FieldKeterangan
kepadawajib; string, "Nama <email>", objek {email, nama}, atau array campuran
cc, bccopsional, format sama; total penerima maks. 50
subjekwajib bila tanpa template
html / teksminimal salah satu (bila tanpa template); HTML maks. 1024 KB
lampiranmaks. 10 berkas, total 15 MB (setelah decode base64)
nama_pengirim, balas_keopsional; alamat pengirim ditetapkan admin per aplikasi
template + dataopsional, 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.

KodeArti
401kunci API salah/kosong
403klien dinonaktifkan
422validasi gagal, rincian di errors
429melewati 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()));
}