API reference
Emails
Send and read email.
/v1/emails/received/addressYour managed inbound address
emails:rNode.js SDKhonkio.emails.received.address()Requires emails:r.
Responses
200The account's managed inbound address (anything@… reaches it), minted on first call and stable after. enabled is the managed-address switch: mail sent to it while off is discarded, uncharged.
Field Type Description domainrequiredstring examplerequiredstring livemoderequiredboolean enabledrequiredboolean - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403ACCOUNT_NOT_VERIFIED: the live managed address needs a verified owner mobile number. A test key is never refused; it always mints and returns the test address. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data: address, error } = await honkio.emails.received.address()
if (error) throw new Error(error.message)
console.log(address.example)curl https://api.honkio.ca/v1/emails/received/address \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/received/addressTurn your managed inbound address on or off (live keys only)
emails:mNode.js SDKhonkio.emails.received.setAddressEnabled()Requires emails:m.
Request body
Turns the account's live managed inbound address on or off.
| Field | Type | Description |
|---|---|---|
enabledrequired | boolean | False stops accepting mail at the managed address; true accepts it again. Your own receiving domains are not affected. |
Responses
200The same address object GET returns, with enabled set to the requested value. The flag is account-wide: turning it off stops the live managed address receiving, so only a live key may change it.
Field Type Description domainrequiredstring examplerequiredstring livemoderequiredboolean enabledrequiredboolean - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403LIVE_KEY_REQUIRED: the switch is account-wide and turns the live address off, so a test key cannot change it (GET still reports it). Also ACCOUNT_NOT_VERIFIED (needs a verified owner mobile number) or FORBIDDEN when the key lacks emails:m.The standard error body.
- 422VALIDATION_ERROR: the request failed validation; details names the fields.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.received.setAddressEnabled(false)
if (error) throw new Error(error.message)
console.log(data.enabled)curl -X PATCH https://api.honkio.ca/v1/emails/received/address \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'/v1/emails/receivedList received emails
emails:rNode.js SDKhonkio.emails.received.list()Requires emails:r.
Responses
200A page of received emails, newest first.
Field Type Description data[]requiredobject[] idrequiredstring fromrequiredstring from_namerequiredstring - Can be null
torequiredstring[] ccrequiredstring[] subjectrequiredstring message_idrequiredstring - Can be null
in_reply_torequiredstring - Can be null
received_atrequiredstring - Format: date-time
statusrequiredstring - One of: received | rejected
reject_reasonrequiredstring - Can be null
verdictsrequiredobject spfrequiredstring dkimrequiredstring dmarcrequiredstring spamrequiredstring virusrequiredstring attachments_countrequiredinteger size_bytesrequiredinteger charge_millicentsrequiredinteger domain_idrequiredstring - Can be null
livemoderequiredboolean has_morerequiredboolean next_cursorrequiredstring - Can be null
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 422VALIDATION_ERROR: the request failed validation; details names the fields.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.received.list({ limit: 10 })
if (error) throw new Error(error.message)
for (const email of data.data) console.log(email.id, email.from, email.subject)curl https://api.honkio.ca/v1/emails/received \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/received/simulateSimulate a received email (test keys only)
emails:wNode.js SDKhonkio.emails.received.simulate()Requires emails:w.
Request body
A message to receive as if it had arrived by email, run through the same processing, record and email.received webhook as real mail.
| Field | Type | Description |
|---|---|---|
fromrequired | string | The sender's address.
|
torequired | string[] | Up to 10 recipients, each your test managed address or an address at one of your test mode domains. |
cc | string[] | Up to 10 more recipients, with the same rule as to. |
subject | string | Up to 998 characters.
|
text | string | The plain text body.
|
html | string | The HTML body.
|
attachments[] | object[] | Up to 10 files, 10 MB in total. |
filenamerequired | string | The file name.
|
content_typerequired | string | The MIME type, such as application/pdf.
|
contentrequired | string | The file, base64 encoded. |
content_id | string | A Content-ID, so html can reference the file as cid:.
|
inline | boolean | Mark the file inline rather than attached. |
verdicts | object | The spam, virus and authentication verdicts to record. virus FAIL stores the message as rejected, as real mail would be. |
spf | string | The verdict to record. Left out, it is PASS.
|
dkim | string | The verdict to record. Left out, it is PASS.
|
dmarc | string | The verdict to record. Left out, it is PASS.
|
spam | string | The verdict to record. Left out, it is PASS.
|
virus | string | The verdict to record. Left out, it is PASS.
|
in_reply_to | string | The Message-ID this message replies to, for threading.
|
headers[] | object[] | Up to 20 extra headers. |
namerequired | string | The header name. |
valuerequired | string | The header value. |
Responses
201The simulated message, in the same shape GET /v1/emails/received/:id answers with. livemode is always false.
Field Type Description idrequiredstring fromrequiredstring from_namerequiredstring - Can be null
torequiredstring[] ccrequiredstring[] subjectrequiredstring message_idrequiredstring - Can be null
in_reply_torequiredstring - Can be null
received_atrequiredstring - Format: date-time
statusrequiredstring - One of: received | rejected
reject_reasonrequiredstring - Can be null
verdictsrequiredobject spfrequiredstring dkimrequiredstring dmarcrequiredstring spamrequiredstring virusrequiredstring attachments_countrequiredinteger size_bytesrequiredinteger charge_millicentsrequiredinteger domain_idrequiredstring - Can be null
livemoderequiredboolean textrequiredstring - Can be null
htmlrequiredstring - Can be null
html_formatrequiredstring - One of: cid | links | sanitized
remote_imagesrequiredinteger Remote images parked in data-remote-src by html_format=sanitized; null for the other formats.
- Can be null
headers[]requiredobject[] namerequiredstring valuerequiredstring referencesrequiredstring[] reply_torequiredstring[] envelope_recipientsrequiredstring[] body_purgedrequiredboolean body_truncatedrequiredboolean text or html was cut at 2 MB (UTF-8 bytes) when stored; the raw message keeps it whole.
raw_availablerequiredboolean parse_failedrequiredboolean attachments_bytesrequiredinteger Total size of the attachments, in bytes.
attachments[]requiredobject[] idrequiredstring filenamerequiredstring content_typerequiredstring content_idrequiredstring - Can be null
inlinerequiredboolean size_bytesrequiredinteger expires_atrequiredstring - Format: date-time
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403TEST_KEY_REQUIRED: this endpoint only accepts test keys.The standard error body.
- 422VALIDATION_ERROR (bad input, or attachments over 10 MB total) or SIMULATE_RECIPIENT_NOT_OWNED (a to/cc address is neither the account's test managed address nor one of its own test-mode domains).The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
// Test keys only: no real sender involved.
const { data, error } = await honkio.emails.received.simulate({
from: 'sam@example.com',
to: ['support@yourdomain.ca'],
subject: 'Where is my order?',
text: 'Hi, it has been a week.',
})
if (error) throw new Error(error.message)
console.log(data.id)curl -X POST https://api.honkio.ca/v1/emails/received/simulate \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sam@example.com",
"to": [
"support@yourdomain.ca"
],
"subject": "Where is my order?",
"text": "Hi, it has been a week."
}'/v1/emails/received/{id}Get a received email
emails:rNode.js SDKhonkio.emails.received.get()Requires emails:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The received email. html is rewritten to point cid: images at the attachment route unless html_format=cid asks for the original; html_format=sanitized also strips scripts and unsafe markup and parks remote images in data-remote-src, counted in remote_images.
Field Type Description idrequiredstring fromrequiredstring from_namerequiredstring - Can be null
torequiredstring[] ccrequiredstring[] subjectrequiredstring message_idrequiredstring - Can be null
in_reply_torequiredstring - Can be null
received_atrequiredstring - Format: date-time
statusrequiredstring - One of: received | rejected
reject_reasonrequiredstring - Can be null
verdictsrequiredobject spfrequiredstring dkimrequiredstring dmarcrequiredstring spamrequiredstring virusrequiredstring attachments_countrequiredinteger size_bytesrequiredinteger charge_millicentsrequiredinteger domain_idrequiredstring - Can be null
livemoderequiredboolean textrequiredstring - Can be null
htmlrequiredstring - Can be null
html_formatrequiredstring - One of: cid | links | sanitized
remote_imagesrequiredinteger Remote images parked in data-remote-src by html_format=sanitized; null for the other formats.
- Can be null
headers[]requiredobject[] namerequiredstring valuerequiredstring referencesrequiredstring[] reply_torequiredstring[] envelope_recipientsrequiredstring[] body_purgedrequiredboolean body_truncatedrequiredboolean text or html was cut at 2 MB (UTF-8 bytes) when stored; the raw message keeps it whole.
raw_availablerequiredboolean parse_failedrequiredboolean attachments_bytesrequiredinteger Total size of the attachments, in bytes.
attachments[]requiredobject[] idrequiredstring filenamerequiredstring content_typerequiredstring content_idrequiredstring - Can be null
inlinerequiredboolean size_bytesrequiredinteger expires_atrequiredstring - Format: date-time
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404RECEIVED_EMAIL_NOT_FOUND: no received email with that id on this account. A test key finds only messages received on the test managed address.The standard error body.
- 422VALIDATION_ERROR: html_format is not cid, links or sanitized.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data: email, error } = await honkio.emails.received.get('RECEIVED_EMAIL_ID')
if (error) throw new Error(error.message)
console.log(email.from, email.subject, email.text)curl https://api.honkio.ca/v1/emails/received/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/received/{id}/rawDownload the raw MIME of a received email
emails:rNode.js SDKhonkio.emails.received.raw()Requires emails:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 200The raw MIME message, exactly as received.
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404RECEIVED_EMAIL_NOT_FOUND: no received email with that id on this account. A test key finds only messages received on the test managed address.The standard error body.
- 410ATTACHMENT_EXPIRED: the raw message or attachment is no longer stored (40-day retention).The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data: mime, error } = await honkio.emails.received.raw('RECEIVED_EMAIL_ID')
if (error) throw new Error(error.message)
console.log(await mime.text())curl https://api.honkio.ca/v1/emails/received/ID/raw \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/received/{id}/attachments/{attachmentId}Download a received attachment
emails:rNode.js SDKhonkio.emails.received.attachment()Requires emails:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string | |
attachmentIdrequiredpath | string |
Responses
- 200The attachment bytes, with Content-Disposition set to the original filename.
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404RECEIVED_EMAIL_NOT_FOUND: no received email with that id on this account. A test key finds only messages received on the test managed address.The standard error body.
- 410ATTACHMENT_EXPIRED: the raw message or attachment is no longer stored (40-day retention).The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data: file, error } = await honkio.emails.received.attachment('RECEIVED_EMAIL_ID', 'ATTACHMENT_ID')
if (error) throw new Error(error.message)
const bytes = new Uint8Array(await file.arrayBuffer())
console.log(bytes.length)curl https://api.honkio.ca/v1/emails/received/ID/attachments/ATTACHMENT_ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emailsList emails
emails:rNode.js SDKhonkio.emails.list()Requires emails:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
limitquery | string | 1 to 100. Default 50. |
cursorquery | string | next_cursor from the previous page. |
statusquery | string | One of queued, scheduled, sending, sent, delivered, bounced, complained, rejected, failed, cancelled. |
tagquery | string | string[] | name:value. Repeat to require several; all must match. |
toquery | string | A full address in the email's to list (not cc or bcc), matched exactly whatever its case. |
fromquery | string | The full sender address, matched exactly whatever its case. |
sincequery | string | ISO 8601 date-time with an offset: created_at at or after this moment. |
untilquery | string | ISO 8601 date-time with an offset: created_at at or before this moment. |
domain_idquery | string | The sending domain's id (GET /v1/email-domains). |
Responses
200A page of sent emails in the calling key's mode (a live key never lists a test send, nor a test key a live one), newest first.
Field Type Description data[]requiredobject[] idrequiredstring fromrequiredstring torequiredstring[] subjectrequiredstring body_purged_atrequiredstring Set once retention purged the subject and body.
- Format: date-time
- Can be null
statusrequiredstring - One of: queued | scheduled | sending | sent | delivered | bounced | complained | rejected | failed | cancelled
ses_message_idrequiredstring - Can be null
is_commercialrequiredboolean attachments_countrequiredinteger livemoderequiredboolean tags[]requiredobject[] namerequiredstring valuerequiredstring created_atrequiredstring - Format: date-time
has_morerequiredboolean next_cursorrequiredstring - Can be null
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 422VALIDATION_ERROR: the request failed validation; details names the fields.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.list({ status: 'bounced', limit: 20 })
if (error) throw new Error(error.message)
for (const email of data.data) console.log(email.id, email.to)curl https://api.honkio.ca/v1/emails \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emailsSend an email
emails:wNode.js SDKhonkio.emails.send()Requires emails:w.
Request body
One email: a subject with html, text or both, or a template.
| Field | Type | Description |
|---|---|---|
from | string | Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.
|
torequired | string | string[] | A string or an array; at most 50 recipients across to, cc and bcc. |
cc | string | string[] | A string or an array. |
bcc | string | string[] | A string or an array. |
reply_to | string | string[] | A string or an array. |
subject | string | Up to 998 characters. Leave out subject, html and text when you send a template.
|
html | string | The HTML body. Give html, text or both, unless you send a template. |
text | string | The plain text body. Give html, text or both, unless you send a template. |
template | object | Send a stored template instead of subject, html and text: its id or alias, and values for its variables. |
idrequired | string | The template's id or alias.
|
variables | object | Values for the template's variables, by key.
|
variables | object | Values to substitute into placeholders in subject, html and text. Ignored when template is set; a template's own variables go in template.variables instead.
|
headers | object | Extra email headers, sent as given.
|
attachments[] | object[] | Up to 10 files and 25 MB in total. The first 2 MB per recipient are included; each started MB above that is charged per recipient (GET /v1/pricing). Executable and script types are refused.
|
filenamerequired | string | The file name the recipient sees.
|
content | string | The file, base64 encoded. Give exactly one of content, content_base64 or path. |
content_base64 | string | The file, base64 encoded (the same as content). |
path | string | An HTTPS URL HonkIO fetches the file from.
|
content_type | string | The MIME type, such as application/pdf. Inferred when left out.
|
content_id | string | Embeds the file inline: reference it from html as cid: followed by this id. |
tags[] | object[] | Up to 10 name and value pairs, each part 1 to 256 letters, digits, underscores or hyphens. Names starting with honkio_ are reserved. Tags are kept after the subject and body are purged, so keep personal information out of them.
|
namerequired | string | |
valuerequired | string | |
is_commercial | boolean | False by default. True marks a commercial message under CASL: it goes to exactly one recipient, needs consent on file for that address, and carries an unsubscribe footer and header.
|
scheduled_at | string | Send later: an ISO 8601 date-time with an offset, 1 minute to 30 days ahead.
|
tracking | object | Open and click tracking for this email, overriding the sending domain's setting.
|
opens | boolean | Track opens with a pixel. |
clicks | boolean | Track clicks by rewriting links. |
disable_unsubscribe_footer | boolean | Leave out the unsubscribe footer HonkIO adds to a commercial email. The one click unsubscribe header is still sent: put your own unsubscribe link in the body.
|
Responses
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403FORBIDDEN (the key lacks emails:w), EMAIL_DOMAIN_NOT_ALLOWED (this key may not send from that domain) or SENDING_PAUSED (live email is paused for this account after a high bounce or complaint rate; details carry paused_until, reason and channel: "email"). Test keys are never paused.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.send({
from: 'Acme <hello@yourdomain.ca>',
to: 'sam@example.com',
subject: 'Your receipt',
html: '<p>Thanks for your order, Sam.</p>',
})
if (error) throw new Error(`${error.name}: ${error.message}`)
console.log(data.id, data.status)curl -X POST https://api.honkio.ca/v1/emails \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@yourdomain.ca>",
"to": "sam@example.com",
"subject": "Your receipt",
"html": "<p>Thanks for your order, Sam.</p>"
}'/v1/emails/{id}Get an email by id
emails:rNode.js SDKhonkio.emails.get()Requires emails:r.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
200The sent email, with its event timeline.
Field Type Description idrequiredstring fromrequiredstring torequiredstring[] subjectrequiredstring body_purged_atrequiredstring Set once retention purged the subject and body.
- Format: date-time
- Can be null
statusrequiredstring - One of: queued | scheduled | sending | sent | delivered | bounced | complained | rejected | failed | cancelled
ses_message_idrequiredstring - Can be null
is_commercialrequiredboolean attachments_countrequiredinteger livemoderequiredboolean tags[]requiredobject[] namerequiredstring valuerequiredstring created_atrequiredstring - Format: date-time
from_namerequiredstring - Can be null
ccrequiredstring[] bccrequiredstring[] htmlrequiredstring - Can be null
textrequiredstring - Can be null
templaterequiredany | object attachments[]requiredobject[] filenamerequiredstring content_typerequiredstring content_idrequiredstring - Can be null
size_bytesrequiredinteger cost_centsrequiredinteger Whole cents this send debited from the balance; often 0 for one sub-cent email.
charge_millicentsrequiredinteger The exact price the send consumed, in CAD millicents.
attachment_bytesrequiredinteger Total attachment bytes the charge was computed on.
scheduled_atrequiredstring - Format: date-time
- Can be null
updated_atrequiredstring - Format: date-time
events[]requiredobject[] typerequiredstring occurred_atrequiredstring - Format: date-time
payloadrequiredany - 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 404NOT_FOUND (details.resource "email"): no email with that id on this account in the calling key's mode. A test key finds only test sends, a live key only live ones.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.get('EMAIL_ID')
if (error) throw new Error(error.message)
console.log(data.status, data.events)curl https://api.honkio.ca/v1/emails/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/{id}Reschedule a scheduled email
emails:mNode.js SDKhonkio.emails.update()Requires emails:m.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Request body
The new send time of a scheduled email.
| Field | Type | Description |
|---|---|---|
scheduled_atrequired | string | An ISO 8601 date-time with an offset, 1 minute to 30 days ahead.
|
Responses
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.emails.update('EMAIL_ID', { scheduledAt: '2026-10-01T14:00:00Z' })
if (error) throw new Error(error.message)
console.log(data.scheduled_at)curl -X PATCH https://api.honkio.ca/v1/emails/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"scheduled_at": "2026-10-01T14:00:00Z"
}'/v1/emails/{id}Cancel a scheduled email
emails:dNode.js SDKhonkio.emails.cancel()Requires emails:d.
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequiredpath | string |
Responses
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403The API key lacks the permission this operation requires, or the account is suspended or closed.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { error } = await honkio.emails.cancel('EMAIL_ID')
if (error) throw new Error(error.message)curl -X DELETE https://api.honkio.ca/v1/emails/ID \
-H "Authorization: Bearer mk_live_YOUR_KEY"/v1/emails/batchSend a batch of emails
emails:wNode.js SDKhonkio.batch.send()Requires emails:w.
Request body
A JSON array of up to 100 independent emails, or one message for up to 500 recipients as an object with a recipients list. Attachments are not available in a batch, and scheduling only in the object form.
An array of up to 100 emails, each sent on its own. Every item is checked before any is sent.
| Field | Type | Description |
|---|---|---|
from | string | Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.
|
torequired | string | string[] | A string or an array; at most 50 recipients across to, cc and bcc. |
cc | string | string[] | A string or an array. |
bcc | string | string[] | A string or an array. |
reply_to | string | string[] | A string or an array. |
subject | string | Up to 998 characters. Leave out subject, html and text when you send a template.
|
html | string | The HTML body. Give html, text or both, unless you send a template. |
text | string | The plain text body. Give html, text or both, unless you send a template. |
template | object | Send a stored template instead of subject, html and text: its id or alias, and values for its variables. |
idrequired | string | The template's id or alias.
|
variables | object | Values for the template's variables, by key.
|
variables | object | Values to substitute into placeholders in subject, html and text. Ignored when template is set; a template's own variables go in template.variables instead.
|
headers | object | Extra email headers, sent as given.
|
tags[] | object[] | Up to 10 name and value pairs, each part 1 to 256 letters, digits, underscores or hyphens. Names starting with honkio_ are reserved. Tags are kept after the subject and body are purged, so keep personal information out of them.
|
namerequired | string | |
valuerequired | string | |
is_commercial | boolean | False by default. True marks a commercial message under CASL: it goes to exactly one recipient, needs consent on file for that address, and carries an unsubscribe footer and header.
|
tracking | object | Open and click tracking for this email, overriding the sending domain's setting.
|
opens | boolean | Track opens with a pixel. |
clicks | boolean | Track clicks by rewriting links. |
disable_unsubscribe_footer | boolean | Leave out the unsubscribe footer HonkIO adds to a commercial email. The one click unsubscribe header is still sent: put your own unsubscribe link in the body.
|
One message for up to 500 recipients, each with its own variables.
| Field | Type | Description |
|---|---|---|
from | string | Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.
|
subject | string | Up to 998 characters. Leave out subject, html and text when you send a template.
|
html | string | The HTML body. Give html, text or both, unless you send a template. |
text | string | The plain text body. Give html, text or both, unless you send a template. |
template | object | Send a stored template instead of subject, html and text: its id or alias, and values for its variables. |
idrequired | string | The template's id or alias.
|
variables | object | Values for the template's variables, by key.
|
headers | object | Extra email headers, sent as given.
|
tags[] | object[] | Up to 10 name and value pairs, each part 1 to 256 letters, digits, underscores or hyphens. Names starting with honkio_ are reserved. Tags are kept after the subject and body are purged, so keep personal information out of them.
|
namerequired | string | |
valuerequired | string | |
is_commercial | boolean | False by default. True marks a commercial message under CASL: it goes to exactly one recipient, needs consent on file for that address, and carries an unsubscribe footer and header.
|
scheduled_at | string | Send later: an ISO 8601 date-time, 1 minute to 30 days ahead.
|
tracking | object | Open and click tracking for this email, overriding the sending domain's setting.
|
opens | boolean | Track opens with a pixel. |
clicks | boolean | Track clicks by rewriting links. |
disable_unsubscribe_footer | boolean | Leave out the unsubscribe footer HonkIO adds to a commercial email. The one click unsubscribe header is still sent: put your own unsubscribe link in the body.
|
recipients[]required | object[] | Up to 500 recipients, each sent their own email. |
torequired | string | The recipient's address.
|
variables | object | Values for this recipient's placeholders or template variables.
|
Responses
- 401Missing, invalid, revoked or expired API key.The standard error body.
- 402The account has no balance, or a LIVE key was used before the first top-up.The standard error body.
- 403FORBIDDEN, EMAIL_DOMAIN_NOT_ALLOWED or SENDING_PAUSED (live email is paused; details carry paused_until, reason and channel: "email"). Refused before any item is sent.The standard error body.
- 429Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).The standard error body.
- 500Unexpected server error.The standard error body.
Example
const { data, error } = await honkio.batch.send([
{ from: 'Acme <hello@yourdomain.ca>', to: 'sam@example.com', subject: 'Your receipt', html: '<p>Thanks, Sam.</p>' },
{ from: 'Acme <hello@yourdomain.ca>', to: 'alex@example.com', subject: 'Your receipt', html: '<p>Thanks, Alex.</p>' },
])
if (error) throw new Error(error.message)
console.log(data.batch_id, data.data.length)curl -X POST https://api.honkio.ca/v1/emails/batch \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"from": "Acme <hello@yourdomain.ca>",
"to": "sam@example.com",
"subject": "Your receipt",
"html": "<p>Thanks, Sam.</p>"
},
{
"from": "Acme <hello@yourdomain.ca>",
"to": "alex@example.com",
"subject": "Your receipt",
"html": "<p>Thanks, Alex.</p>"
}
]'
HonkIO