Use session cookie htm_session after login, or API key header:
Authorization: Bearer htm_<your_key>
API keys are stored hashed, shown once, revocable, and may include scopes + IP allowlist.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/inboxes | Create inbox |
| GET | /api/v1/inboxes | List inboxes |
| GET | /api/v1/inboxes/:id | Inbox detail |
| POST | /api/v1/inboxes/:id/extend | Extend TTL |
| DELETE | /api/v1/inboxes/:id | Delete inbox |
| GET | /api/v1/inboxes/:id/messages | List messages |
| GET | /api/v1/messages/:id | Message detail (masked codes) |
| DELETE | /api/v1/messages/:id | Delete message |
| GET | /api/v1/quotas/me | Quota usage |
| POST | /api/v1/webhooks | Create webhook |
| POST | /api/inbound/email | Inbound provider webhook |
curl -X POST "$APP_URL/api/v1/inboxes" \
-H "Authorization: Bearer htm_xxx" \
-H "Content-Type: application/json" \
-d '{"domainId":"<uuid>","durationAmount":24,"durationUnit":"hours"}'const res = await fetch(`${APP_URL}/api/v1/inboxes/${id}/messages`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const json = await res.json();import requests
r = requests.get(
f"{APP_URL}/api/v1/messages/{mid}",
headers={"Authorization": f"Bearer {key}"},
)
print(r.json())import hmac, hashlib
def verify(secret: str, body: bytes, signature_hex: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_hex)
# Headers: X-Huang-Signature, X-Huang-Timestamp, X-Huang-Event
# Default payload is metadata only (no full email body).{
"error": {
"code": "FORBIDDEN",
"message": "You do not have access to this inbox.",
"requestId": "req_...",
"timestamp": "2026-07-13T00:00:00.000Z"
}
}Pagination: page, pageSize (max 100). Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id.
Acceptable use: only mail for domains you own. Do not use the API to obtain OTPs or credentials from third-party services.