Docs · Guides
Send with SMTP
Send from any SMTP client or library with an API key as the password, through the same pipeline as the API.
Anything that can send email over SMTP can send from your inboxes: a framework’s mailer, a CRM, a printer, smtplib. Log in with an API key as the password. The message goes through exactly the same checks and delivery as POST /v1/inboxes/:id/messages/send, and shows up in the API and the dashboard like any other sent message.
#Settings
| Setting | Value |
|---|---|
| Server | smtp.agentboxd.com |
| Port | 587 with STARTTLS (required before login), or 465 with TLS |
| Username | The inbox address (any value works; the address makes the client’s account list readable) |
| Password | An API key (mr_…) with the messages:send permission |
| Authentication | PLAIN or LOGIN |
import nodemailer from 'nodemailer';
const smtp = nodemailer.createTransport({
host: 'smtp.agentboxd.com',
port: 587, // STARTTLS; or port: 465, secure: true
auth: { user: 'support-bot@agents.agentboxd.com', pass: process.env.AGENTBOXD_API_KEY },
});
const info = await smtp.sendMail({
from: 'support-bot@agents.agentboxd.com',
to: 'dana@example.com',
subject: 'Your refund',
text: 'Hi Dana, the refund is on its way.',
});
console.log(info.response); // 250 2.0.0 Queued as <message id>import os
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "support-bot@agents.agentboxd.com"
msg["To"] = "dana@example.com"
msg["Subject"] = "Your refund"
msg.set_content("Hi Dana, the refund is on its way.")
with smtplib.SMTP("smtp.agentboxd.com", 587) as smtp:
smtp.starttls()
smtp.login("support-bot@agents.agentboxd.com", os.environ["AGENTBOXD_API_KEY"])
smtp.send_message(msg)#Who you can send as
The envelope sender (MAIL FROM) must be one of the key’s inboxes: any inbox of the workspace for a workspace key, only its inbox for an inbox-scoped key. The From: header must be the same address. Temporary inboxes are receive-only, and inboxes on a custom domain need the domain verified, as with the API. Otherwise the server answers 550 5.7.1.
#What happens to the message
- The recipients are the SMTP envelope recipients (up to 50). Each one appears as To or Cc if the header lists it, otherwise it is sent as Bcc.
- Subject, text, HTML and attachments are kept.
Fromis set to the inbox address and display name, and the message gets our own Message-ID, as every API send does. Other headers are not carried over, and inlinecid:images are sent as ordinary attachments. In-Reply-ToandReferencesare kept. When they point at a message in the same inbox, the new message joins that thread, and your reply allow/block lists apply as withPOST …/reply.- Suppression, allow/block lists, the monthly email quota, the 5-minute burst limit, daily sending caps, size limits (
MAX_MESSAGE_BYTES) and DKIM signing all apply. The message counts toward usage exactly like an API send, and firesmessage.sent(then delivery events) on webhooks and the event stream. - The reply is
250 2.0.0 Queued as <message id>: fetch it withGET /v1/messages/:id. - Resubmitting a message with the same Message-ID within 24 hours (a client retrying after a timeout) doesn’t send it twice.
#Errors
| Reply | Why |
|---|---|
535 5.7.8 | Wrong or revoked key, or a key without messages:send |
538 5.7.11 | Login attempted before STARTTLS on port 587 |
550 5.7.1 <code>: … | Refused by the API rules, e.g. recipient_suppressed, recipient_blocked, plan_limit_emails, or a sender the key can’t use |
451 4.7.1 <code>: … | Try later: daily_send_limit_exceeded, the 5-minute burst limit (rate_limited, with “retry in N s”) or the key’s per-minute rate limit (shared with its API calls) |
552 5.3.4 | Message or attachment too large |
421 4.7.0 | Too many failed logins from your IP; wait 15 minutes |