API Hilmipremindo Mail
Temp-mail buat terima OTP/email verifikasi otomatis dari project lain — server-to-server maupun frontend.
Informasi umum
| Base URL | https://api.hilmipremindo.online/api/v1 |
|---|---|
| Versi | v1 |
| Format | JSON — POST butuh header Content-Type: application/json |
| Autentikasi | X-Api-Key (server-to-server) atau X-Session-Token (browser) — cuma buat endpoint 🔒 |
| Rate limit | 120 request / menit / IP |
| Kontak | Telegram @generatortelebot |
Autentikasi
Sebagian besar endpoint publik (bikin alamat, cek info, extend, list domain). Yang butuh auth cuma 2 endpoint yang baca ISI pesan/OTP: GET /…/messages dan GET /messages/:id (ditandai 🔒).
Dua endpoint itu perlu salah satu header berikut:
| Header | Buat apa | Umur | Cara dapetnya |
|---|---|---|---|
X-Api-Key | Server-to-server, skrip, bot | Permanen (sampai dicabut) | Bot Telegram: Admin → API Key → Generate (ditunjukin sekali) |
X-Session-Token | Frontend/browser | 10 menit | GET /session, auto-expired |
X-Api-Key — paling gampang, gak perlu refresh. Browser JS? Pakai alur X-Session-Token.Tanpa header valid, dua endpoint itu balikin 403:
{ "error": "Akses ditolak - butuh browser resmi atau API key" }Kode status
| Kode | Arti | Kapan muncul |
|---|---|---|
200 | OK | Request sukses. |
400 | Bad Request | domain gak ada di GET /domains pas bikin alamat. |
403 | Forbidden | Endpoint 🔒 dipanggil tanpa X-Api-Key/X-Session-Token yang valid. |
404 | Not Found | Alamat/pesan gak ketemu atau udah expired. |
429 | Too Many Requests | Kena rate limit (120/menit/IP) — pelanin request-nya. |
Body error selalu berbentuk { "error": "..." }.
Ambil session token publik
Khusus frontend/browser. Balikin token HMAC short-lived (10 menit) buat header X-Session-Token. Buat server-to-server abaikan ini — langsung pakai X-Api-Key.
{ "token": "eyJleHAiOjE3ODU2NzQwMDB9.q1w2e3..." }Daftar domain publik
Selalu ambil dari sini, jangan di-hardcode — domain bisa nambah kapan aja.
{ "domains": ["hilmipremindo.online", "hilmipremindo.com", "aksesresmi.biz.id", "indocuan.web.id"] }curl https://api.hilmipremindo.online/api/v1/domains
Bikin / ambil alamat publik
| Field | Wajib | Keterangan |
|---|---|---|
domain | ya | harus salah satu dari GET /domains |
local | tidak | local-part custom (budi → budi@domain). Dikosongin = acak 12 karakter. |
Kalau local@domain udah ada dan belum expired, balikin alamat yang SAMA — aman dipanggil berkali-kali.
{ "local": "k7m2x9qp3a4d", "domain": "hilmipremindo.online", "createdAt": 1784574688, "expiresAt": 1784575288, "extendedCount": 0 }curl -X POST https://api.hilmipremindo.online/api/v1/addresses \
-H "Content-Type: application/json" \
-d '{"domain":"hilmipremindo.online"}'Info alamat publik
Response sama shape kayak endpoint bikin alamat. 404 kalau gak ketemu/expired.
curl https://api.hilmipremindo.online/api/v1/addresses/k7m2x9qp3a4d/hilmipremindo.online
Perpanjang TTL publik
TTL default alamat baru 10 menit, tiap extend nambah 10 menit dari sisa waktu, maksimal 1 jam dari saat extend dipanggil. 404 kalau udah expired duluan.
curl -X POST https://api.hilmipremindo.online/api/v1/addresses/k7m2x9qp3a4d/hilmipremindo.online/extend
List email masuk 🔒 butuh auth
| Query | Keterangan |
|---|---|
since | cuma balikin pesan dengan id > nilai ini — buat polling biar gak narik ulang pesan lama |
{
"count": 1,
"messages": [
{
"id": 42,
"fromName": "OpenAI",
"fromEmail": "[email protected]",
"subject": "Your verification code",
"otp": "482913",
"receivedAt": 1784574700,
"read": 0
}
]
}otp udah otomatis diekstrak (kode 4–8 digit atau format XXX-XXX), kosong "" kalau gak ada. List ini belum ada isi lengkap (plain/html) — buat itu pakai endpoint berikutnya.
curl -H "X-Api-Key: KEY_LO_DISINI" \ "https://api.hilmipremindo.online/api/v1/addresses/k7m2x9qp3a4d/hilmipremindo.online/messages?since=42"
Isi lengkap 1 email 🔒 butuh auth
:id dari field id di response list. Manggil ini nandain pesan jadi read.
{
"id": 42,
"fromName": "OpenAI",
"fromEmail": "[email protected]",
"subject": "Your verification code",
"plain": "Your code is 482913",
"html": "<p>Your code is <b>482913</b></p>",
"otp": "482913",
"receivedAt": 1784574700
}curl -H "X-Api-Key: KEY_LO_DISINI" \ https://api.hilmipremindo.online/api/v1/messages/42
Contoh lengkap: generate → tunggu OTP
Semua contoh pakai API key (server-to-server). Ganti KEY_LO_DISINI dengan key hasil generate dari bot.
#!/usr/bin/env bash
BASE="https://api.hilmipremindo.online/api/v1"
KEY="KEY_LO_DISINI"
# 1. bikin alamat
RESP=$(curl -s -X POST "$BASE/addresses" \
-H "Content-Type: application/json" -d '{"domain":"hilmipremindo.online"}')
LOCAL=$(echo "$RESP" | grep -o '"local":"[^"]*"' | cut -d'"' -f4)
echo "alamat: [email protected]"
# 2. pakai alamat itu buat daftar di layanan lain, lalu poll OTP:
for i in $(seq 1 30); do
MSGS=$(curl -s -H "X-Api-Key: $KEY" \
"$BASE/addresses/$LOCAL/hilmipremindo.online/messages")
OTP=$(echo "$MSGS" | grep -o '"otp":"[0-9][^"]*"' | head -1 | cut -d'"' -f4)
if [ -n "$OTP" ]; then echo "OTP: $OTP"; break; fi
sleep 3
donepip install requestsimport time
import requests
BASE = "https://api.hilmipremindo.online/api/v1"
KEY = "KEY_LO_DISINI"
HEADERS = {"X-Api-Key": KEY}
def generate(domain="hilmipremindo.online", local=None):
body = {"domain": domain}
if local:
body["local"] = local
r = requests.post(f"{BASE}/addresses", json=body)
r.raise_for_status()
return r.json()
def wait_for_otp(local, domain, timeout=120, interval=3):
deadline = time.time() + timeout
while time.time() < deadline:
r = requests.get(
f"{BASE}/addresses/{local}/{domain}/messages",
headers=HEADERS,
)
r.raise_for_status()
for msg in r.json()["messages"]:
if msg["otp"]:
return msg["otp"]
time.sleep(interval)
return None
addr = generate()
print("alamat:", f'{addr["local"]}@{addr["domain"]}')
# ... pakai alamat itu buat daftar di layanan lain ...
otp = wait_for_otp(addr["local"], addr["domain"])
print("OTP:", otp)fetch bawaan, no deps)const BASE = "https://api.hilmipremindo.online/api/v1";
const KEY = "KEY_LO_DISINI";
const HEADERS = { "X-Api-Key": KEY };
async function generate(domain = "hilmipremindo.online", local) {
const body = local ? { domain, local } : { domain };
const r = await fetch(`${BASE}/addresses`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
}
async function waitForOtp(local, domain, timeoutMs = 120000, intervalMs = 3000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = await fetch(
`${BASE}/addresses/${local}/${domain}/messages`,
{ headers: HEADERS }
);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const { messages } = await r.json();
const hit = messages.find((m) => m.otp);
if (hit) return hit.otp;
await new Promise((res) => setTimeout(res, intervalMs));
}
return null;
}
(async () => {
const addr = await generate();
console.log("alamat:", `${addr.local}@${addr.domain}`);
// ... pakai alamat itu buat daftar di layanan lain ...
const otp = await waitForOtp(addr.local, addr.domain);
console.log("OTP:", otp);
})();<?php
$BASE = "https://api.hilmipremindo.online/api/v1";
$KEY = "KEY_LO_DISINI";
function req($method, $url, $body = null, $key = null) {
$ch = curl_init($url);
$headers = ["Content-Type: application/json"];
if ($key) $headers[] = "X-Api-Key: $key";
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
]);
if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
$resp = curl_exec($ch);
curl_close($ch);
return json_decode($resp, true);
}
// 1. bikin alamat
$addr = req("POST", "$BASE/addresses", ["domain" => "hilmipremindo.online"]);
$local = $addr["local"];
$domain = $addr["domain"];
echo "alamat: $local@$domain\n";
// 2. poll OTP
$otp = null;
for ($i = 0; $i < 40; $i++) {
$msgs = req("GET", "$BASE/addresses/$local/$domain/messages", null, $KEY);
foreach ($msgs["messages"] as $m) {
if (!empty($m["otp"])) { $otp = $m["otp"]; break 2; }
}
sleep(3);
}
echo "OTP: $otp\n";Alur session token (browser JS)
Buat browser, ganti X-Api-Key dengan alur ambil-/session-dulu + auto-retry pas 403:
const BASE = "https://api.hilmipremindo.online/api/v1";
let token = null;
async function ensureToken() {
const r = await fetch(`${BASE}/session`);
token = (await r.json()).token;
}
async function listMessages(local, domain) {
let r = await fetch(`${BASE}/addresses/${local}/${domain}/messages`, {
headers: token ? { "X-Session-Token": token } : {},
});
if (r.status === 403) { // token expired/belum ada -> ambil baru, retry sekali
await ensureToken();
r = await fetch(`${BASE}/addresses/${local}/${domain}/messages`, {
headers: { "X-Session-Token": token },
});
}
return r.json();
}ALLOWED_ORIGIN di .env VPS dulu.Catatan
- Gak ada endpoint HAPUS alamat/pesan manual — semua expired otomatis lewat TTL, dibersihin job background.
- Endpoint lain di codebase (
/tenant-config,/webhooks/*, ingest) itu internal, bukan buat dipanggil dari luar. - API key bisa dicabut kapan aja lewat bot (Admin → API Key → Cabut) — abis dicabut, request pakai key itu langsung balik
403.
Change Log
| Tanggal | Perubahan |
|---|---|
| 2026-08-03 | Endpoint GET /…/messages & GET /messages/:id sekarang butuh auth (X-Api-Key atau X-Session-Token). Tambah endpoint GET /session. |
| 2026-08-02 | Local-part alamat acak dinaikin ke 12 karakter (dari 5) — keyspace jauh lebih gede biar gak ketebak. |
| v1 | Rilis awal: bikin alamat, list domain, extend, baca pesan/OTP. |
Istilah
| Istilah | Arti |
|---|---|
| local-part | Bagian sebelum @ di alamat email — budi pada [email protected]. |
| OTP | One-Time Password — kode verifikasi sekali pakai (4–8 digit / XXX-XXX) yang otomatis diekstrak dari email masuk. |
| TTL | Time To Live — masa aktif alamat sebelum hangus otomatis (default 10 menit, maks 1 jam). |
| API key | Kunci permanen (X-Api-Key) buat akses server-to-server, di-generate lewat bot Telegram. |
| session token | Token sementara (X-Session-Token, 10 menit) buat akses dari browser, diambil dari GET /session. |