Kirim OTP ke email dalam satu request.
API ringan untuk mengirim kode verifikasi dengan nama aplikasi, logo, dan desain email milik Anda sendiri.
Mulai pasangCoba langsungPemasangan
Ikuti urutan ini persis. Sebagian besar error deploy berasal dari struktur folder yang salah atau langkah yang terlewat.
1. Siapkan App Password Gmail
Aktifkan verifikasi 2 langkah di akun Gmail, lalu buat App Password di myaccount.google.com/apppasswords. Kode 16 karakter itu yang dipakai, bukan password Gmail biasa.
2. Pastikan struktur repo seperti ini
File harus berada di root repo. Jangan mengunggah foldernya sebagai subfolder.
api-email-otp/ ├─ api/ │ └─ send.js ├─ public/ │ └─ index.html ├─ config.json ├─ package.json ├─ vercel.json └─ .gitignore
3. Isi config.json
Isi gmail.user dan gmail.pass. Pengaturan lain boleh dibiarkan. Setiap kali config.json diubah, push ulang agar Vercel deploy ulang.
4. Push ke GitHub
Gunakan repo private karena config.json berisi App Password.
git init git add . git commit -m "api email otp" git branch -M main git remote add origin https://github.com/USERNAME/NAMA-REPO.git git push -u origin main
5. Import ke Vercel
Pilih Add New → Project, lalu pilih repo tadi. Atur seperti ini lalu klik Deploy:
| Pengaturan | Nilai |
|---|---|
| Framework Preset | Other |
| Root Directory | kosongkan (./) |
| Build Command, Output Directory, Install Command | biarkan default |
| Environment Variables | tidak perlu diisi |
| Node.js Version | 24.x (sudah diatur di package.json) |
6. Tes setelah deploy
Ganti alamat dan email, lalu jalankan. Hasil yang benar adalah {"ok":true,...} dan email masuk ke penerima.
curl -X POST https://DOMAIN-ANDA.vercel.app/api/send \
-H "Content-Type: application/json" \
-d '{"to":"emailanda@gmail.com","app":"Tes","otp":"123456"}'
Kalau ada masalah
| Gejala | Penyebab dan solusi |
|---|---|
| Build: Node.js version discontinued | Pastikan package.json berisi "engines": { "node": "24.x" }. |
/api/send menghasilkan 404 | Folder api tidak berada di root repo. Perbaiki struktur lalu push ulang. |
| Respons 405 | Request memakai GET. Gunakan POST. |
smtp_auth | App Password salah, verifikasi 2 langkah belum aktif, atau email di gmail.user tidak cocok dengan App Password. |
not_configured | gmail.user atau gmail.pass di config.json masih kosong. |
send_failed | Gangguan sementara atau batas kirim harian Gmail tercapai. Coba lagi nanti. |
rate_limited | Lebih dari batas request per menit. Ubah rateLimit di config.json bila perlu. |
| Email masuk ke spam | Wajar pada pengirim Gmail baru. Minta penerima menandai "bukan spam". |
| Perubahan config tidak berlaku | Commit dan push dulu. Vercel hanya membaca config.json saat deploy. |
Mode
Endpoint POST /api/send punya dua mode. Pilih lewat field mode. Jika tidak diisi, mode bawaan dari config.json dipakai (otp).
Mengirim email OTP dengan template HTML bawaan. Tampilan template diatur di bagian template pada config.json.
| Nama | Tipe | Keterangan |
|---|---|---|
to wajib | string | Alamat email penerima. |
app wajib | string | Nama aplikasi. Tampil sebagai nama pengirim dan judul email. |
otp wajib | string | Kode OTP, 3–12 karakter (huruf, angka, atau tanda hubung). |
logo | string | Link gambar logo. Harus diawali https://. |
subject | string | Judul email. Bawaan dari email.subject di config. |
curl -X POST https://DOMAIN-ANDA.vercel.app/api/send \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"app": "Nama Aplikasi",
"otp": "482913",
"logo": "https://example.com/logo.png"
}'
Email dikirim persis seperti HTML yang Anda tulis, tanpa template. Cukup to dan html.
| Nama | Tipe | Keterangan |
|---|---|---|
mode wajib | string | Isi dengan "html". |
to wajib | string | Alamat email penerima. |
html wajib | string | Isi email dalam HTML, maksimal 100 KB. |
subject | string | Judul email. Bawaan dari email.htmlSubject di config. |
app | string | Nama pengirim. Bawaan dari email.defaultFromName di config. |
curl -X POST https://DOMAIN-ANDA.vercel.app/api/send \
-H "Content-Type: application/json" \
-d '{
"mode": "html",
"to": "user@example.com",
"subject": "Selamat datang",
"html": "<h1>Halo!</h1><p>Terima kasih sudah mendaftar.</p>"
}'
Versi teks biasa dibuat otomatis dari HTML Anda sebagai cadangan untuk aplikasi email yang tidak menampilkan HTML.
Respons
Semua respons berupa JSON dengan field ok.
Berhasil · 200
{ "ok": true, "mode": "otp", "id": "<message-id>", "to": "user@example.com" }
Gagal
{ "ok": false, "error": { "code": "invalid_otp", "message": "Field 'otp' wajib 3-12 karakter ..." } }
| Status | Kode | Penyebab |
|---|---|---|
| 400 | invalid_body | Body bukan JSON object. |
| 400 | invalid_mode | Field mode bukan otp atau html. |
| 400 | invalid_to | Email penerima tidak valid. |
| 400 | invalid_app | Nama aplikasi kosong (mode otp) atau terlalu panjang. |
| 400 | invalid_otp | Format OTP tidak sesuai. |
| 400 | invalid_logo | Link logo bukan https yang valid. |
| 400 | invalid_html | HTML kosong (mode html) atau lebih dari 100 KB. |
| 405 | method_not_allowed | Memakai metode selain POST. |
| 429 | rate_limited | Lebih dari 10 request per menit dari satu IP. |
| 500 | not_configured | Gmail di config.json belum diisi. |
| 502 | smtp_auth | Login Gmail ditolak. Periksa App Password. |
| 502 | send_failed | Gmail gagal mengirim. Coba lagi. |
Coba langsung
Email yang dikirim dari form ini asli sampai ke penerima.
Hasil request akan muncul di sini.