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.fromNamereplyToattachmentsConstraints
- 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. - Up to 10 attachments, 15 MB each, and the body plus all attachments combined under 18 MB, otherwise
413.
Attachments
Add an attachments array to send files alongside the message. Each item takes one of two shapes:
- A hep.gg upload you own:
{ "uploadId": "<id>", "filename": "optional override" }. The file is read straight from your hep.gg uploads, so the request body stays small even for large files. You can only attach uploads on your own account. - Inline data:
{ "filename": "report.pdf", "content": "<base64>", "contentType": "application/pdf" }. The bytes ride along in the request as base64, with no upload step. Works for any file type.
Limits: up to 10 attachments, up to 15 MB each, and the body plus all attachments combined must stay under 18 MB before encoding (which keeps the assembled message under the 25 MB upstream ceiling). Inline base64 also counts against the 15 MB request-payload limit, so reach for an upload reference when a file is large. Attachments do not cost extra credits; billing stays per recipient.
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
Multiple recipients with Cc and Bcc
This call has two to addresses, one cc, and one bcc, so it costs 4 credits.
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, or attachments over their size limits.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.