API reference

Emails

Send and read email.

get/v1/emails/received/address

Your managed inbound 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.
    FieldTypeDescription
    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)
patch/v1/emails/received/address

Turn your managed inbound address on or off (live keys only)

Requires emails:m.

Request body

Turns the account's live managed inbound address on or off.

FieldTypeDescription
enabledrequiredboolean

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.
    FieldTypeDescription
    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)
get/v1/emails/received

List received emails

Requires emails:r.

Responses

  • 200A page of received emails, newest first.
    FieldTypeDescription
    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)
post/v1/emails/received/simulate

Simulate a received email (test keys only)

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.

FieldTypeDescription
fromrequiredstring

The sender's address.

  • Format: email
torequiredstring[]

Up to 10 recipients, each your test managed address or an address at one of your test mode domains.

ccstring[]

Up to 10 more recipients, with the same rule as to.

subjectstring

Up to 998 characters.

  • At most 998 characters
  • Default:
textstring

The plain text body.

  • At most 1000000 characters
htmlstring

The HTML body.

  • At most 2000000 characters
attachments[]object[]

Up to 10 files, 10 MB in total.

filenamerequiredstring

The file name.

  • At least 1 characters
  • At most 255 characters
content_typerequiredstring

The MIME type, such as application/pdf.

  • At least 1 characters
  • At most 255 characters
contentrequiredstring

The file, base64 encoded.

content_idstring

A Content-ID, so html can reference the file as cid:.

  • At most 255 characters
inlineboolean

Mark the file inline rather than attached.

verdictsobject

The spam, virus and authentication verdicts to record. virus FAIL stores the message as rejected, as real mail would be.

spfstring

The verdict to record. Left out, it is PASS.

  • One of: PASS | FAIL | GRAY | PROCESSING_FAILED
dkimstring

The verdict to record. Left out, it is PASS.

  • One of: PASS | FAIL | GRAY | PROCESSING_FAILED
dmarcstring

The verdict to record. Left out, it is PASS.

  • One of: PASS | FAIL | GRAY | PROCESSING_FAILED
spamstring

The verdict to record. Left out, it is PASS.

  • One of: PASS | FAIL | GRAY | PROCESSING_FAILED
virusstring

The verdict to record. Left out, it is PASS.

  • One of: PASS | FAIL | GRAY | PROCESSING_FAILED
in_reply_tostring

The Message-ID this message replies to, for threading.

  • At most 998 characters
headers[]object[]

Up to 20 extra headers.

namerequiredstring

The header name.

valuerequiredstring

The header value.

Responses

  • 201The simulated message, in the same shape GET /v1/emails/received/:id answers with. livemode is always false.
    FieldTypeDescription
    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)
get/v1/emails/received/{id}

Get a received email

Requires emails:r.

Parameters

ParameterTypeDescription
idrequiredpathstring

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.
    FieldTypeDescription
    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)
get/v1/emails/received/{id}/raw

Download the raw MIME of a received email

Requires emails:r.

Parameters

ParameterTypeDescription
idrequiredpathstring

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())
get/v1/emails/received/{id}/attachments/{attachmentId}

Download a received attachment

Requires emails:r.

Parameters

ParameterTypeDescription
idrequiredpathstring
attachmentIdrequiredpathstring

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)
get/v1/emails

List emails

Requires emails:r.

Parameters

ParameterTypeDescription
limitquerystring

1 to 100. Default 50.

cursorquerystring

next_cursor from the previous page.

statusquerystring

One of queued, scheduled, sending, sent, delivered, bounced, complained, rejected, failed, cancelled.

tagquerystring | string[]

name:value. Repeat to require several; all must match.

toquerystring

A full address in the email's to list (not cc or bcc), matched exactly whatever its case.

fromquerystring

The full sender address, matched exactly whatever its case.

sincequerystring

ISO 8601 date-time with an offset: created_at at or after this moment.

untilquerystring

ISO 8601 date-time with an offset: created_at at or before this moment.

domain_idquerystring

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.
    FieldTypeDescription
    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)
post/v1/emails

Send an email

Requires emails:w.

Request body

One email: a subject with html, text or both, or a template.

FieldTypeDescription
fromstring

Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.

  • At least 1 characters
torequiredstring | string[]

A string or an array; at most 50 recipients across to, cc and bcc.

ccstring | string[]

A string or an array.

bccstring | string[]

A string or an array.

reply_tostring | string[]

A string or an array.

subjectstring

Up to 998 characters. Leave out subject, html and text when you send a template.

  • At least 1 characters
  • At most 998 characters
htmlstring

The HTML body. Give html, text or both, unless you send a template.

textstring

The plain text body. Give html, text or both, unless you send a template.

templateobject

Send a stored template instead of subject, html and text: its id or alias, and values for its variables.

idrequiredstring

The template's id or alias.

  • At least 1 characters
  • At most 200 characters
