HTTPS API
POST a JSON body to https://hep.gg/api/v1/email/send to send one or more transactional emails and get a messageId back.
HTTPS API
The HTTPS API sends transactional mail with a single JSON POST. It is the right channel for new code: no SMTP transport to configure, a synchronous messageId in the response, and the same credits, daily caps, and send log as the SMTP relay.
https://hep.gg/api/v1/email/sendAuth requiredAuthenticate with Authorization: Bearer hyd-mail-.... Mint keys on the API Keys tab; there is no endpoint that creates one.
toccbccsubjecthtmlhtml or text is required.texttext or html is required.fromnoreply@hep.gg, or an address assigned to your account). If omitted, resolves to your account default sender, then the global default. See Senders, billing & limits.fromNamereplyToConstraints
- At least one
toaddress after de-duplication, otherwise400. - Total recipients (To + Cc + Bcc, de-duplicated case-insensitively) must be 100 or fewer, otherwise
400. - Every address must be a syntactically valid email, otherwise
400. - Exactly one of
htmlortextis required, otherwise400. - Combined
html+textlength must be under 10 MB, otherwise413. (The JSON body parser accepts up to 15 MB of request payload, but the 10 MB body cap is the binding limit.) - 120 calls per minute per key, shared with the SMTP relay, otherwise
429.
Billing
One credit per distinct recipient across To, Cc, and Bcc. Duplicates are removed before billing. A message to two to addresses, one cc, and one bcc costs 4 credits. Credits are debited before the relay attempt and refunded automatically if the send terminally fails. See Senders, billing & limits.
Examples
Single recipient
curl -X POST https://hep.gg/api/v1/email/send \
-H "Authorization: Bearer hyd-mail-..." \
-H "Content-Type: application/json" \
-d '{
"to": "customer@example.com",
"subject": "Receipt #12345",
"html": "<h1>Thanks!</h1><p>Your order is on the way.</p>"
}'await fetch("https://hep.gg/api/v1/email/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HEPGG_EMAIL_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "customer@example.com",
subject: "Receipt #12345",
html: "<h1>Thanks!</h1><p>Your order is on the way.</p>",
}),
});Multiple recipients with Cc and Bcc
This call has two to addresses, one cc, and one bcc, so it costs 4 credits.
curl -X POST https://hep.gg/api/v1/email/send \
-H "Authorization: Bearer hyd-mail-..." \
-H "Content-Type: application/json" \
-d '{
"to": ["a@example.com", "b@example.com"],
"cc": ["manager@example.com"],
"bcc": ["archive@example.com"],
"from": "noreply@hep.gg",
"subject": "Quarterly update",
"html": "<p>Numbers are in.</p>"
}'await fetch("https://hep.gg/api/v1/email/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HEPGG_EMAIL_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: ["a@example.com", "b@example.com"],
cc: ["manager@example.com"],
bcc: ["archive@example.com"],
from: "noreply@hep.gg",
subject: "Quarterly update",
html: "<p>Numbers are in.</p>",
}),
});Responses
All responses use the standard envelope: { "ok": true, "data": {...} } on success, { "ok": false, "error": "...", "code"?: "..." } on failure.
200 OK (sent)
The message was relayed synchronously.
{
"ok": true,
"data": {
"messageId": "a1b2c3d4e5f6a7b8",
"smtpMessageId": "<...@hep.gg>",
"status": "sent",
"from": "noreply@hep.gg",
"recipients": 1,
"creditsCharged": 1
}
}messageId is the 16-character row id on the dashboard Logs tab. smtpMessageId is the upstream message id.
202 Accepted (queued)
The sender address hit its rolling 24-hour provider cap, so the message was queued and will be drained within 24 hours. Credits are charged at queue time.
{
"ok": true,
"data": {
"messageId": "a1b2c3d4e5f6a7b8",
"status": "queued",
"recipients": 1,
"creditsCharged": 1,
"retryHint": "Daily provider cap reached; will retry within 24h."
}
}Errors
See Errors & retries for the complete table. Common ones:
400validation: emptyto, more than 100 recipients, invalid address, missing body, or an unauthorizedfrom.402INSUFFICIENT_CREDITS(pre-check) orINSUFFICIENT_FUNDS(debit race): not enough credits.413: body over 10 MB.429: rate limited. The response carries aRetry-Afterheader in seconds.502: terminal relay failure. Credits charged for the request are refunded automatically.
No delivery callback
messageId is only returned on the synchronous response. There is no delivery, open, or bounce webhook, and no public endpoint to look a message up by id. Post-send visibility is the dashboard Logs tab. See Errors & retries for retry guidance, since there is no idempotency key.