A helpdesk widget waits for customers to come to you; the support inbox is where they already went. Order status questions, return requests, shipping complaints, fraud alerts, marketing replies β for an online store it all piles into one address, and the e-commerce patterns overview opens with the honest diagnosis: manual triage of that pile doesn't scale.
The architecture that does scale is an agent-owned mailbox per store. Agent Accounts β Nylas-hosted mailboxes currently in beta β are real addresses your application creates and controls entirely through the API. An AI layer answers the repetitive majority ("where's my order?" has a database answer, not a human one) and escalates anything involving judgment, money, or anger.
Creating the account is one call against the Bring Your Own Auth endpoint with "provider": "nylas"
:
curl --request POST \
--url "https://api.us.nylas.com/v3/connect/custom" \
--header "Authorization: Bearer <NYLAS_API_KEY>" \
--header "Content-Type: application/json" \
--data '{
"provider": "nylas",
"settings": {
"email": "support@orders.yourstore.com"
}
}'
The response carries a grant_id
that works with every existing endpoint β Messages, Threads, Folders, Attachments, Webhooks β so nothing about your integration is agent-specific. The mailbox arrives with six system folders (inbox
, sent
, drafts
, trash
, junk
, archive
), and you can add custom ones like returns
or fraud-review
. For a multi-store platform, the per-customer pattern goes further: one account per merchant on each merchant's own verified domain, each with its own send quota and sender reputation, all inside a single application.
Inbound mail fires the standard message.created
webhook. From there, the e-commerce hub points at two agent recipes that split the problem sensibly:
That confidence gate is the load-bearing design decision. A wrong shipping estimate sent confidently costs you more trust than a slow correct one. Classification first, generation second, escalation as the default for everything ambiguous β returns disputes, chargebacks, and anything where the customer is already angry go straight to a person.
Spam never even has to reach the classifier: rules on the account can block known junk domains at the SMTP stage, which also keeps prompt-injection bait out of your LLM's context window entirely.
Rules can do more than block junk. They match on sender fields (from.address
, from.domain
, from.tld
) and run actions like assign_to_folder
, mark_as_starred
, or archive
β inside the mail infrastructure, before your webhook handler fires. For a store, two rules earn their keep immediately:
curl --request POST \
--url "https://api.us.nylas.com/v3/rules" \
--header "Authorization: Bearer <NYLAS_API_KEY>" \
--header "Content-Type: application/json" \
--data '{
"name": "Carrier notifications β shipping folder",
"trigger": "inbound",
"match": {
"operator": "any",
"conditions": [
{ "field": "from.domain", "operator": "is", "value": "ups.com" },
{ "field": "from.domain", "operator": "is", "value": "fedex.com" }
]
},
"actions": [
{ "type": "assign_to_folder", "value": "<SHIPPING_FOLDER_ID>" },
{ "type": "mark_as_read" }
]
}'
A second rule can mark_as_starred
mail from your highest-value customer domains so the escalation queue surfaces them first. Rules attach to workspaces rather than individual mailboxes β set the rule_ids
once on a workspace and every store's agent account in it inherits the same sorting, which is exactly what you want when store number forty-seven onboards.
Order support means attachments: photos of damaged goods, screenshots of error pages, PDFs of receipts. Inbound attachment limits come from your plan and the account's policy β limit_attachment_size_limit
, limit_attachment_count_limit
, and limit_attachment_allowed_types
are all tunable, so you can refuse executables while accepting images. Attachment IDs arrive on the message object, and down is one call:
curl --request GET \
--url "https://api.us.nylas.com/v3/grants/<GRANT_ID>/attachments/<ATTACHMENT_ID>/download?message_id=<MESSAGE_ID>" \
--header "Authorization: Bearer <NYLAS_API_KEY>"
That's the input for a vision model checking damage claims, or simply the file your human agent sees when the ticket escalates.
Escalation needs a place for the human to work, and here the mailbox model pays off twice. Because the Agent Account is a real mailbox, your support staff can connect to it over standard IMAP and SMTP from Outlook or Apple Mail and answer the angry-customer thread directly β same address, same thread, no context lost. The API and the mail client see the same mailbox, so when the human is done, the agent's view of the conversation includes everything the human wrote.
One implementation detail if your application also manages connected human grants: the message.created
payload for an Agent Account is identical in shape to any other grant's. Branch on the grant's provider
β "nylas"
for Agent Accounts β to route agent-mailbox deliveries to the triage pipeline and leave human inboxes alone.
Outbound acknowledgments and answers go through the normal send endpoint on the same grant, so the customer sees one consistent identity and replies land back in the same mailbox β the full conversation is one thread your code can read. Outbound messages are capped at 40 MB total, which comfortably covers invoices and return labels as attachments. For batch sends like shipping-delay notices, the hub also points to a mail-merge pattern with per-recipient scheduling.
Free-plan limits from the docs, worth knowing before launch day:
For a store doing modest volume, 200 sends a day covers a lot of acknowledgments; for peak season, plan the upgrade before Black Friday does it for you.
Provision one agent mailbox on a trial domain, point your message.created
webhook at a classifier with exactly two auto-answer categories β order status and shipping ETA β and route everything else to your existing human queue untouched. Run it for two weeks and measure what fraction of mail never needed a person. If you run a store today, what percentage of your support volume do you suspect is answerable straight from your orders table?