variablesobject

Values for the template's variables, by key.

  • Default: {}
variablesobject

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.

  • Default: {}
headersobject

Extra email headers, sent as given.

  • Default: {}
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.

  • Default: []
filenamerequiredstring

The file name the recipient sees.

  • At least 1 characters
  • At most 255 characters
contentstring

The file, base64 encoded. Give exactly one of content, content_base64 or path.

content_base64string

The file, base64 encoded (the same as content).

pathstring

An HTTPS URL HonkIO fetches the file from.

  • Format: uri
  • At most 2048 characters
content_typestring

The MIME type, such as application/pdf. Inferred when left out.

  • At most 255 characters
content_idstring

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.

  • Default: []
namerequiredstring
valuerequiredstring
is_commercialboolean

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.

  • Default: false
scheduled_atstring

Send later: an ISO 8601 date-time with an offset, 1 minute to 30 days ahead.

  • Format: date-time
  • Default: null
  • Can be null
trackingobject

Open and click tracking for this email, overriding the sending domain's setting.

  • Default: {}
opensboolean

Track opens with a pixel.

clicksboolean

Track clicks by rewriting links.

disable_unsubscribe_footerboolean

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.

  • Default: false

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)
get/v1/emails/{id}

Get an email by id

Requires emails:r.

Parameters

ParameterTypeDescription
idrequiredpathstring

Responses

  • 200The sent email, with its event timeline.
    FieldTypeDescription
    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)
patch/v1/emails/{id}

Reschedule a scheduled email

Requires emails:m.

Parameters

ParameterTypeDescription
idrequiredpathstring

Request body

The new send time of a scheduled email.

FieldTypeDescription
scheduled_atrequiredstring

An ISO 8601 date-time with an offset, 1 minute to 30 days ahead.

  • Format: date-time

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)
delete/v1/emails/{id}

Cancel a scheduled email

Requires emails:d.

Parameters

ParameterTypeDescription
idrequiredpathstring

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)
post/v1/emails/batch

Send a batch of emails

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.

FieldTypeDescription
fromstring

Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.

  • At least 1 characters
torequiredstring | string[]

A string or an array; at most 50 recipients across to, cc and bcc.

ccstring | string[]

A string or an array.

bccstring | string[]

A string or an array.

reply_tostring | string[]

A string or an array.

subjectstring

Up to 998 characters. Leave out subject, html and text when you send a template.

  • At least 1 characters
  • At most 998 characters
htmlstring

The HTML body. Give html, text or both, unless you send a template.

textstring

The plain text body. Give html, text or both, unless you send a template.

templateobject

Send a stored template instead of subject, html and text: its id or alias, and values for its variables.

idrequiredstring

The template's id or alias.

  • At least 1 characters
  • At most 200 characters
variablesobject

Values for the template's variables, by key.

  • Default: {}
variablesobject

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.

  • Default: {}
headersobject

Extra email headers, sent as given.

  • Default: {}
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.

  • Default: []
namerequiredstring
valuerequiredstring
is_commercialboolean

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.

  • Default: false
trackingobject

Open and click tracking for this email, overriding the sending domain's setting.

  • Default: {}
opensboolean

Track opens with a pixel.

clicksboolean

Track clicks by rewriting links.

disable_unsubscribe_footerboolean

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.

  • Default: false

One message for up to 500 recipients, each with its own variables.

FieldTypeDescription
fromstring

Sender, optionally with a name. Its domain must be a verified sending domain on your account. Optional when the template sets one.

  • At least 1 characters
subjectstring

Up to 998 characters. Leave out subject, html and text when you send a template.

  • At least 1 characters
  • At most 998 characters
htmlstring

The HTML body. Give html, text or both, unless you send a template.

textstring

The plain text body. Give html, text or both, unless you send a template.

templateobject

Send a stored template instead of subject, html and text: its id or alias, and values for its variables.

idrequiredstring

The template's id or alias.

  • At least 1 characters
  • At most 200 characters
variablesobject

Values for the template's variables, by key.

  • Default: {}
headersobject

Extra email headers, sent as given.

  • Default: {}
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.

  • Default: []
namerequiredstring
valuerequiredstring
is_commercialboolean

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.

  • Default: false
scheduled_atstring

Send later: an ISO 8601 date-time, 1 minute to 30 days ahead.

  • Format: date-time
  • Default: null
  • Can be null
trackingobject

Open and click tracking for this email, overriding the sending domain's setting.

  • Default: {}
opensboolean

Track opens with a pixel.

clicksboolean

Track clicks by rewriting links.

disable_unsubscribe_footerboolean

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.

  • Default: false
recipients[]requiredobject[]

Up to 500 recipients, each sent their own email.

torequiredstring

The recipient's address.

  • Format: email
variablesobject

Values for this recipient's placeholders or template variables.

  • Default: {}

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)