{"id":278358,"date":"2026-04-24T16:37:49","date_gmt":"2026-04-24T14:37:49","guid":{"rendered":"https:\/\/www.unipile.com\/?p=278358"},"modified":"2026-04-28T17:24:47","modified_gmt":"2026-04-28T15:24:47","slug":"e-mail-verzenden-api-javascript","status":"publish","type":"post","link":"https:\/\/www.unipile.com\/nl\/send-email-api-javascript\/","title":{"rendered":"E-mail verzenden via API in JavaScript (Node.js Tutorial)"},"content":{"rendered":"\n[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;40px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-toc-jsapi, #upl-toc-jsapi *, #upl-toc-jsapi *::before, #upl-toc-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi { max-width:1100px!important;margin:0 auto!important;padding:0 20px 8px!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-card { background:#fff!important;border-radius:14px!important;border:1px solid #e2e5ea!important;overflow:hidden!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-mobile-toggle { display:none!important;align-items:center!important;justify-content:space-between!important;padding:14px 18px!important;cursor:pointer!important;background:#fff!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-mobile-label { font-family:'Poppins',sans-serif!important;font-size:0.8rem!important;font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-mobile-icon { color:#64748b!important;transition:transform 0.3s!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-collapsible { display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-header { display:flex!important;align-items:center!important;justify-content:space-between!important;padding:14px 18px 10px!important;border-bottom:1px solid #f0f1f3!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-header-title { font-family:'Poppins',sans-serif!important;font-size:0.72rem!important;font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-badge { background:rgba(59,185,139,0.12)!important;color:#3BB98B!important;font-size:0.52rem!important;font-weight:700!important;padding:3px 8px!important;border-radius:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-grid { display:grid!important;grid-template-columns:repeat(4,1fr)!important;gap:0!important;padding:6px 6px 10px!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-col { padding:12px!important;border-left:1px solid #f0f1f3!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-col:first-child { border-left:none!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-label { font-size:0.52rem!important;font-weight:700!important;color:#94a3b8!important;text-transform:uppercase!important;letter-spacing:1px!important;margin-bottom:8px!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-link { display:flex!important;align-items:center!important;gap:7px!important;padding:5px 6px!important;border-radius:6px!important;color:#64748b!important;font-size:0.68rem!important;font-weight:500!important;cursor:pointer!important;margin-bottom:2px!important;transition:background 0.15s!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-link:hover { background:rgba(59,185,139,0.06)!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-link.utcj-active { background:rgba(59,185,139,0.08)!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-num { width:18px!important;height:18px!important;min-width:18px!important;border-radius:5px!important;background:#f1f5f9!important;font-size:0.55rem!important;font-weight:700!important;color:#94a3b8!important;display:flex!important;align-items:center!important;justify-content:center!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-link.utcj-active .utcj-num { background:#3BB98B!important;color:#fff!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-link-text { flex:1!important; }<!-- [et_pb_line_break_holder] -->#upl-toc-jsapi .utcj-tag-rec { background:rgba(59,185,139,0.12)!important;color:#3BB98B!important;font-size:0.45rem!important;font-weight:700!important;padding:2px 5px!important;border-radius:4px!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:1000px){ #upl-toc-jsapi .utcj-grid { grid-template-columns:repeat(2,1fr)!important; } }<!-- [et_pb_line_break_holder] -->@media(max-width:700px){<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-mobile-toggle { display:flex!important; }<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-collapsible { display:none!important; }<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-collapsible.open { display:block!important; }<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-grid { grid-template-columns:1fr!important; }<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-col { border-left:none!important;border-top:1px solid #f0f1f3!important; }<!-- [et_pb_line_break_holder] -->  #upl-toc-jsapi .utcj-col:first-child { border-top:none!important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-toc-jsapi\"><!-- [et_pb_line_break_holder] -->  <div class=\"utcj-card\"><!-- [et_pb_line_break_holder] -->    <div class=\"utcj-mobile-toggle\" onclick=\"var c=this.nextElementSibling;c.classList.toggle('open');this.querySelector('.utcj-mobile-icon').style.transform=c.classList.contains('open')?'rotate(180deg)':'rotate(0)'\"><!-- [et_pb_line_break_holder] -->      <span class=\"utcj-mobile-label\">Table of Contents<\/span><!-- [et_pb_line_break_holder] -->      <svg class=\"utcj-mobile-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"><\/polyline><\/svg><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"utcj-collapsible\"><!-- [et_pb_line_break_holder] -->      <div class=\"utcj-header\"><!-- [et_pb_line_break_holder] -->        <span class=\"utcj-header-title\">Table of Contents<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"utcj-badge\">14 sections<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"utcj-grid\"><!-- [et_pb_line_break_holder] -->        <div class=\"utcj-col\"><!-- [et_pb_line_break_holder] -->          <span class=\"utcj-label\">Getting Started<\/span><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link utcj-active\" onclick=\"document.getElementById('anchor-tldr').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">01<\/span><span class=\"utcj-link-text\">TL;DR &#8211; 5-Line Example<\/span><span class=\"utcj-tag-rec\">Quick<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-prereqs').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">02<\/span><span class=\"utcj-link-text\">Prerequisites &#038; Setup<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-connect').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">03<\/span><span class=\"utcj-link-text\">Connect First Account<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"utcj-col\"><!-- [et_pb_line_break_holder] -->          <span class=\"utcj-label\">Sending Emails<\/span><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-send').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">04<\/span><span class=\"utcj-link-text\">Send Your First Email<\/span><span class=\"utcj-tag-rec\">Core<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-attachments').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">05<\/span><span class=\"utcj-link-text\">Attachments in Node.js<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-advanced').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">06<\/span><span class=\"utcj-link-text\">Replies, Threads &#038; Tracking<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"utcj-col\"><!-- [et_pb_line_break_holder] -->          <span class=\"utcj-label\">Production<\/span><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-errors').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">07<\/span><span class=\"utcj-link-text\">Error Handling &#038; Retries<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-security').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">08<\/span><span class=\"utcj-link-text\">Security Best Practices<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-pitfalls').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">09<\/span><span class=\"utcj-link-text\">Common Node.js Pitfalls<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"utcj-col\"><!-- [et_pb_line_break_holder] -->          <span class=\"utcj-label\">Reference<\/span><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-faq').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">10<\/span><span class=\"utcj-link-text\">FAQ<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"utcj-link\" onclick=\"document.getElementById('anchor-final-cta').scrollIntoView({behavior:'smooth'})\"><span class=\"utcj-num\">11<\/span><span class=\"utcj-link-text\">Start Building<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-hero-jsapi, #upl-hero-jsapi *, #upl-hero-jsapi *::before, #upl-hero-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi {<!-- [et_pb_line_break_holder] -->  padding:64px 20px 72px!important;<!-- [et_pb_line_break_holder] -->  background:#f4f5f7!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-inner {<!-- [et_pb_line_break_holder] -->  max-width:1160px!important;<!-- [et_pb_line_break_holder] -->  margin:0 auto!important;<!-- [et_pb_line_break_holder] -->  display:grid!important;<!-- [et_pb_line_break_holder] -->  grid-template-columns:1fr 1fr!important;<!-- [et_pb_line_break_holder] -->  gap:56px!important;<!-- [et_pb_line_break_holder] -->  align-items:center!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;<!-- [et_pb_line_break_holder] -->  align-items:center!important;<!-- [et_pb_line_break_holder] -->  gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;<!-- [et_pb_line_break_holder] -->  color:#8a8c2e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;<!-- [et_pb_line_break_holder] -->  border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;<!-- [et_pb_line_break_holder] -->  font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;<!-- [et_pb_line_break_holder] -->  letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:20px!important;<!-- [et_pb_line_break_holder] -->  width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-eyebrow .hjs-dot {<!-- [et_pb_line_break_holder] -->  width:7px!important;height:7px!important;<!-- [et_pb_line_break_holder] -->  background:#DDDF4C!important;<!-- [et_pb_line_break_holder] -->  border-radius:50%!important;<!-- [et_pb_line_break_holder] -->  flex-shrink:0!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-h1 {<!-- [et_pb_line_break_holder] -->  font-family:'Poppins',sans-serif!important;<!-- [et_pb_line_break_holder] -->  font-size:44px!important;<!-- [et_pb_line_break_holder] -->  font-weight:700!important;<!-- [et_pb_line_break_holder] -->  color:#0f2736!important;<!-- [et_pb_line_break_holder] -->  line-height:1.18!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:20px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-h1 .hjs-accent { color:#3BB98B!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-desc {<!-- [et_pb_line_break_holder] -->  font-size:17px!important;<!-- [et_pb_line_break_holder] -->  line-height:1.75!important;<!-- [et_pb_line_break_holder] -->  color:#383838!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:24px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-desc a {<!-- [et_pb_line_break_holder] -->  color:#3BB98B!important;<!-- [et_pb_line_break_holder] -->  font-weight:600!important;<!-- [et_pb_line_break_holder] -->  text-decoration:underline!important;<!-- [et_pb_line_break_holder] -->  text-decoration-color:rgba(59,185,139,0.4)!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-meta {<!-- [et_pb_line_break_holder] -->  display:flex!important;<!-- [et_pb_line_break_holder] -->  align-items:center!important;<!-- [et_pb_line_break_holder] -->  gap:16px!important;<!-- [et_pb_line_break_holder] -->  flex-wrap:wrap!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:20px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-meta-item {<!-- [et_pb_line_break_holder] -->  display:flex!important;<!-- [et_pb_line_break_holder] -->  align-items:center!important;<!-- [et_pb_line_break_holder] -->  gap:6px!important;<!-- [et_pb_line_break_holder] -->  font-size:0.8rem!important;<!-- [et_pb_line_break_holder] -->  color:#718096!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-meta-item svg {<!-- [et_pb_line_break_holder] -->  width:14px!important;height:14px!important;<!-- [et_pb_line_break_holder] -->  stroke:#3BB98B!important;fill:none!important;<!-- [et_pb_line_break_holder] -->  stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important;<!-- [et_pb_line_break_holder] -->  flex-shrink:0!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-meta-sep {<!-- [et_pb_line_break_holder] -->  width:4px!important;height:4px!important;<!-- [et_pb_line_break_holder] -->  background:#cbd5e0!important;border-radius:50%!important;flex-shrink:0!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-tags {<!-- [et_pb_line_break_holder] -->  display:flex!important;flex-wrap:wrap!important;gap:8px!important;margin-bottom:28px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-tag {<!-- [et_pb_line_break_holder] -->  background:#ffffff!important;color:#4a5568!important;<!-- [et_pb_line_break_holder] -->  padding:5px 12px!important;border-radius:6px!important;<!-- [et_pb_line_break_holder] -->  font-size:0.75rem!important;font-weight:500!important;<!-- [et_pb_line_break_holder] -->  border:1px solid #e2e8f0!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-actions {<!-- [et_pb_line_break_holder] -->  display:flex!important;align-items:center!important;gap:14px!important;flex-wrap:wrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-primary {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:#DDDF4C!important;color:#0f2736!important;<!-- [et_pb_line_break_holder] -->  padding:14px 28px!important;border-radius:8px!important;<!-- [et_pb_line_break_holder] -->  font-size:0.95rem!important;font-weight:600!important;<!-- [et_pb_line_break_holder] -->  border:2px solid #DDDF4C!important;<!-- [et_pb_line_break_holder] -->  transition:all 0.3s ease!important;cursor:pointer!important;<!-- [et_pb_line_break_holder] -->  white-space:nowrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-primary:hover { transform:translateY(-5px)!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-primary svg { width:16px!important;height:16px!important;stroke:currentColor!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-secondary {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:transparent!important;color:#0f2736!important;<!-- [et_pb_line_break_holder] -->  padding:12px 24px!important;border-radius:8px!important;<!-- [et_pb_line_break_holder] -->  border:2px solid #0f2736!important;<!-- [et_pb_line_break_holder] -->  font-size:0.95rem!important;font-weight:600!important;<!-- [et_pb_line_break_holder] -->  transition:all 0.3s ease!important;cursor:pointer!important;<!-- [et_pb_line_break_holder] -->  white-space:nowrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-secondary:hover { background:#0f2736!important;color:#ffffff!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-cta-secondary svg { width:16px!important;height:16px!important;stroke:currentColor!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->\/* Code editor right column *\/<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-editor {<!-- [et_pb_line_break_holder] -->  border-radius:14px!important;overflow:hidden!important;<!-- [et_pb_line_break_holder] -->  background:#0d1117!important;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-editor-bar {<!-- [et_pb_line_break_holder] -->  background:#161b22!important;padding:12px 18px!important;<!-- [et_pb_line_break_holder] -->  display:flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  border-bottom:1px solid rgba(255,255,255,0.06)!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-dot-r {width:12px!important;height:12px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-dot-y {width:12px!important;height:12px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-dot-g {width:12px!important;height:12px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-filename {<!-- [et_pb_line_break_holder] -->  color:#8b949e!important;font-size:13px!important;margin-left:6px!important;<!-- [et_pb_line_break_holder] -->  font-family:'Courier New',monospace!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-pre {<!-- [et_pb_line_break_holder] -->  padding:22px 24px!important;font-size:13px!important;<!-- [et_pb_line_break_holder] -->  line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-pre code {<!-- [et_pb_line_break_holder] -->  font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-c {color:#8b949e!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-k {color:#ff7b72!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-fn {color:#d2a8ff!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-s {color:#a5d6ff!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-w {color:#e6edf3!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-editor-ok {<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.10)!important;<!-- [et_pb_line_break_holder] -->  border-top:1px solid rgba(59,185,139,0.25)!important;<!-- [et_pb_line_break_holder] -->  color:#3BB98B!important;padding:11px 24px!important;<!-- [et_pb_line_break_holder] -->  font-size:12.5px!important;font-family:'Courier New',monospace!important;<!-- [et_pb_line_break_holder] -->  display:flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-editor-ok svg { width:14px!important;height:14px!important;stroke:#3BB98B!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-providers {<!-- [et_pb_line_break_holder] -->  display:flex!important;align-items:center!important;gap:12px!important;<!-- [et_pb_line_break_holder] -->  padding:14px 20px!important;background:#ffffff!important;<!-- [et_pb_line_break_holder] -->  border-top:1px solid #e8ecf0!important;flex-wrap:wrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-providers img { width:20px!important;height:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-hero-jsapi .hjs-prov-label { font-size:0.72rem!important;color:#94a3b8!important;font-weight:500!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi {padding:50px 20px 60px!important;}<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi .hjs-inner {grid-template-columns:1fr!important;gap:44px!important;}<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi .hjs-h1 {font-size:34px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi {padding:40px 16px 50px!important;}<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi .hjs-h1 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi .hjs-actions {flex-direction:column!important;width:100%!important;}<!-- [et_pb_line_break_holder] -->  #upl-hero-jsapi .hjs-cta-primary, #upl-hero-jsapi .hjs-cta-secondary {width:100%!important;justify-content:center!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:400px){#upl-hero-jsapi .hjs-h1 {font-size:26px!important;}}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-hero-jsapi\"><!-- [et_pb_line_break_holder] -->  <div class=\"hjs-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"hjs-content\"><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-eyebrow\"><span class=\"hjs-dot\"><\/span><span>JavaScript Tutorial<\/span><\/div><!-- [et_pb_line_break_holder] -->      <h1 class=\"hjs-h1\">How to <span class=\"hjs-accent\">Send Email via API<\/span> in JavaScript (Node.js Tutorial)<\/h1><!-- [et_pb_line_break_holder] -->      <pee class=\"hjs-desc\">Skip the SMTP boilerplate. This guide shows you how to send email in Node.js using the <a href=\"https:\/\/www.unipile.com\/send-email-api\/\" target=\"_self\">Unipile unified email API<\/a> &#8211; with copy-paste code for Gmail, Outlook, and SMTP in under 10 lines of JavaScript.<\/pee><!-- [et_pb_line_break_holder] -->      <!-- [et_pb_line_break_holder] -->      <div class=\"hjs-tags\"><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-tag\">send email api javascript<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-tag\">node.js send email api<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-tag\">Gmail \/ Outlook \/ SMTP<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-tag\">ESM + async\/await<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-actions\"><!-- [et_pb_line_break_holder] -->        <a href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" class=\"hjs-cta-primary\" data-upl-link=\"https:\/\/dashboard.unipile.com\/signup\/\"><svg viewBox=\"0 0 24 24\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"\/><polyline points=\"10 17 15 12 10 7\"\/><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"\/><\/svg><span>Get your free API key<\/span><\/a><!-- [et_pb_line_break_holder] -->        <a href=\"\/email-api-guide\/\" target=\"_self\" class=\"hjs-cta-secondary\" data-upl-link=\"\/email-api-guide\/\"><svg viewBox=\"0 0 24 24\"><path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\"\/><path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\"\/><\/svg><span>Read the Email API guide<\/span><\/a><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"hjs-editor\"><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-editor-bar\"><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-dot-r\"><\/span><span class=\"hjs-dot-y\"><\/span><span class=\"hjs-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-filename\">sendEmail.mjs<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-pre\"><code><span class=\"hjs-k\">import<\/span><span class=\"hjs-w\"> <\/span><span class=\"hjs-fn\">{ UnipileClient }<\/span><span class=\"hjs-w\"> <\/span><span class=\"hjs-k\">from<\/span><span class=\"hjs-w\"> <\/span><span class=\"hjs-s\">'unipile-node-sdk'<\/span><span class=\"hjs-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"hjs-k\">const<\/span><span class=\"hjs-w\"> client <\/span><span class=\"hjs-fn\">= new<\/span><span class=\"hjs-w\"> <\/span><span class=\"hjs-fn\">UnipileClient<\/span><span class=\"hjs-w\">(<!-- [et_pb_line_break_holder] -->  process.env.<\/span><span class=\"hjs-n\">UNIPILE_DSN<\/span><span class=\"hjs-w\">,<!-- [et_pb_line_break_holder] -->  process.env.<\/span><span class=\"hjs-n\">UNIPILE_TOKEN<\/span><span class=\"hjs-w\"><!-- [et_pb_line_break_holder] -->);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"hjs-k\">await<\/span><span class=\"hjs-w\"> client.email.<\/span><span class=\"hjs-fn\">send<\/span><span class=\"hjs-w\">({<!-- [et_pb_line_break_holder] -->  account_id: <\/span><span class=\"hjs-s\">'YOUR_ACCOUNT_ID'<\/span><span class=\"hjs-w\">,<!-- [et_pb_line_break_holder] -->  to: [{ display_name: <\/span><span class=\"hjs-s\">'Alice'<\/span><span class=\"hjs-w\">,<!-- [et_pb_line_break_holder] -->          identifier: <\/span><span class=\"hjs-s\">'alice@example.com'<\/span><span class=\"hjs-w\"> }],<!-- [et_pb_line_break_holder] -->  subject: <\/span><span class=\"hjs-s\">'Hello from Node.js'<\/span><span class=\"hjs-w\">,<!-- [et_pb_line_break_holder] -->  body:    <\/span><span class=\"hjs-s\">'<pee>Sent via Unipile!<\/pee>'<\/span><span class=\"hjs-w\"><!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-editor-ok\"><!-- [et_pb_line_break_holder] -->        <svg viewBox=\"0 0 24 24\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><!-- [et_pb_line_break_holder] -->        <span>Email delivered &#8211; 202 Accepted<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"hjs-providers\"><!-- [et_pb_line_break_holder] -->        <span class=\"hjs-prov-label\">Works with:<\/span><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/gmail-3.svg\" alt=\"Gmail\"><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/outlook-2.svg\" alt=\"Outlook\"><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/imap-1.svg\" alt=\"IMAP\"><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->document.querySelectorAll('[data-upl-link]').forEach(function(el){<!-- [et_pb_line_break_holder] -->  el.addEventListener('click',function(e){<!-- [et_pb_line_break_holder] -->    e.preventDefault();<!-- [et_pb_line_break_holder] -->    var url=el.getAttribute('data-upl-link');<!-- [et_pb_line_break_holder] -->    if(url.startsWith('http')){window.open(url,'_blank');}<!-- [et_pb_line_break_holder] -->    else{window.location.href=url;}<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.4&#8243; background_color=&#8221;RGBA(255,255,255,0)&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243; background_color=&#8221;RGBA(255,255,255,0)&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi, #upl-tldr-jsapi *, #upl-tldr-jsapi *::before, #upl-tldr-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi { padding:72px 20px!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-dot { width:7px!important;height:7px!important;background:#3BB98B!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-h2 {<!-- [et_pb_line_break_holder] -->  font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:800px!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:36px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-grid { display:grid!important;grid-template-columns:1fr 1fr!important;gap:32px!important;align-items:start!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-steps { display:flex!important;flex-direction:column!important;gap:16px!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-step { display:flex!important;gap:16px!important;align-items:flex-start!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-step-num {<!-- [et_pb_line_break_holder] -->  width:36px!important;height:36px!important;min-width:36px!important;<!-- [et_pb_line_break_holder] -->  border-radius:10px!important;background:rgba(59,185,139,0.12)!important;<!-- [et_pb_line_break_holder] -->  color:#2aaa7e!important;display:flex!important;align-items:center!important;justify-content:center!important;<!-- [et_pb_line_break_holder] -->  font-family:'Poppins',sans-serif!important;font-size:14px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-step-body {}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-step-title { font-size:15px!important;font-weight:600!important;color:#0f2736!important;margin-bottom:3px!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-step-desc { font-size:14px!important;color:#718096!important;line-height:1.6!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-editor { border-radius:14px!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-editor-bar { background:#161b22!important;padding:12px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-dot-r {width:12px!important;height:12px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-dot-y {width:12px!important;height:12px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-dot-g {width:12px!important;height:12px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-fname { color:#8b949e!important;font-size:13px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-pre { padding:22px 24px!important;font-size:13px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .t-c {color:#8b949e!important;}#upl-tldr-jsapi .t-k {color:#ff7b72!important;}#upl-tldr-jsapi .t-fn {color:#d2a8ff!important;}#upl-tldr-jsapi .t-s {color:#a5d6ff!important;}#upl-tldr-jsapi .t-w {color:#e6edf3!important;}#upl-tldr-jsapi .t-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-info-strip {<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.08)!important;<!-- [et_pb_line_break_holder] -->  border-left:3px solid #3BB98B!important;<!-- [et_pb_line_break_holder] -->  border-radius:0 8px 8px 0!important;<!-- [et_pb_line_break_holder] -->  padding:14px 18px!important;<!-- [et_pb_line_break_holder] -->  margin-top:24px!important;<!-- [et_pb_line_break_holder] -->  font-size:14px!important;<!-- [et_pb_line_break_holder] -->  color:#0f2736!important;<!-- [et_pb_line_break_holder] -->  line-height:1.6!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-tldr-jsapi .tldr-info-strip a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-tldr-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-tldr-jsapi .tldr-grid {grid-template-columns:1fr!important;gap:28px!important;}<!-- [et_pb_line_break_holder] -->  #upl-tldr-jsapi .tldr-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-tldr-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-tldr-jsapi .tldr-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-tldr-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-tldr\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"tldr-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"tldr-eyebrow\"><span class=\"tldr-dot\"><\/span><span>TL;DR<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"tldr-h2\">5-Line Node.js Example<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"tldr-sub\">If you already know what a <a href=\"https:\/\/www.unipile.com\/send-email-api\/\" style=\"color:#2aaa7e;font-weight:600;\">Send Email API<\/a> is and just want to send email API JavaScript code that actually runs, here it is. The full tutorial follows below.<\/pee><!-- [et_pb_line_break_holder] -->    <div class=\"tldr-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"tldr-steps\"><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-num\">1<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-body\"><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-title\">Install the SDK<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-desc\"><code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">npm install unipile-node-sdk<\/code><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-num\">2<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-body\"><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-title\">Set env vars<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-desc\">Add <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">UNIPILE_DSN<\/code> and <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">UNIPILE_TOKEN<\/code> to your <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">.env<\/code> file.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-num\">3<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-body\"><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-title\">Link an email account<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-desc\">OAuth for Gmail\/Outlook or SMTP credentials for any IMAP server &#8211; one API call.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-num\">4<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"tldr-step-body\"><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-title\">Call <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">client.email.send()<\/code><\/div><!-- [et_pb_line_break_holder] -->            <div class=\"tldr-step-desc\">Pass <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">account_id<\/code>, <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">to<\/code>, <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">subject<\/code>, and <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:13px;color:#0f2736;\">body<\/code>. Done.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-info-strip\"><!-- [et_pb_line_break_holder] -->          Same code works for Gmail, Outlook, and any IMAP server &#8211; no provider-specific logic needed. Check the <a href=\"\/email-api-guide\/\">Email API guide<\/a> for the full concept overview.<!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"tldr-editor\"><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"tldr-dot-r\"><\/span><span class=\"tldr-dot-y\"><\/span><span class=\"tldr-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"tldr-fname\">send.mjs<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"tldr-pre\"><code><span class=\"t-k\">import<\/span><span class=\"t-w\"> <\/span><span class=\"t-fn\">{ UnipileClient }<\/span><span class=\"t-w\"> <\/span><span class=\"t-k\">from<\/span><span class=\"t-w\"> <\/span><span class=\"t-s\">'unipile-node-sdk'<\/span><span class=\"t-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"t-k\">const<\/span><span class=\"t-w\"> client <\/span><span class=\"t-fn\">= new<\/span><span class=\"t-w\"> <\/span><span class=\"t-fn\">UnipileClient<\/span><span class=\"t-w\">(<!-- [et_pb_line_break_holder] -->  process.env.<\/span><span class=\"t-n\">UNIPILE_DSN<\/span><span class=\"t-w\">,<!-- [et_pb_line_break_holder] -->  process.env.<\/span><span class=\"t-n\">UNIPILE_TOKEN<\/span><span class=\"t-w\"><!-- [et_pb_line_break_holder] -->);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"t-k\">const<\/span><span class=\"t-w\"> result <\/span><span class=\"t-fn\">= await<\/span><span class=\"t-w\"> client.email.<\/span><span class=\"t-fn\">send<\/span><span class=\"t-w\">({<!-- [et_pb_line_break_holder] -->  account_id: <\/span><span class=\"t-s\">'acc_xxxxxxxxxxxxxxxx'<\/span><span class=\"t-w\">,<!-- [et_pb_line_break_holder] -->  to: [{<!-- [et_pb_line_break_holder] -->    display_name: <\/span><span class=\"t-s\">'Alice Martin'<\/span><span class=\"t-w\">,<!-- [et_pb_line_break_holder] -->    identifier:   <\/span><span class=\"t-s\">'alice@acme.com'<\/span><span class=\"t-w\"><!-- [et_pb_line_break_holder] -->  }],<!-- [et_pb_line_break_holder] -->  subject: <\/span><span class=\"t-s\">'Hello from Node.js'<\/span><span class=\"t-w\">,<!-- [et_pb_line_break_holder] -->  body:    <\/span><span class=\"t-s\">'<pee>Sent via Unipile API!<\/pee>'<\/span><span class=\"t-w\"><!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"t-fn\">console<\/span><span class=\"t-w\">.<\/span><span class=\"t-fn\">log<\/span><span class=\"t-w\">(result); <\/span><span class=\"t-c\">\/\/ { tracking_id: 'msg_...' }<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi, #upl-prereqs-jsapi *, #upl-prereqs-jsapi *::before, #upl-prereqs-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi { padding:72px 20px!important;background:#f4f5f7!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;color:#8a8c2e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-dot { width:7px!important;height:7px!important;background:#DDDF4C!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:800px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-grid { display:grid!important;grid-template-columns:1fr 1fr!important;gap:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:16px!important;padding:28px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card-icon { width:44px!important;height:44px!important;border-radius:12px!important;background:rgba(59,185,139,0.12)!important;display:flex!important;align-items:center!important;justify-content:center!important;margin-bottom:16px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card-icon svg { width:22px!important;height:22px!important;stroke:#3BB98B!important;fill:none!important;stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card-title { font-family:'Poppins',sans-serif!important;font-size:17px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:10px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card-body { font-size:15px!important;line-height:1.7!important;color:#383838!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-card-body code { font-family:'Courier New',monospace!important;background:#f4f5f7!important;padding:2px 6px!important;border-radius:4px!important;font-size:13px!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->\/* Full-width install block *\/<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-install { margin-top:32px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-install-title { font-family:'Poppins',sans-serif!important;font-size:20px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-tabs { display:flex!important;gap:4px!important;margin-bottom:0!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-tab { padding:8px 16px!important;border-radius:8px 8px 0 0!important;background:#e5e7eb!important;color:#64748b!important;font-size:13px!important;font-weight:600!important;cursor:pointer!important;transition:all 0.2s!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-tab.active { background:#0d1117!important;color:#e6edf3!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-editor { border-radius:0 8px 8px 8px!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-editor-bar { background:#161b22!important;padding:12px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .p-dot-r {width:12px!important;height:12px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .p-dot-y {width:12px!important;height:12px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .p-dot-g {width:12px!important;height:12px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-fname { color:#8b949e!important;font-size:13px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-pane { display:none!important;padding:20px 24px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-pane.active { display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-pane code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important;font-size:13px!important;line-height:1.8!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .p-c {color:#8b949e!important;}#upl-prereqs-jsapi .p-k {color:#ff7b72!important;}#upl-prereqs-jsapi .p-fn {color:#d2a8ff!important;}#upl-prereqs-jsapi .p-s {color:#a5d6ff!important;}#upl-prereqs-jsapi .p-w {color:#e6edf3!important;}#upl-prereqs-jsapi .p-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->\/* .env card *\/<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-env-card { background:#0d1117!important;border-radius:14px!important;overflow:hidden!important;margin-top:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-env-bar { background:#161b22!important;padding:12px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-env-pre { padding:20px 24px!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-env-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important;font-size:13px!important;line-height:1.8!important; }<!-- [et_pb_line_break_holder] -->#upl-prereqs-jsapi .pre-note { margin-top:12px!important;font-size:13px!important;color:#718096!important;line-height:1.6!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-prereqs-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-prereqs-jsapi .pre-grid {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-prereqs-jsapi .pre-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-prereqs-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-prereqs-jsapi .pre-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-prereqs-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-prereqs\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"pre-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"pre-eyebrow\"><span class=\"pre-dot\"><\/span><span>Setup<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"pre-h2\">Prerequisites &#038; Setup<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"pre-sub\">Before you can use the send email API JavaScript workflow in production, you need four things: a supported Node.js version, the Unipile SDK, an API key, and a DSN endpoint.<\/pee><!-- [et_pb_line_break_holder] -->    <div class=\"pre-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"pre-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-icon\"><svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"\/><polyline points=\"8 6 2 12 8 18\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-title\">Node.js 18+ (20 recommended)<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-body\">The Unipile SDK uses native <code>fetch<\/code> and top-level <code>await<\/code>. Node 20 LTS is recommended for production. Check your version with <code>node -v<\/code>.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-title\">Unipile API Key &#038; DSN<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-body\">Sign up at the Unipile dashboard to get your access token and DSN (a personal HTTPS endpoint like <code>api4.unipile.com:13444<\/code>). Both are required to initialise the client.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-title\">ESM or CommonJS<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-body\">The SDK supports both. For ESM, use <code>.mjs<\/code> files or set <code>\"type\":\"module\"<\/code> in <code>package.json<\/code>. For CommonJS, dynamic <code>import()<\/code> works too &#8211; examples shown below.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-icon\"><svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-title\">A linked email account<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-card-body\">You send email <em>through<\/em> a linked account (Gmail, Outlook, or IMAP). The next section walks you through the OAuth flow to link one. You only do this once per account.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"pre-install\"><!-- [et_pb_line_break_holder] -->      <div class=\"pre-install-title\">Installing the Unipile SDK<\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-tabs\"><!-- [et_pb_line_break_holder] -->        <div class=\"pre-tab active\" onclick=\"switchTab(this,'npm')\"><span>npm<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-tab\" onclick=\"switchTab(this,'yarn')\"><span>yarn<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pre-tab\" onclick=\"switchTab(this,'pnpm')\"><span>pnpm<\/span><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-editor\"><!-- [et_pb_line_break_holder] -->        <div id=\"pre-pane-npm\" class=\"pre-pane active\"><code><span class=\"p-w\">npm install unipile-node-sdk<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <div id=\"pre-pane-yarn\" class=\"pre-pane\"><code><span class=\"p-w\">yarn add unipile-node-sdk<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <div id=\"pre-pane-pnpm\" class=\"pre-pane\"><code><span class=\"p-w\">pnpm add unipile-node-sdk<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"pre-env-card\"><!-- [et_pb_line_break_holder] -->      <div class=\"pre-env-bar\"><!-- [et_pb_line_break_holder] -->        <span class=\"p-dot-r\"><\/span><span class=\"p-dot-y\"><\/span><span class=\"p-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->        <span class=\"pre-fname\">.env<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"pre-env-pre\"><code><span class=\"p-c\"># Unipile credentials (never commit this file)<\/span><span class=\"p-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"p-n\">UNIPILE_DSN<\/span><span class=\"p-w\">=https:\/\/api4.unipile.com:13444<!-- [et_pb_line_break_holder] --><\/span><span class=\"p-n\">UNIPILE_TOKEN<\/span><span class=\"p-w\">=your_access_token_here<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"p-c\"># The account ID of the linked email account<\/span><span class=\"p-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"p-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"p-w\">=acc_xxxxxxxxxxxxxxxx<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <pee class=\"pre-note\">Add <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:12px;color:#0f2736;\">.env<\/code> to your <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:12px;color:#0f2736;\">.gitignore<\/code>. Use <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:12px;color:#0f2736;\">dotenv<\/code> or the native Node 20.6+ <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:12px;color:#0f2736;\">--env-file<\/code> flag to load it: <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:12px;color:#0f2736;\">node --env-file=.env send.mjs<\/code>.<\/pee><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->function switchTab(el, id) {<!-- [et_pb_line_break_holder] -->  el.closest('.pre-install').querySelectorAll('.pre-tab').forEach(function(t){ t.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->  el.classList.add('active');<!-- [et_pb_line_break_holder] -->  el.closest('.pre-install').querySelectorAll('.pre-pane').forEach(function(p){ p.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->  document.getElementById('pre-pane-' + id).classList.add('active');<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-connect-jsapi, #upl-connect-jsapi *, #upl-connect-jsapi *::before, #upl-connect-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi { padding:72px 20px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-dot { width:7px!important;height:7px!important;background:#3BB98B!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:12px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-sub a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-intro-note { font-size:15px!important;color:#718096!important;line-height:1.7!important;margin-bottom:36px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->\/* Provider tabs *\/<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-tabs { display:flex!important;gap:8px!important;margin-bottom:0!important;flex-wrap:wrap!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-tab {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  padding:10px 18px!important;border-radius:10px 10px 0 0!important;<!-- [et_pb_line_break_holder] -->  background:#f4f5f7!important;color:#64748b!important;<!-- [et_pb_line_break_holder] -->  font-size:14px!important;font-weight:600!important;cursor:pointer!important;<!-- [et_pb_line_break_holder] -->  border:1px solid #e5e7eb!important;border-bottom:none!important;<!-- [et_pb_line_break_holder] -->  transition:all 0.2s!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-tab img { width:18px!important;height:18px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-tab.active { background:#0d1117!important;color:#e6edf3!important;border-color:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-editor { border-radius:0 8px 8px 8px!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-editor-bar { background:#161b22!important;padding:12px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .c-dot-r {width:12px!important;height:12px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .c-dot-y {width:12px!important;height:12px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .c-dot-g {width:12px!important;height:12px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-fname { color:#8b949e!important;font-size:13px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-pane { display:none!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-pane.active { display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-pre { padding:22px 24px!important;font-size:13px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .cn-c {color:#8b949e!important;}#upl-connect-jsapi .cn-k {color:#ff7b72!important;}#upl-connect-jsapi .cn-fn {color:#d2a8ff!important;}#upl-connect-jsapi .cn-s {color:#a5d6ff!important;}#upl-connect-jsapi .cn-w {color:#e6edf3!important;}#upl-connect-jsapi .cn-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->\/* Info cards below tabs *\/<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-grid { display:grid!important;grid-template-columns:repeat(3,1fr)!important;gap:20px!important;margin-top:32px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card { background:#f4f5f7!important;border-radius:12px!important;padding:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card-head { display:flex!important;align-items:center!important;gap:10px!important;margin-bottom:10px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card-head img { width:24px!important;height:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card-title { font-size:14px!important;font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card-body { font-size:13px!important;color:#718096!important;line-height:1.65!important; }<!-- [et_pb_line_break_holder] -->#upl-connect-jsapi .con-info-card-body a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi .con-info-grid {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi .con-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi .con-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi .con-tabs {gap:4px!important;}<!-- [et_pb_line_break_holder] -->  #upl-connect-jsapi .con-tab {font-size:12px!important;padding:8px 12px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-connect-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-connect\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"con-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"con-eyebrow\"><span class=\"con-dot\"><\/span><span>Account Linking<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"con-h2\">Connecting Your First Email Account<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"con-sub\">The <a href=\"https:\/\/www.unipile.com\/unified-email-api-integration\/\" target=\"_self\">unified email API<\/a> uses a single <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:14px;color:#0f2736;\">account_id<\/code> to abstract provider differences. Link an account once, then call <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:14px;color:#0f2736;\">client.email.send()<\/code> identically across all three providers.<\/pee><!-- [et_pb_line_break_holder] -->    <pee class=\"con-intro-note\">Pick your provider below to see the exact Node.js snippet. The account_id returned is what you store and reuse for every subsequent send.<\/pee><!-- [et_pb_line_break_holder] -->    <div class=\"con-tabs\"><!-- [et_pb_line_break_holder] -->      <div class=\"con-tab active\" onclick=\"conTab(this,'gmail')\"><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/gmail-3.svg\" alt=\"Gmail\"><span>Gmail OAuth<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"con-tab\" onclick=\"conTab(this,'outlook')\"><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/outlook-2.svg\" alt=\"Outlook\"><span>Outlook \/ Microsoft 365<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"con-tab\" onclick=\"conTab(this,'imap')\"><!-- [et_pb_line_break_holder] -->        <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/imap-1.svg\" alt=\"IMAP\"><span>SMTP \/ IMAP<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"con-editor\"><!-- [et_pb_line_break_holder] -->      <!-- Gmail --><!-- [et_pb_line_break_holder] -->      <div id=\"con-pane-gmail\" class=\"con-pane active\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"c-dot-r\"><\/span><span class=\"c-dot-y\"><\/span><span class=\"c-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"con-fname\">connect-gmail.mjs<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-pre\"><code><span class=\"cn-k\">import<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">{ UnipileClient }<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-k\">from<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-s\">'unipile-node-sdk'<\/span><span class=\"cn-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> client <\/span><span class=\"cn-fn\">= new<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">UnipileClient<\/span><span class=\"cn-w\">(process.env.<\/span><span class=\"cn-n\">UNIPILE_DSN<\/span><span class=\"cn-w\">, process.env.<\/span><span class=\"cn-n\">UNIPILE_TOKEN<\/span><span class=\"cn-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Step 1: generate a hosted OAuth link for Gmail<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">{ url }<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">= await<\/span><span class=\"cn-w\"> client.account.<\/span><span class=\"cn-fn\">createHostedAuthLink<\/span><span class=\"cn-w\">({<!-- [et_pb_line_break_holder] -->  type:          <\/span><span class=\"cn-s\">'GOOGLE'<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  success_redirect_url: process.env.<\/span><span class=\"cn-n\">OAUTH_CALLBACK_URL<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  failure_redirect_url: process.env.<\/span><span class=\"cn-n\">OAUTH_CALLBACK_URL<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-s\">+ '?error=1'<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Step 2: redirect your user to `url`<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-fn\">console<\/span><span class=\"cn-w\">.<\/span><span class=\"cn-fn\">log<\/span><span class=\"cn-w\">(<\/span><span class=\"cn-s\">'Redirect user to:'<\/span><span class=\"cn-w\">, url);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Step 3: Unipile POSTs the account_id to your callback<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Store it: process.env.EMAIL_ACCOUNT_ID = result.account_id<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <!-- Outlook --><!-- [et_pb_line_break_holder] -->      <div id=\"con-pane-outlook\" class=\"con-pane\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"c-dot-r\"><\/span><span class=\"c-dot-y\"><\/span><span class=\"c-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"con-fname\">connect-outlook.mjs<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-pre\"><code><span class=\"cn-k\">import<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">{ UnipileClient }<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-k\">from<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-s\">'unipile-node-sdk'<\/span><span class=\"cn-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> client <\/span><span class=\"cn-fn\">= new<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">UnipileClient<\/span><span class=\"cn-w\">(process.env.<\/span><span class=\"cn-n\">UNIPILE_DSN<\/span><span class=\"cn-w\">, process.env.<\/span><span class=\"cn-n\">UNIPILE_TOKEN<\/span><span class=\"cn-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Works for personal Outlook AND Microsoft 365 \/ Exchange Online<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">{ url }<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">= await<\/span><span class=\"cn-w\"> client.account.<\/span><span class=\"cn-fn\">createHostedAuthLink<\/span><span class=\"cn-w\">({<!-- [et_pb_line_break_holder] -->  type:          <\/span><span class=\"cn-s\">'MICROSOFT'<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  success_redirect_url: process.env.<\/span><span class=\"cn-n\">OAUTH_CALLBACK_URL<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  failure_redirect_url: process.env.<\/span><span class=\"cn-n\">OAUTH_CALLBACK_URL<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-s\">+ '?error=1'<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ Redirect user -> they complete Microsoft OAuth flow<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-fn\">console<\/span><span class=\"cn-w\">.<\/span><span class=\"cn-fn\">log<\/span><span class=\"cn-w\">(<\/span><span class=\"cn-s\">'Redirect user to:'<\/span><span class=\"cn-w\">, url);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ See: \/syncing-emails-with-microsoft-graph-api-a-developers-guide\/<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <!-- IMAP --><!-- [et_pb_line_break_holder] -->      <div id=\"con-pane-imap\" class=\"con-pane\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"c-dot-r\"><\/span><span class=\"c-dot-y\"><\/span><span class=\"c-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"con-fname\">connect-imap.mjs<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-pre\"><code><span class=\"cn-k\">import<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">{ UnipileClient }<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-k\">from<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-s\">'unipile-node-sdk'<\/span><span class=\"cn-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> client <\/span><span class=\"cn-fn\">= new<\/span><span class=\"cn-w\"> <\/span><span class=\"cn-fn\">UnipileClient<\/span><span class=\"cn-w\">(process.env.<\/span><span class=\"cn-n\">UNIPILE_DSN<\/span><span class=\"cn-w\">, process.env.<\/span><span class=\"cn-n\">UNIPILE_TOKEN<\/span><span class=\"cn-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-c\">\/\/ SMTP\/IMAP: pass credentials directly (no OAuth redirect)<\/span><span class=\"cn-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-k\">const<\/span><span class=\"cn-w\"> account <\/span><span class=\"cn-fn\">= await<\/span><span class=\"cn-w\"> client.account.<\/span><span class=\"cn-fn\">create<\/span><span class=\"cn-w\">({<!-- [et_pb_line_break_holder] -->  type:     <\/span><span class=\"cn-s\">'IMAP'<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  imap: {<!-- [et_pb_line_break_holder] -->    username: process.env.<\/span><span class=\"cn-n\">IMAP_USER<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    password: process.env.<\/span><span class=\"cn-n\">IMAP_PASS<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    host:     process.env.<\/span><span class=\"cn-n\">IMAP_HOST<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    port:     <\/span><span class=\"cn-n\">993<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->  smtp: {<!-- [et_pb_line_break_holder] -->    username: process.env.<\/span><span class=\"cn-n\">IMAP_USER<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    password: process.env.<\/span><span class=\"cn-n\">IMAP_PASS<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    host:     process.env.<\/span><span class=\"cn-n\">SMTP_HOST<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->    port:     <\/span><span class=\"cn-n\">587<\/span><span class=\"cn-w\">,<!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"cn-fn\">console<\/span><span class=\"cn-w\">.<\/span><span class=\"cn-fn\">log<\/span><span class=\"cn-w\">(account.account_id); <\/span><span class=\"cn-c\">\/\/ store this<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"con-info-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"con-info-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-head\"><!-- [et_pb_line_break_holder] -->          <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/gmail-3.svg\" alt=\"Gmail\"><!-- [et_pb_line_break_holder] -->          <span class=\"con-info-card-title\">Gmail<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-body\">Uses Google OAuth 2.0. No app passwords needed. See the full <a href=\"\/gmail-api-send-email\/\" target=\"_self\">Gmail API send email tutorial<\/a> for scopes and consent screen setup.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"con-info-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-head\"><!-- [et_pb_line_break_holder] -->          <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/outlook-2.svg\" alt=\"Outlook\"><!-- [et_pb_line_break_holder] -->          <span class=\"con-info-card-title\">Outlook \/ Microsoft 365<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-body\">Uses Microsoft Graph OAuth. Covers personal Outlook and M365 tenants. Details in the <a href=\"\/syncing-emails-with-microsoft-graph-api-a-developers-guide\/\" target=\"_self\">Microsoft Graph email guide<\/a>.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"con-info-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-head\"><!-- [et_pb_line_break_holder] -->          <img decoding=\"async\" src=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/imap-1.svg\" alt=\"IMAP\"><!-- [et_pb_line_break_holder] -->          <span class=\"con-info-card-title\">SMTP \/ IMAP<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"con-info-card-body\">Works with any provider that exposes IMAP\/SMTP (Yahoo, ProtonMail Bridge, custom mail servers). Read the <a href=\"\/the-developers-guide-to-imap-api-solution\/\" target=\"_self\">IMAP API solution guide<\/a>.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->function conTab(el, id) {<!-- [et_pb_line_break_holder] -->  el.closest('.con-inner').querySelectorAll('.con-tab').forEach(function(t){ t.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->  el.classList.add('active');<!-- [et_pb_line_break_holder] -->  el.closest('.con-inner').querySelectorAll('.con-pane').forEach(function(p){ p.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->  document.getElementById('con-pane-' + id).classList.add('active');<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-send-jsapi, #upl-send-jsapi *, #upl-send-jsapi *::before, #upl-send-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi { padding:72px 20px!important;background:#f4f5f7!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;color:#8a8c2e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-dot { width:7px!important;height:7px!important;background:#DDDF4C!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-blocks { display:flex!important;flex-direction:column!important;gap:32px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-block { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:16px!important;overflow:hidden!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-block-header { padding:20px 24px!important;border-bottom:1px solid #f0f1f3!important;display:flex!important;align-items:center!important;gap:12px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-block-num { width:32px!important;height:32px!important;min-width:32px!important;border-radius:8px!important;background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;display:flex!important;align-items:center!important;justify-content:center!important;font-family:'Poppins',sans-serif!important;font-size:13px!important;font-weight:700!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-block-title { font-family:'Poppins',sans-serif!important;font-size:17px!important;font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-block-desc { font-size:14px!important;color:#718096!important;margin-left:auto!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-editor { border-radius:0!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-editor-bar { background:#161b22!important;padding:10px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .s-dot-r {width:11px!important;height:11px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .s-dot-y {width:11px!important;height:11px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .s-dot-g {width:11px!important;height:11px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-fname { color:#8b949e!important;font-size:12px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-pre { padding:20px 24px!important;font-size:13px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .s-c {color:#8b949e!important;}#upl-send-jsapi .s-k {color:#ff7b72!important;}#upl-send-jsapi .s-fn {color:#d2a8ff!important;}#upl-send-jsapi .s-s {color:#a5d6ff!important;}#upl-send-jsapi .s-w {color:#e6edf3!important;}#upl-send-jsapi .s-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-ok { background:rgba(59,185,139,0.10)!important;border-top:1px solid rgba(59,185,139,0.25)!important;color:#3BB98B!important;padding:10px 24px!important;font-size:12px!important;font-family:'Courier New',monospace!important;display:flex!important;align-items:center!important;gap:8px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-ok svg { width:13px!important;height:13px!important;stroke:#3BB98B!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->\/* Field reference table *\/<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table-wrap { padding:24px!important;overflow-x:auto!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table { width:100%!important;border-collapse:collapse!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table th { background:#f8fafc!important;color:#0f2736!important;font-size:12px!important;font-weight:700!important;text-transform:uppercase!important;letter-spacing:0.5px!important;padding:10px 14px!important;text-align:left!important;border-bottom:2px solid #e5e7eb!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table td { padding:10px 14px!important;font-size:13px!important;color:#383838!important;border-bottom:1px solid #f0f1f3!important;vertical-align:top!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table tr:last-child td { border-bottom:none!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-table code { font-family:'Courier New',monospace!important;background:#f4f5f7!important;padding:2px 6px!important;border-radius:4px!important;font-size:12px!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-badge-req { display:inline-block!important;background:rgba(234,67,53,0.12)!important;color:#c53030!important;font-size:10px!important;font-weight:700!important;padding:2px 6px!important;border-radius:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-send-jsapi .snd-badge-opt { display:inline-block!important;background:#f1f5f9!important;color:#718096!important;font-size:10px!important;font-weight:700!important;padding:2px 6px!important;border-radius:4px!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-send-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-send-jsapi .snd-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->  #upl-send-jsapi .snd-block-desc {display:none!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-send-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-send-jsapi .snd-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-send-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-send\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"snd-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"snd-eyebrow\"><span class=\"snd-dot\"><\/span><span>Core API<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"snd-h2\">Sending Your First Email from Node.js<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"snd-sub\">Three production-ready patterns for the send email API JavaScript workflow: plain text, HTML with CC\/BCC, and reading the response object. All use the same <code style=\"font-family:'Courier New',monospace;background:#e2e8f0;padding:2px 6px;border-radius:4px;font-size:14px;color:#0f2736;\">client.email.send()<\/code> call.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"snd-blocks\"><!-- [et_pb_line_break_holder] -->      <!-- Block 1: plain text --><!-- [et_pb_line_break_holder] -->      <div class=\"snd-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"snd-block-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-num\">1<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-title\">Plain-text email<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-desc\">Simplest case<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"snd-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"snd-editor-bar\"><span class=\"s-dot-r\"><\/span><span class=\"s-dot-y\"><\/span><span class=\"s-dot-g\"><\/span><span class=\"snd-fname\">plain-text.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-pre\"><code><span class=\"s-k\">import<\/span><span class=\"s-w\"> <\/span><span class=\"s-fn\">{ UnipileClient }<\/span><span class=\"s-w\"> <\/span><span class=\"s-k\">from<\/span><span class=\"s-w\"> <\/span><span class=\"s-s\">'unipile-node-sdk'<\/span><span class=\"s-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"s-k\">const<\/span><span class=\"s-w\"> client <\/span><span class=\"s-fn\">= new<\/span><span class=\"s-w\"> <\/span><span class=\"s-fn\">UnipileClient<\/span><span class=\"s-w\">(process.env.<\/span><span class=\"s-n\">UNIPILE_DSN<\/span><span class=\"s-w\">, process.env.<\/span><span class=\"s-n\">UNIPILE_TOKEN<\/span><span class=\"s-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"s-k\">const<\/span><span class=\"s-w\"> result <\/span><span class=\"s-fn\">= await<\/span><span class=\"s-w\"> client.email.<\/span><span class=\"s-fn\">send<\/span><span class=\"s-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"s-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] -->  to: [{ display_name: <\/span><span class=\"s-s\">'Bob'<\/span><span class=\"s-w\">, identifier: <\/span><span class=\"s-s\">'bob@example.com'<\/span><span class=\"s-w\"> }],<!-- [et_pb_line_break_holder] -->  subject: <\/span><span class=\"s-s\">'Welcome to the platform'<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] -->  body:    <\/span><span class=\"s-s\">'Hi Bob, your account is ready.'<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"s-fn\">console<\/span><span class=\"s-w\">.<\/span><span class=\"s-fn\">log<\/span><span class=\"s-w\">(result.tracking_id); <\/span><span class=\"s-c\">\/\/ msg_xxxxxxxxxxxxxxxx<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"snd-ok\"><svg viewBox=\"0 0 24 24\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><span>202 Accepted &#8211; result.tracking_id populated<\/span><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- Block 2: HTML + CC\/BCC --><!-- [et_pb_line_break_holder] -->      <div class=\"snd-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"snd-block-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-num\">2<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-title\">HTML body with CC and BCC<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-desc\">Multi-recipient<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"snd-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"snd-editor-bar\"><span class=\"s-dot-r\"><\/span><span class=\"s-dot-y\"><\/span><span class=\"s-dot-g\"><\/span><span class=\"snd-fname\">html-cc-bcc.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-pre\"><code><span class=\"s-k\">const<\/span><span class=\"s-w\"> result <\/span><span class=\"s-fn\">= await<\/span><span class=\"s-w\"> client.email.<\/span><span class=\"s-fn\">send<\/span><span class=\"s-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"s-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  to:  [{ display_name: <\/span><span class=\"s-s\">'Alice'<\/span><span class=\"s-w\">,   identifier: <\/span><span class=\"s-s\">'alice@acme.com'<\/span><span class=\"s-w\">   }],<!-- [et_pb_line_break_holder] -->  cc:  [{ display_name: <\/span><span class=\"s-s\">'Manager'<\/span><span class=\"s-w\">, identifier: <\/span><span class=\"s-s\">'boss@acme.com'<\/span><span class=\"s-w\">    }],<!-- [et_pb_line_break_holder] -->  bcc: [{ display_name: <\/span><span class=\"s-s\">'Audit'<\/span><span class=\"s-w\">,   identifier: <\/span><span class=\"s-s\">'audit@internal.io'<\/span><span class=\"s-w\"> }],<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  subject: <\/span><span class=\"s-s\">'Your invoice #1042'<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/span><span class=\"s-c\">\/\/ HTML body - provider renders it natively<\/span><span class=\"s-w\"><!-- [et_pb_line_break_holder] -->  body: <\/span><span class=\"s-s\">`<!-- [et_pb_line_break_holder] -->    <h2>Invoice #1042<\/h2><!-- [et_pb_line_break_holder] -->    <pee>Amount due: <strong>$299<\/strong><\/pee><!-- [et_pb_line_break_holder] -->    <a href=\"https:\/\/pay.acme.com\/1042\">Pay now<\/a><!-- [et_pb_line_break_holder] -->  `<\/span><span class=\"s-w\">,<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"s-fn\">console<\/span><span class=\"s-w\">.<\/span><span class=\"s-fn\">log<\/span><span class=\"s-w\">(<\/span><span class=\"s-s\">'Sent:'<\/span><span class=\"s-w\">, result.tracking_id);<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- Block 3: field reference --><!-- [et_pb_line_break_holder] -->      <div class=\"snd-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"snd-block-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-num\">3<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-title\">Full field reference<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"snd-block-desc\">All supported params<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"snd-table-wrap\"><!-- [et_pb_line_break_holder] -->          <table class=\"snd-table\"><!-- [et_pb_line_break_holder] -->            <thead><tr><th>Field<\/th><th>Type<\/th><th>Required<\/th><th>Description<\/th><\/tr><\/thead><!-- [et_pb_line_break_holder] -->            <tbody><!-- [et_pb_line_break_holder] -->              <tr><td><code>account_id<\/code><\/td><td><code>string<\/code><\/td><td><span class=\"snd-badge-req\">Required<\/span><\/td><td>ID of the linked email account to send from<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>to<\/code><\/td><td><code>Recipient[]<\/code><\/td><td><span class=\"snd-badge-req\">Required<\/span><\/td><td>Array of <code>{display_name, identifier}<\/code> objects<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>subject<\/code><\/td><td><code>string<\/code><\/td><td><span class=\"snd-badge-req\">Required<\/span><\/td><td>Email subject line<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>body<\/code><\/td><td><code>string<\/code><\/td><td><span class=\"snd-badge-req\">Required<\/span><\/td><td>Plain text or HTML string<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>cc<\/code><\/td><td><code>Recipient[]<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Carbon-copy recipients<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>bcc<\/code><\/td><td><code>Recipient[]<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Blind carbon-copy recipients<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>from<\/code><\/td><td><code>Recipient<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Override sender display name<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>reply_to<\/code><\/td><td><code>string<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Provider message ID to reply to (threads)<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>attachments<\/code><\/td><td><code>Array<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Array of <code>[filename, Buffer]<\/code> tuples<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>custom_headers<\/code><\/td><td><code>object[]<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td>Custom X- headers array<\/td><\/tr><!-- [et_pb_line_break_holder] -->              <tr><td><code>tracking_options<\/code><\/td><td><code>object<\/code><\/td><td><span class=\"snd-badge-opt\">Optional<\/span><\/td><td><code>{opens, links, label}<\/code> &#8211; enable open\/click tracking<\/td><\/tr><!-- [et_pb_line_break_holder] -->            <\/tbody><!-- [et_pb_line_break_holder] -->          <\/table><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi, #upl-midcta-jsapi *, #upl-midcta-jsapi *::before, #upl-midcta-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;border-radius:20px;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi { padding:56px 20px!important;background:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-inner { max-width:900px!important;margin:0 auto!important;display:flex!important;align-items:center!important;justify-content:space-between!important;gap:32px!important;flex-wrap:wrap!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-left {}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;color:#DDDF4C!important;<!-- [et_pb_line_break_holder] -->  padding:5px 12px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:11px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:14px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-title { font-family:'Poppins',sans-serif!important;font-size:26px!important;font-weight:700!important;color:#ffffff!important;line-height:1.3!important;margin-bottom:10px!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-desc { font-size:15px!important;color:rgba(255,255,255,0.75)!important;line-height:1.7!important;max-width:520px!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-actions { display:flex!important;align-items:center!important;gap:14px!important;flex-wrap:wrap!important;margin-top:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-primary {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:#DDDF4C!important;color:#0f2736!important;<!-- [et_pb_line_break_holder] -->  padding:13px 26px!important;border-radius:8px!important;<!-- [et_pb_line_break_holder] -->  font-size:0.9rem!important;font-weight:600!important;<!-- [et_pb_line_break_holder] -->  border:2px solid #DDDF4C!important;<!-- [et_pb_line_break_holder] -->  transition:all 0.3s ease!important;cursor:pointer!important;<!-- [et_pb_line_break_holder] -->  white-space:nowrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-primary:hover { transform:translateY(-5px)!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-primary svg { width:15px!important;height:15px!important;stroke:currentColor!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-secondary {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:transparent!important;color:#ffffff!important;<!-- [et_pb_line_break_holder] -->  padding:11px 22px!important;border-radius:8px!important;<!-- [et_pb_line_break_holder] -->  border:2px solid rgba(255,255,255,0.3)!important;<!-- [et_pb_line_break_holder] -->  font-size:0.9rem!important;font-weight:600!important;<!-- [et_pb_line_break_holder] -->  transition:all 0.3s ease!important;cursor:pointer!important;<!-- [et_pb_line_break_holder] -->  white-space:nowrap!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-secondary:hover { border-color:#ffffff!important;color:#ffffff!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-cta-secondary svg { width:15px!important;height:15px!important;stroke:currentColor!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-stats { display:flex!important;gap:28px!important;flex-wrap:wrap!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-stat {}<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-stat-num { font-family:'Poppins',sans-serif!important;font-size:28px!important;font-weight:700!important;color:#DDDF4C!important;line-height:1!important;margin-bottom:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-midcta-jsapi .mca-stat-label { font-size:12px!important;color:rgba(255,255,255,0.55)!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi {padding:48px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi .mca-inner {flex-direction:column!important;align-items:flex-start!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi .mca-title {font-size:22px!important;}<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi .mca-actions {flex-direction:column!important;width:100%!important;}<!-- [et_pb_line_break_holder] -->  #upl-midcta-jsapi .mca-cta-primary, #upl-midcta-jsapi .mca-cta-secondary {width:100%!important;justify-content:center!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-midcta-jsapi\"><!-- [et_pb_line_break_holder] -->  <div class=\"mca-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"mca-left\"><!-- [et_pb_line_break_holder] -->      <div class=\"mca-eyebrow\"><span>Free to start<\/span><\/div><!-- [et_pb_line_break_holder] -->      <div class=\"mca-title\">Ready to send email via API in JavaScript?<\/div><!-- [et_pb_line_break_holder] -->      <pee class=\"mca-desc\">Get your API key, link a Gmail or Outlook account in minutes, and run the Node.js examples from this guide against real mailboxes.<\/pee><!-- [et_pb_line_break_holder] -->      <div class=\"mca-actions\"><!-- [et_pb_line_break_holder] -->        <a href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" class=\"mca-cta-primary\" data-upl-link=\"https:\/\/dashboard.unipile.com\/signup\/\"><svg viewBox=\"0 0 24 24\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"\/><polyline points=\"10 17 15 12 10 7\"\/><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"\/><\/svg><span>Get your free API key<\/span><\/a><!-- [et_pb_line_break_holder] -->        <a href=\"\/email-api-guide\/\" target=\"_self\" class=\"mca-cta-secondary\" data-upl-link=\"\/email-api-guide\/\"><svg viewBox=\"0 0 24 24\"><path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\"\/><path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\"\/><\/svg><span>Read the full Email API guide<\/span><\/a><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->document.querySelectorAll('#upl-midcta-jsapi [data-upl-link]').forEach(function(el){<!-- [et_pb_line_break_holder] -->  el.addEventListener('click',function(e){<!-- [et_pb_line_break_holder] -->    e.preventDefault();<!-- [et_pb_line_break_holder] -->    var url=el.getAttribute('data-upl-link');<!-- [et_pb_line_break_holder] -->    if(url.startsWith('http')){window.open(url,'_blank');}else{window.location.href=url;}<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-attach-jsapi, #upl-attach-jsapi *, #upl-attach-jsapi *::before, #upl-attach-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi { padding:72px 20px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;color:#8a8c2e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-dot { width:7px!important;height:7px!important;background:#DDDF4C!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-grid { display:grid!important;grid-template-columns:1fr 1fr!important;gap:24px!important;margin-bottom:32px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card { background:#ffffff!important;border-radius:14px!important;padding:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card-icon { width:40px!important;height:40px!important;border-radius:10px!important;background:rgba(221,223,76,0.18)!important;display:flex!important;align-items:center!important;justify-content:center!important;margin-bottom:14px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card-icon svg { width:20px!important;height:20px!important;stroke:#8a8c2e!important;fill:none!important;stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card-title { font-size:15px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:6px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card-body { font-size:14px!important;color:#718096!important;line-height:1.65!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-card-body code { font-family:'Courier New',monospace!important;background:#ffffff!important;padding:2px 5px!important;border-radius:3px!important;font-size:12px!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->\/* editors *\/<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-editor { border-radius:14px!important;overflow:hidden!important;background:#0d1117!important;margin-bottom:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-editor-bar { background:#161b22!important;padding:11px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .a-dot-r {width:11px!important;height:11px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .a-dot-y {width:11px!important;height:11px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .a-dot-g {width:11px!important;height:11px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-fname { color:#8b949e!important;font-size:12px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-pre { padding:20px 24px!important;font-size:13px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .a-c {color:#8b949e!important;}#upl-attach-jsapi .a-k {color:#ff7b72!important;}#upl-attach-jsapi .a-fn {color:#d2a8ff!important;}#upl-attach-jsapi .a-s {color:#a5d6ff!important;}#upl-attach-jsapi .a-w {color:#e6edf3!important;}#upl-attach-jsapi .a-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->\/* warning strip *\/<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-warn { background:rgba(251,188,4,0.10)!important;border-left:3px solid #FBBC04!important;border-radius:0 8px 8px 0!important;padding:14px 18px!important;font-size:14px!important;color:#0f2736!important;line-height:1.65!important; }<!-- [et_pb_line_break_holder] -->#upl-attach-jsapi .att-warn strong { font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-attach-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-attach-jsapi .att-grid {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-attach-jsapi .att-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-attach-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-attach-jsapi .att-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-attach-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-attachments\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"att-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"att-eyebrow\"><span class=\"att-dot\"><\/span><span>Attachments<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"att-h2\">Sending Attachments in Node.js<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"att-sub\">The <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:15px;color:#0f2736;\">attachments<\/code> field accepts an array of <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:15px;color:#0f2736;\">[filename, Buffer]<\/code> tuples. Read the file with Node&#8217;s <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:15px;color:#0f2736;\">fs.readFileSync<\/code> or stream it with <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 6px;border-radius:4px;font-size:15px;color:#0f2736;\">fs.promises.readFile<\/code>.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"att-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"att-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-title\">Single file from disk<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-body\">Use <code>fs.promises.readFile(path)<\/code> to get a Buffer, then pass <code>['filename.pdf', buffer]<\/code>. Works for PDF, DOCX, images, any binary.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"att-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-icon\"><svg viewBox=\"0 0 24 24\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"\/><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"\/><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-title\">Multiple attachments<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-body\">Pass an array of tuples. Each tuple is independent &#8211; mix file types freely. No hard cap per attachment, but keep total payload under your plan&#8217;s limit.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"att-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z\"\/><line x1=\"4\" y1=\"22\" x2=\"4\" y2=\"15\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-title\">Inline images (CID)<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-body\">Embed images in the HTML body using the <code>cid:<\/code> scheme. Reference the same filename used in the attachments tuple: <code>&lt;img src=\"cid:logo.png\"&gt;<\/code>.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"att-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-icon\"><svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-title\">Buffer from a stream<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"att-card-body\">Generate a PDF on-the-fly (e.g., with <code>pdfkit<\/code>), collect it into a Buffer, and attach without writing to disk. Production-safe for serverless.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <!-- Single attachment --><!-- [et_pb_line_break_holder] -->    <div class=\"att-editor\"><!-- [et_pb_line_break_holder] -->      <div class=\"att-editor-bar\"><span class=\"a-dot-r\"><\/span><span class=\"a-dot-y\"><\/span><span class=\"a-dot-g\"><\/span><span class=\"att-fname\">attach-file.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->      <div class=\"att-pre\"><code><span class=\"a-k\">import<\/span><span class=\"a-w\"> <\/span><span class=\"a-fn\">{ UnipileClient }<\/span><span class=\"a-w\"> <\/span><span class=\"a-k\">from<\/span><span class=\"a-w\"> <\/span><span class=\"a-s\">'unipile-node-sdk'<\/span><span class=\"a-w\">;<!-- [et_pb_line_break_holder] --><\/span><span class=\"a-k\">import<\/span><span class=\"a-w\"> { promises <\/span><span class=\"a-k\">as<\/span><span class=\"a-w\"> fs } <\/span><span class=\"a-k\">from<\/span><span class=\"a-w\"> <\/span><span class=\"a-s\">'node:fs'<\/span><span class=\"a-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"a-k\">const<\/span><span class=\"a-w\"> client <\/span><span class=\"a-fn\">= new<\/span><span class=\"a-w\"> <\/span><span class=\"a-fn\">UnipileClient<\/span><span class=\"a-w\">(process.env.<\/span><span class=\"a-n\">UNIPILE_DSN<\/span><span class=\"a-w\">, process.env.<\/span><span class=\"a-n\">UNIPILE_TOKEN<\/span><span class=\"a-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"a-c\">\/\/ Read file into a Buffer<\/span><span class=\"a-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"a-k\">const<\/span><span class=\"a-w\"> pdfBuffer <\/span><span class=\"a-fn\">= await<\/span><span class=\"a-w\"> fs.<\/span><span class=\"a-fn\">readFile<\/span><span class=\"a-w\">(<\/span><span class=\"a-s\">'.\/invoice.pdf'<\/span><span class=\"a-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"a-k\">await<\/span><span class=\"a-w\"> client.email.<\/span><span class=\"a-fn\">send<\/span><span class=\"a-w\">({<!-- [et_pb_line_break_holder] -->  account_id:  process.env.<\/span><span class=\"a-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  to:          [{ display_name: <\/span><span class=\"a-s\">'Client'<\/span><span class=\"a-w\">, identifier: <\/span><span class=\"a-s\">'client@example.com'<\/span><span class=\"a-w\"> }],<!-- [et_pb_line_break_holder] -->  subject:     <\/span><span class=\"a-s\">'Your invoice is attached'<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  body:        <\/span><span class=\"a-s\">'<pee>Please find your invoice attached.<\/pee>'<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  attachments: [<!-- [et_pb_line_break_holder] -->    [<\/span><span class=\"a-s\">'invoice.pdf'<\/span><span class=\"a-w\">, pdfBuffer],   <\/span><span class=\"a-c\">\/\/ [filename, Buffer]<\/span><span class=\"a-w\"><!-- [et_pb_line_break_holder] -->  ],<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <!-- Multiple + inline image --><!-- [et_pb_line_break_holder] -->    <div class=\"att-editor\"><!-- [et_pb_line_break_holder] -->      <div class=\"att-editor-bar\"><span class=\"a-dot-r\"><\/span><span class=\"a-dot-y\"><\/span><span class=\"a-dot-g\"><\/span><span class=\"att-fname\">attach-multiple-inline.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->      <div class=\"att-pre\"><code><span class=\"a-k\">const<\/span><span class=\"a-w\"> [logo, report] <\/span><span class=\"a-fn\">= await<\/span><span class=\"a-w\"> <\/span><span class=\"a-fn\">Promise.all<\/span><span class=\"a-w\">([<!-- [et_pb_line_break_holder] -->  fs.<\/span><span class=\"a-fn\">readFile<\/span><span class=\"a-w\">(<\/span><span class=\"a-s\">'.\/logo.png'<\/span><span class=\"a-w\">),<!-- [et_pb_line_break_holder] -->  fs.<\/span><span class=\"a-fn\">readFile<\/span><span class=\"a-w\">(<\/span><span class=\"a-s\">'.\/report.xlsx'<\/span><span class=\"a-w\">),<!-- [et_pb_line_break_holder] -->]);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"a-k\">await<\/span><span class=\"a-w\"> client.email.<\/span><span class=\"a-fn\">send<\/span><span class=\"a-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"a-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  to:         [{ display_name: <\/span><span class=\"a-s\">'Team'<\/span><span class=\"a-w\">, identifier: <\/span><span class=\"a-s\">'team@acme.com'<\/span><span class=\"a-w\"> }],<!-- [et_pb_line_break_holder] -->  subject:    <\/span><span class=\"a-s\">'Q1 Report'<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  body: <\/span><span class=\"a-s\">`<!-- [et_pb_line_break_holder] -->    &lt;img src=\"cid:logo.png\" alt=\"Logo\" width=\"120\"&gt;<!-- [et_pb_line_break_holder] -->    <h2>Q1 Report<\/h2><!-- [et_pb_line_break_holder] -->    <pee>See the attached spreadsheet for details.<\/pee><!-- [et_pb_line_break_holder] -->  `<\/span><span class=\"a-w\">,<!-- [et_pb_line_break_holder] -->  attachments: [<!-- [et_pb_line_break_holder] -->    [<\/span><span class=\"a-s\">'logo.png'<\/span><span class=\"a-w\">,   logo],   <\/span><span class=\"a-c\">\/\/ inline via cid:logo.png in body<\/span><span class=\"a-w\"><!-- [et_pb_line_break_holder] -->    [<\/span><span class=\"a-s\">'report.xlsx'<\/span><span class=\"a-w\">, report], <\/span><span class=\"a-c\">\/\/ regular attachment<\/span><span class=\"a-w\"><!-- [et_pb_line_break_holder] -->  ],<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"att-warn\"><strong>Size limit:<\/strong> Keep individual attachments under 25 MB (Gmail&#8217;s hard limit). For large files, upload to cloud storage and include a download link in the email body instead.<\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-adv-jsapi, #upl-adv-jsapi *, #upl-adv-jsapi *::before, #upl-adv-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi { padding:72px 20px!important;background:#f4f5f7!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-dot { width:7px!important;height:7px!important;background:#3BB98B!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-sub a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->\/* Accordion *\/<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi details.adv-acc { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:16px!important;overflow:hidden!important;transition:border-color 0.2s ease!important;margin-bottom:16px!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi details.adv-acc[open] { border-color:#3BB98B!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi details.adv-acc summary { list-style:none!important;cursor:pointer!important;padding:20px 24px!important;display:flex!important;align-items:center!important;gap:14px!important;user-select:none!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi details.adv-acc summary::-webkit-details-marker { display:none!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-num { width:38px!important;height:38px!important;min-width:38px!important;border-radius:10px!important;background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;display:flex!important;align-items:center!important;justify-content:center!important;font-family:'Poppins',sans-serif!important;font-size:14px!important;font-weight:700!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-title { font-size:16px!important;font-weight:700!important;color:#0f2736!important;flex:1!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-chevron { color:#6b7280!important;transition:transform 0.25s ease,color 0.2s ease!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi details.adv-acc[open] .adv-acc-chevron { transform:rotate(180deg)!important;color:#3BB98B!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-body { padding:0 24px 24px!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-desc { font-size:15px!important;color:#383838!important;line-height:1.7!important;margin-bottom:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-acc-desc a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->\/* mini editor inside accordion *\/<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-editor { border-radius:12px!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-editor-bar { background:#161b22!important;padding:10px 16px!important;display:flex!important;align-items:center!important;gap:7px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .v-dot-r {width:10px!important;height:10px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .v-dot-y {width:10px!important;height:10px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .v-dot-g {width:10px!important;height:10px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-fname { color:#8b949e!important;font-size:12px!important;margin-left:5px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-pre { padding:18px 20px!important;font-size:12.5px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .adv-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-adv-jsapi .v-c {color:#8b949e!important;}#upl-adv-jsapi .v-k {color:#ff7b72!important;}#upl-adv-jsapi .v-fn {color:#d2a8ff!important;}#upl-adv-jsapi .v-s {color:#a5d6ff!important;}#upl-adv-jsapi .v-w {color:#e6edf3!important;}#upl-adv-jsapi .v-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi .adv-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi .adv-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi details.adv-acc summary {padding:16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-adv-jsapi .adv-acc-body {padding:0 16px 20px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-adv-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-advanced\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"adv-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"adv-eyebrow\"><span class=\"adv-dot\"><\/span><span>Advanced<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"adv-h2\">Replies, Threads &#038; Tracking<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"adv-sub\">Go beyond basic sends: thread replies, custom headers for idempotency, open\/click tracking via webhooks, and <a href=\"\/send-email-on-behalf-of-user-api\/\" target=\"_self\">sending email on behalf of a user<\/a>.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <details class=\"adv-acc\" open><!-- [et_pb_line_break_holder] -->      <summary><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-num\">1<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-title\">Replying to a thread<\/div><!-- [et_pb_line_break_holder] -->        <svg class=\"adv-acc-chevron\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <\/summary><!-- [et_pb_line_break_holder] -->      <div class=\"adv-acc-body\"><!-- [et_pb_line_break_holder] -->        <pee class=\"adv-acc-desc\">Pass the provider message ID (returned in the original send response or from listing emails) as <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">reply_to<\/code>. Unipile injects the correct <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">In-Reply-To<\/code> and <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">References<\/code> headers so the reply threads correctly in Gmail, Outlook, and IMAP clients.<\/pee><!-- [et_pb_line_break_holder] -->        <div class=\"adv-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"adv-editor-bar\"><span class=\"v-dot-r\"><\/span><span class=\"v-dot-y\"><\/span><span class=\"v-dot-g\"><\/span><span class=\"adv-fname\">reply-thread.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"adv-pre\"><code><span class=\"v-k\">await<\/span><span class=\"v-w\"> client.email.<\/span><span class=\"v-fn\">send<\/span><span class=\"v-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"v-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  to:         [{ display_name: <\/span><span class=\"v-s\">'Alice'<\/span><span class=\"v-w\">, identifier: <\/span><span class=\"v-s\">'alice@acme.com'<\/span><span class=\"v-w\"> }],<!-- [et_pb_line_break_holder] -->  subject:    <\/span><span class=\"v-s\">'Re: Your question'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  body:       <\/span><span class=\"v-s\">'<pee>Thanks for reaching out! Here is the answer...<\/pee>'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/span><span class=\"v-c\">\/\/ Provider message ID from the original email<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] -->  reply_to:   <\/span><span class=\"v-s\">'msg_xxxxxxxxxxxxxxxx'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/details><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <details class=\"adv-acc\"><!-- [et_pb_line_break_holder] -->      <summary><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-num\">2<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-title\">Custom headers &#038; idempotency<\/div><!-- [et_pb_line_break_holder] -->        <svg class=\"adv-acc-chevron\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <\/summary><!-- [et_pb_line_break_holder] -->      <div class=\"adv-acc-body\"><!-- [et_pb_line_break_holder] -->        <pee class=\"adv-acc-desc\">Use <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">custom_headers<\/code> to add any <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">X-<\/code> header. A common pattern is <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">X-Idempotency-Key<\/code> to prevent duplicate sends when retrying after a network timeout.<\/pee><!-- [et_pb_line_break_holder] -->        <div class=\"adv-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"adv-editor-bar\"><span class=\"v-dot-r\"><\/span><span class=\"v-dot-y\"><\/span><span class=\"v-dot-g\"><\/span><span class=\"adv-fname\">custom-headers.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"adv-pre\"><code><span class=\"v-k\">import<\/span><span class=\"v-w\"> { randomUUID } <\/span><span class=\"v-k\">from<\/span><span class=\"v-w\"> <\/span><span class=\"v-s\">'node:crypto'<\/span><span class=\"v-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"v-k\">await<\/span><span class=\"v-w\"> client.email.<\/span><span class=\"v-fn\">send<\/span><span class=\"v-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"v-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  to:         [{ display_name: <\/span><span class=\"v-s\">'Bob'<\/span><span class=\"v-w\">, identifier: <\/span><span class=\"v-s\">'bob@example.com'<\/span><span class=\"v-w\"> }],<!-- [et_pb_line_break_holder] -->  subject:    <\/span><span class=\"v-s\">'Order confirmation #9981'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  body:       <\/span><span class=\"v-s\">'<pee>Your order is confirmed.<\/pee>'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  custom_headers: [<!-- [et_pb_line_break_holder] -->    { name: <\/span><span class=\"v-s\">'X-Idempotency-Key'<\/span><span class=\"v-w\">, value: <\/span><span class=\"v-fn\">randomUUID<\/span><span class=\"v-w\">() },<!-- [et_pb_line_break_holder] -->    { name: <\/span><span class=\"v-s\">'X-Order-ID'<\/span><span class=\"v-w\">,       value: <\/span><span class=\"v-s\">'9981'<\/span><span class=\"v-w\"> },<!-- [et_pb_line_break_holder] -->  ],<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/details><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <details class=\"adv-acc\"><!-- [et_pb_line_break_holder] -->      <summary><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-num\">3<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-title\">Open &#038; click tracking via webhooks<\/div><!-- [et_pb_line_break_holder] -->        <svg class=\"adv-acc-chevron\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <\/summary><!-- [et_pb_line_break_holder] -->      <div class=\"adv-acc-body\"><!-- [et_pb_line_break_holder] -->        <pee class=\"adv-acc-desc\">Enable tracking in <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">tracking_options<\/code>. Unipile fires a webhook event (<code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">email.opened<\/code> \/ <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">email.link_clicked<\/code>) to your registered webhook URL with the <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">label<\/code> you set here so you can correlate events to your internal IDs.<\/pee><!-- [et_pb_line_break_holder] -->        <div class=\"adv-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"adv-editor-bar\"><span class=\"v-dot-r\"><\/span><span class=\"v-dot-y\"><\/span><span class=\"v-dot-g\"><\/span><span class=\"adv-fname\">tracking.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"adv-pre\"><code><span class=\"v-k\">await<\/span><span class=\"v-w\"> client.email.<\/span><span class=\"v-fn\">send<\/span><span class=\"v-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"v-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  to:         [{ display_name: <\/span><span class=\"v-s\">'Lead'<\/span><span class=\"v-w\">, identifier: <\/span><span class=\"v-s\">'lead@prospect.com'<\/span><span class=\"v-w\"> }],<!-- [et_pb_line_break_holder] -->  subject:    <\/span><span class=\"v-s\">'Following up on your trial'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  body:       <\/span><span class=\"v-s\">'<pee>Hi, wanted to check in...<\/pee>'<\/span><span class=\"v-w\">,<!-- [et_pb_line_break_holder] -->  tracking_options: {<!-- [et_pb_line_break_holder] -->    opens:  <\/span><span class=\"v-n\">true<\/span><span class=\"v-w\">,   <\/span><span class=\"v-c\">\/\/ fires email.opened webhook<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] -->    links:  <\/span><span class=\"v-n\">true<\/span><span class=\"v-w\">,   <\/span><span class=\"v-c\">\/\/ fires email.link_clicked webhook<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] -->    label:  <\/span><span class=\"v-s\">'crm_lead_12345'<\/span><span class=\"v-w\">, <\/span><span class=\"v-c\">\/\/ your internal correlation ID<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/details><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <details class=\"adv-acc\"><!-- [et_pb_line_break_holder] -->      <summary><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-num\">4<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"adv-acc-title\">Sending on behalf of another user<\/div><!-- [et_pb_line_break_holder] -->        <svg class=\"adv-acc-chevron\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <\/summary><!-- [et_pb_line_break_holder] -->      <div class=\"adv-acc-body\"><!-- [et_pb_line_break_holder] -->        <pee class=\"adv-acc-desc\">When building multi-tenant SaaS apps, each end-user links their own email account. Store the <code style=\"font-family:'Courier New',monospace;background:#f4f5f7;padding:2px 5px;border-radius:3px;font-size:13px;color:#0f2736;\">account_id<\/code> per user in your database and pass it at send time. See the full guide on <a href=\"\/send-email-on-behalf-of-user-api\/\" target=\"_self\">how to send email on behalf of a user<\/a>.<\/pee><!-- [et_pb_line_break_holder] -->        <div class=\"adv-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"adv-editor-bar\"><span class=\"v-dot-r\"><\/span><span class=\"v-dot-y\"><\/span><span class=\"v-dot-g\"><\/span><span class=\"adv-fname\">on-behalf.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"adv-pre\"><code><span class=\"v-c\">\/\/ Each user has their own linked account_id stored in your DB<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"v-k\">async function<\/span><span class=\"v-w\"> <\/span><span class=\"v-fn\">sendAsUser<\/span><span class=\"v-w\">(userId, to, subject, body) {<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"v-k\">const<\/span><span class=\"v-w\"> user <\/span><span class=\"v-fn\">= await<\/span><span class=\"v-w\"> db.<\/span><span class=\"v-fn\">getUser<\/span><span class=\"v-w\">(userId);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/span><span class=\"v-k\">return<\/span><span class=\"v-w\"> client.email.<\/span><span class=\"v-fn\">send<\/span><span class=\"v-w\">({<!-- [et_pb_line_break_holder] -->    account_id: user.unipile_account_id, <\/span><span class=\"v-c\">\/\/ per-user<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] -->    to, subject, body,<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"v-c\">\/\/ Email is sent from alice's Gmail, not your server address<\/span><span class=\"v-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"v-k\">await<\/span><span class=\"v-w\"> <\/span><span class=\"v-fn\">sendAsUser<\/span><span class=\"v-w\">(<\/span><span class=\"v-s\">'user_alice'<\/span><span class=\"v-w\">, recipients, subject, body);<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/details><!-- [et_pb_line_break_holder] -->  <pee class=\"adv-sub\" style=\"margin-top:16px!important;font-size:14px!important;color:#64748b!important;\">Working in Python instead? See our <a href=\"https:\/\/www.unipile.com\/send-email-api-python\/\">Python implementation<\/a> guide.<\/pee><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-err-jsapi, #upl-err-jsapi *, #upl-err-jsapi *::before, #upl-err-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi { padding:72px 20px!important;!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(221,223,76,0.18)!important;color:#8a8c2e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-dot { width:7px!important;height:7px!important;background:#DDDF4C!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-grid { display:grid!important;grid-template-columns:1fr 1fr!important;gap:24px!important;margin-bottom:40px!important; }<!-- [et_pb_line_break_holder] -->\/* HTTP code cards *\/<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-card { background:#ffffff!important;border-radius:14px!important;padding:20px 24px!important;display:flex!important;gap:16px!important;align-items:flex-start!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-badge { min-width:52px!important;height:36px!important;border-radius:8px!important;display:flex!important;align-items:center!important;justify-content:center!important;font-family:'Courier New',monospace!important;font-size:13px!important;font-weight:700!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-2xx { background:rgba(59,185,139,0.15)!important;color:#2aaa7e!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-4xx { background:rgba(234,67,53,0.12)!important;color:#c53030!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-5xx { background:rgba(251,188,4,0.15)!important;color:#8a6400!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-429 { background:rgba(66,133,244,0.12)!important;color:#2563eb!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-title { font-size:14px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-code-desc { font-size:13px!important;color:#718096!important;line-height:1.6!important; }<!-- [et_pb_line_break_holder] -->\/* editors *\/<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-editor { border-radius:14px!important;overflow:hidden!important;background:#0d1117!important;margin-bottom:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-editor-bar { background:#161b22!important;padding:11px 18px!important;display:flex!important;align-items:center!important;gap:8px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .e-dot-r {width:11px!important;height:11px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .e-dot-y {width:11px!important;height:11px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .e-dot-g {width:11px!important;height:11px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-fname { color:#8b949e!important;font-size:12px!important;margin-left:6px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-pre { padding:20px 24px!important;font-size:13px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .r-c {color:#8b949e!important;}#upl-err-jsapi .r-k {color:#ff7b72!important;}#upl-err-jsapi .r-fn {color:#d2a8ff!important;}#upl-err-jsapi .r-s {color:#a5d6ff!important;}#upl-err-jsapi .r-w {color:#e6edf3!important;}#upl-err-jsapi .r-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->#upl-err-jsapi .err-section-title { font-family:'Poppins',sans-serif!important;font-size:20px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:16px!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-err-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-err-jsapi .err-grid {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-err-jsapi .err-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-err-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-err-jsapi .err-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-err-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-errors\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"err-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"err-eyebrow\"><span class=\"err-dot\"><\/span><span>Production-Ready<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"err-h2\">Error Handling &#038; Retries<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"err-sub\">Network failures and rate limits are inevitable at scale. Here is a production-grade async\/await pattern for your send email API JavaScript implementation &#8211; with exponential backoff and structured logging using Winston or Pino.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"err-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-2xx\"><span>202<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Accepted<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">Email queued successfully. The <code style=\"font-family:'Courier New',monospace;font-size:12px;\">tracking_id<\/code> is populated. No retry needed.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-429\"><span>429<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Rate Limited<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">Too many requests. Respect the <code style=\"font-family:'Courier New',monospace;font-size:12px;\">Retry-After<\/code> header. Use exponential backoff.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-4xx\"><span>401<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Unauthorized<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">Invalid or expired token. Check <code style=\"font-family:'Courier New',monospace;font-size:12px;\">UNIPILE_TOKEN<\/code> env var. Do not retry &#8211; fix credentials.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-4xx\"><span>422<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Validation Error<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">Missing required field or malformed recipient. Check the error body &#8211; it specifies which field failed.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-5xx\"><span>503<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Service Unavailable<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">Transient server error. Safe to retry with backoff. Check status.unipile.com for incidents.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-code-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"err-code-badge err-code-4xx\"><span>404<\/span><\/div><!-- [et_pb_line_break_holder] -->        <div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-title\">Account Not Found<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"err-code-desc\">The <code style=\"font-family:'Courier New',monospace;font-size:12px;\">account_id<\/code> does not exist or was revoked. Re-link the account.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"err-section-title\">Exponential backoff with async\/await<\/div><!-- [et_pb_line_break_holder] -->    <div class=\"err-editor\"><!-- [et_pb_line_break_holder] -->      <div class=\"err-editor-bar\"><span class=\"e-dot-r\"><\/span><span class=\"e-dot-y\"><\/span><span class=\"e-dot-g\"><\/span><span class=\"err-fname\">send-with-retry.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->      <div class=\"err-pre\"><code><span class=\"r-k\">import<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">{ UnipileClient }<\/span><span class=\"r-w\"> <\/span><span class=\"r-k\">from<\/span><span class=\"r-w\"> <\/span><span class=\"r-s\">'unipile-node-sdk'<\/span><span class=\"r-w\">;<!-- [et_pb_line_break_holder] --><\/span><span class=\"r-k\">import<\/span><span class=\"r-w\"> logger <\/span><span class=\"r-k\">from<\/span><span class=\"r-w\"> <\/span><span class=\"r-s\">'.\/logger.mjs'<\/span><span class=\"r-w\">; <\/span><span class=\"r-c\">\/\/ Winston or Pino instance<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"r-k\">const<\/span><span class=\"r-w\"> client <\/span><span class=\"r-fn\">= new<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">UnipileClient<\/span><span class=\"r-w\">(process.env.<\/span><span class=\"r-n\">UNIPILE_DSN<\/span><span class=\"r-w\">, process.env.<\/span><span class=\"r-n\">UNIPILE_TOKEN<\/span><span class=\"r-w\">);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"r-k\">async function<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">sendWithRetry<\/span><span class=\"r-w\">(payload, maxAttempts <\/span><span class=\"r-fn\">=<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">4<\/span><span class=\"r-w\">) {<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"r-k\">let<\/span><span class=\"r-w\"> attempt <\/span><span class=\"r-fn\">=<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">0<\/span><span class=\"r-w\">;<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"r-k\">while<\/span><span class=\"r-w\"> (attempt <\/span><span class=\"r-fn\"><<\/span><span class=\"r-w\"> maxAttempts) {<!-- [et_pb_line_break_holder] -->    <\/span><span class=\"r-k\">try<\/span><span class=\"r-w\"> {<!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">const<\/span><span class=\"r-w\"> result <\/span><span class=\"r-fn\">= await<\/span><span class=\"r-w\"> client.email.<\/span><span class=\"r-fn\">send<\/span><span class=\"r-w\">(payload);<!-- [et_pb_line_break_holder] -->      logger.<\/span><span class=\"r-fn\">info<\/span><span class=\"r-w\">({ tracking_id: result.tracking_id }, <\/span><span class=\"r-s\">'Email sent'<\/span><span class=\"r-w\">);<!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">return<\/span><span class=\"r-w\"> result;<!-- [et_pb_line_break_holder] -->    } <\/span><span class=\"r-k\">catch<\/span><span class=\"r-w\"> (err) {<!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">const<\/span><span class=\"r-w\"> status <\/span><span class=\"r-fn\">=<\/span><span class=\"r-w\"> err?.status <\/span><span class=\"r-fn\">??<\/span><span class=\"r-w\"> err?.statusCode;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-c\">\/\/ Do not retry on client errors (4xx except 429)<\/span><span class=\"r-w\"><!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">if<\/span><span class=\"r-w\"> (status <\/span><span class=\"r-fn\">>=<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">400<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">&&<\/span><span class=\"r-w\"> status <\/span><span class=\"r-fn\">!==<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">429<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">&&<\/span><span class=\"r-w\"> status <\/span><span class=\"r-fn\"><<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">500<\/span><span class=\"r-w\">) {<!-- [et_pb_line_break_holder] -->        logger.<\/span><span class=\"r-fn\">error<\/span><span class=\"r-w\">({ status, err }, <\/span><span class=\"r-s\">'Non-retryable error'<\/span><span class=\"r-w\">);<!-- [et_pb_line_break_holder] -->        <\/span><span class=\"r-k\">throw<\/span><span class=\"r-w\"> err;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      attempt<\/span><span class=\"r-fn\">++<\/span><span class=\"r-w\">;<!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">if<\/span><span class=\"r-w\"> (attempt <\/span><span class=\"r-fn\">>=<\/span><span class=\"r-w\"> maxAttempts) <\/span><span class=\"r-k\">throw<\/span><span class=\"r-w\"> err;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-c\">\/\/ Exponential backoff: 1s, 2s, 4s, 8s...<\/span><span class=\"r-w\"><!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">const<\/span><span class=\"r-w\"> delay <\/span><span class=\"r-fn\">=<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">1000<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">*<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">2<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">**<\/span><span class=\"r-w\"> (attempt <\/span><span class=\"r-fn\">-<\/span><span class=\"r-w\"> <\/span><span class=\"r-n\">1<\/span><span class=\"r-w\">);<!-- [et_pb_line_break_holder] -->      logger.<\/span><span class=\"r-fn\">warn<\/span><span class=\"r-w\">({ attempt, delay, status }, <\/span><span class=\"r-s\">'Retrying...'<\/span><span class=\"r-w\">);<!-- [et_pb_line_break_holder] -->      <\/span><span class=\"r-k\">await new<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">Promise<\/span><span class=\"r-w\">(r <\/span><span class=\"r-fn\">=><\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">setTimeout<\/span><span class=\"r-w\">(r, delay));<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"r-c\">\/\/ Usage<\/span><span class=\"r-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"r-k\">await<\/span><span class=\"r-w\"> <\/span><span class=\"r-fn\">sendWithRetry<\/span><span class=\"r-w\">({<!-- [et_pb_line_break_holder] -->  account_id: process.env.<\/span><span class=\"r-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"r-w\">,<!-- [et_pb_line_break_holder] -->  to: [{ display_name: <\/span><span class=\"r-s\">'User'<\/span><span class=\"r-w\">, identifier: <\/span><span class=\"r-s\">'user@example.com'<\/span><span class=\"r-w\"> }],<!-- [et_pb_line_break_holder] -->  subject: <\/span><span class=\"r-s\">'Your report is ready'<\/span><span class=\"r-w\">,<!-- [et_pb_line_break_holder] -->  body:    <\/span><span class=\"r-s\">'<pee>Click to download.<\/pee>'<\/span><span class=\"r-w\">,<!-- [et_pb_line_break_holder] -->});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-sec-jsapi, #upl-sec-jsapi *, #upl-sec-jsapi *::before, #upl-sec-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi { padding:72px 20px!important;background:#f4f5f7!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-dot { width:7px!important;height:7px!important;background:#3BB98B!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-sub a { color:#2aaa7e!important;font-weight:600!important;text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-grid { display:grid!important;grid-template-columns:repeat(3,1fr)!important;gap:20px!important;margin-bottom:36px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:16px!important;padding:24px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card-icon { width:40px!important;height:40px!important;border-radius:10px!important;background:rgba(59,185,139,0.12)!important;display:flex!important;align-items:center!important;justify-content:center!important;margin-bottom:14px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card-icon svg { width:20px!important;height:20px!important;stroke:#3BB98B!important;fill:none!important;stroke-width:2!important;stroke-linecap:round!important;stroke-linejoin:round!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card-title { font-size:15px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:8px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card-body { font-size:13px!important;color:#718096!important;line-height:1.65!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-card-body code { font-family:'Courier New',monospace!important;background:#f4f5f7!important;padding:2px 5px!important;border-radius:3px!important;font-size:12px!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->\/* do\/dont block *\/<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-dodonts { display:grid!important;grid-template-columns:1fr 1fr!important;gap:20px!important;margin-bottom:32px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:14px!important;overflow:hidden!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-header { padding:14px 20px!important;border-bottom:1px solid #f0f1f3!important;display:flex!important;align-items:center!important;gap:10px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-badge-good { background:rgba(59,185,139,0.12)!important;color:#2aaa7e!important;font-size:11px!important;font-weight:700!important;padding:3px 8px!important;border-radius:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-badge-bad { background:rgba(234,67,53,0.12)!important;color:#c53030!important;font-size:11px!important;font-weight:700!important;padding:3px 8px!important;border-radius:4px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-title { font-size:14px!important;font-weight:700!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-body { padding:16px 20px!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-do-pre { font-family:'Courier New',monospace!important;font-size:12px!important;line-height:1.8!important;color:#e6edf3!important;background:#0d1117!important;padding:14px 16px!important;border-radius:8px!important;overflow-x:auto!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-kw-good { color:#a5d6ff!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-kw-bad { color:#ff7b72!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-kw-comment { color:#8b949e!important; }<!-- [et_pb_line_break_holder] -->\/* link to security guide *\/<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-cta-link { display:inline-flex!important;align-items:center!important;gap:8px!important;background:rgba(59,185,139,0.10)!important;color:#2aaa7e!important;padding:12px 20px!important;border-radius:10px!important;font-size:14px!important;font-weight:600!important;transition:all 0.2s!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-cta-link:hover { background:rgba(59,185,139,0.18)!important; }<!-- [et_pb_line_break_holder] -->#upl-sec-jsapi .sec-cta-link svg { width:16px!important;height:16px!important;stroke:currentColor!important;fill:none!important;stroke-width:2.5!important;stroke-linecap:round!important;stroke-linejoin:round!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi .sec-grid {grid-template-columns:1fr 1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi .sec-dodonts {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi .sec-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi .sec-grid {grid-template-columns:1fr!important;}<!-- [et_pb_line_break_holder] -->  #upl-sec-jsapi .sec-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-sec-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-security\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"sec-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"sec-eyebrow\"><span class=\"sec-dot\"><\/span><span>Security<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"sec-h2\">Security Best Practices in Node.js<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"sec-sub\">Your <code style=\"font-family:'Courier New',monospace;background:#e8ecf0;padding:2px 6px;border-radius:4px;font-size:15px;color:#0f2736;\">UNIPILE_TOKEN<\/code> grants full API access. Never expose it client-side. See the full <a href=\"\/secure-email-api\/\" target=\"_self\">email API security guide<\/a> for advanced topics including DKIM, SPF, and OAuth token rotation.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"sec-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">Never expose keys client-side<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">Your <code>UNIPILE_TOKEN<\/code> must stay on the server. Any browser-side JavaScript &#8211; including Next.js client components, React frontend, or Vite &#8211; must NOT import the token directly.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">Use a backend proxy route<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">In Next.js, create an API route (<code>\/api\/send-email<\/code>). In Express, a POST endpoint. Authenticate your own users first, then call Unipile server-side with the token from env.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"\/><circle cx=\"12\" cy=\"7\" r=\"4\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">OAuth refresh tokens<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">Unipile manages Gmail and Outlook OAuth token refresh automatically. Your stored <code>account_id<\/code> remains valid. You do not need to handle access token expiry yourself.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">DKIM and SPF (sender reputation)<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">Emails sent through linked Gmail\/Outlook accounts inherit those providers&#8217; DKIM signatures. For IMAP\/SMTP accounts, configure DKIM on your mail server before linking.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">Validate recipient input<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">If recipients come from user input, validate email format server-side before calling the API. The API will reject malformed addresses with a 422, but validation before the call gives cleaner UX errors.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-title\">Scope API tokens by environment<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-card-body\">Use separate Unipile projects (and tokens) for dev, staging, and production. This prevents test emails from going to real users and limits blast radius if a key is leaked.<\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"sec-dodonts\"><!-- [et_pb_line_break_holder] -->      <div class=\"sec-do\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-do-header\"><!-- [et_pb_line_break_holder] -->          <span class=\"sec-do-badge-bad\">WRONG<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"sec-do-title\">Token in frontend code<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-do-body\"><!-- [et_pb_line_break_holder] -->          <code class=\"sec-do-pre\"><span class=\"sec-kw-comment\">\/\/ client.js - NEVER do this<\/span><!-- [et_pb_line_break_holder] --><span class=\"sec-kw-bad\">const<\/span> client = new UnipileClient(<!-- [et_pb_line_break_holder] -->  <span class=\"sec-kw-bad\">'https:\/\/api4.unipile.com:13444'<\/span>,<!-- [et_pb_line_break_holder] -->  <span class=\"sec-kw-bad\">'sk_live_xxxxxxxxxx'<\/span> <span class=\"sec-kw-comment\">\/\/ exposed!<\/span><!-- [et_pb_line_break_holder] -->);<\/code><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"sec-do\"><!-- [et_pb_line_break_holder] -->        <div class=\"sec-do-header\"><!-- [et_pb_line_break_holder] -->          <span class=\"sec-do-badge-good\">CORRECT<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"sec-do-title\">Backend proxy route (Next.js)<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"sec-do-body\"><!-- [et_pb_line_break_holder] -->          <code class=\"sec-do-pre\"><span class=\"sec-kw-comment\">\/\/ app\/api\/send-email\/route.js<\/span><!-- [et_pb_line_break_holder] --><span class=\"sec-kw-good\">export async function<\/span> POST(req) {<!-- [et_pb_line_break_holder] -->  <span class=\"sec-kw-comment\">\/\/ auth check first<\/span><!-- [et_pb_line_break_holder] -->  const session = <span class=\"sec-kw-good\">await<\/span> getServerSession();<!-- [et_pb_line_break_holder] -->  if (!session) return new Response(null,{status:401});<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  const client = new UnipileClient(<!-- [et_pb_line_break_holder] -->    process.env.<span class=\"sec-kw-good\">UNIPILE_DSN<\/span>,    <span class=\"sec-kw-comment\">\/\/ server-only<\/span><!-- [et_pb_line_break_holder] -->    process.env.<span class=\"sec-kw-good\">UNIPILE_TOKEN<\/span>  <span class=\"sec-kw-comment\">\/\/ server-only<\/span><!-- [et_pb_line_break_holder] -->  );<!-- [et_pb_line_break_holder] -->  <span class=\"sec-kw-good\">await<\/span> client.email.send({...});<!-- [et_pb_line_break_holder] -->}<\/code><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <a href=\"\/secure-email-api\/\" target=\"_self\" class=\"sec-cta-link\" data-upl-link=\"\/secure-email-api\/\"><!-- [et_pb_line_break_holder] -->      <svg viewBox=\"0 0 24 24\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <span>Read the complete email API security guide<\/span><!-- [et_pb_line_break_holder] -->      <svg viewBox=\"0 0 24 24\"><polyline points=\"9 18 15 12 9 6\"\/><\/svg><!-- [et_pb_line_break_holder] -->    <\/a><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->document.querySelectorAll('#upl-sec-jsapi [data-upl-link]').forEach(function(el){<!-- [et_pb_line_break_holder] -->  el.addEventListener('click',function(e){<!-- [et_pb_line_break_holder] -->    e.preventDefault();<!-- [et_pb_line_break_holder] -->    var url=el.getAttribute('data-upl-link');<!-- [et_pb_line_break_holder] -->    if(url.startsWith('http')){window.open(url,'_blank');}else{window.location.href=url;}<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] -->});<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; sticky_enabled=&#8221;0&#8243;]<style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->#upl-pit-jsapi, #upl-pit-jsapi *, #upl-pit-jsapi *::before, #upl-pit-jsapi *::after {<!-- [et_pb_line_break_holder] -->  margin:0!important;padding:0!important;box-sizing:border-box!important;border:none!important;<!-- [et_pb_line_break_holder] -->  outline:none!important;font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;<!-- [et_pb_line_break_holder] -->  line-height:normal!important;letter-spacing:normal!important;text-transform:none!important;<!-- [et_pb_line_break_holder] -->  text-decoration:none!important;list-style:none!important;background:transparent!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi { padding:72px 20px!important;!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-inner { max-width:1100px!important;margin:0 auto!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-eyebrow {<!-- [et_pb_line_break_holder] -->  display:inline-flex!important;align-items:center!important;gap:8px!important;<!-- [et_pb_line_break_holder] -->  background:rgba(251,188,4,0.15)!important;color:#8a6400!important;<!-- [et_pb_line_break_holder] -->  padding:6px 14px!important;border-radius:20px!important;<!-- [et_pb_line_break_holder] -->  font-size:12px!important;font-weight:700!important;<!-- [et_pb_line_break_holder] -->  text-transform:uppercase!important;letter-spacing:0.5px!important;<!-- [et_pb_line_break_holder] -->  margin-bottom:16px!important;width:fit-content!important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-dot { width:7px!important;height:7px!important;background:#FBBC04!important;border-radius:50%!important;flex-shrink:0!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-h2 { font-family:'Poppins',sans-serif!important;font-size:35px!important;font-weight:700!important;color:#0f2736!important;line-height:1.2!important;margin-bottom:14px!important;max-width:820px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-sub { font-size:17px!important;line-height:1.75!important;color:#383838!important;margin-bottom:40px!important;max-width:720px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-list { display:flex!important;flex-direction:column!important;gap:20px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item { background:#ffffff!important;border:1px solid #e5e7eb!important;border-radius:16px!important;overflow:hidden!important;border-left:4px solid #FBBC04!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-header { padding:18px 24px!important;display:flex!important;align-items:flex-start!important;gap:14px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-num { width:28px!important;height:28px!important;min-width:28px!important;border-radius:7px!important;background:rgba(251,188,4,0.15)!important;color:#8a6400!important;display:flex!important;align-items:center!important;justify-content:center!important;font-family:'Poppins',sans-serif!important;font-size:12px!important;font-weight:700!important;margin-top:1px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-content {}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-title { font-size:15px!important;font-weight:700!important;color:#0f2736!important;margin-bottom:6px!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-desc { font-size:14px!important;color:#383838!important;line-height:1.7!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-item-desc code { font-family:'Courier New',monospace!important;background:#f4f5f7!important;padding:2px 5px!important;border-radius:3px!important;font-size:12px!important;color:#0f2736!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-editor { margin:0 24px 20px!important;border-radius:10px!important;overflow:hidden!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-editor-bar { background:#161b22!important;padding:9px 14px!important;display:flex!important;align-items:center!important;gap:6px!important;border-bottom:1px solid rgba(255,255,255,0.06)!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pt-dot-r {width:10px!important;height:10px!important;border-radius:50%!important;background:#ff5f57!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pt-dot-y {width:10px!important;height:10px!important;border-radius:50%!important;background:#febc2e!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pt-dot-g {width:10px!important;height:10px!important;border-radius:50%!important;background:#28c840!important;display:inline-block!important;flex-shrink:0!important;}<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-fname { color:#8b949e!important;font-size:11px!important;margin-left:5px!important;font-family:'Courier New',monospace!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-pre { padding:16px 18px!important;font-size:12px!important;line-height:1.8!important;overflow-x:auto!important;background:#0d1117!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pit-pre code { font-family:'Courier New',monospace!important;white-space:pre!important;display:block!important; }<!-- [et_pb_line_break_holder] -->#upl-pit-jsapi .pt-c {color:#8b949e!important;}#upl-pit-jsapi .pt-k {color:#ff7b72!important;}#upl-pit-jsapi .pt-fn {color:#d2a8ff!important;}#upl-pit-jsapi .pt-s {color:#a5d6ff!important;}#upl-pit-jsapi .pt-w {color:#e6edf3!important;}#upl-pit-jsapi .pt-n {color:#79c0ff!important;}<!-- [et_pb_line_break_holder] -->@media(max-width:900px){<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi {padding:50px 20px!important;}<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi .pit-h2 {font-size:28px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media(max-width:600px){<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi {padding:40px 16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi .pit-h2 {font-size:26px!important;}<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi .pit-item-header {padding:16px!important;}<!-- [et_pb_line_break_holder] -->  #upl-pit-jsapi .pit-editor {margin:0 16px 16px!important;}<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><div id=\"upl-pit-jsapi\"><!-- [et_pb_line_break_holder] -->  <span id=\"anchor-pitfalls\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"pit-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"pit-eyebrow\"><span class=\"pit-dot\"><\/span><span>Common Pitfalls<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"pit-h2\">Common Pitfalls (Node.js-specific)<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"pit-sub\">These are the most frequent mistakes developers make when integrating a send email API in JavaScript for the first time. Each one is easy to avoid once you know the pattern &#8211; and all apply equally to the Node.js send email API context.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"pit-list\"><!-- [et_pb_line_break_holder] -->      <!-- 1 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">1<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Forgetting top-level await (CommonJS vs ESM)<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">Top-level <code>await<\/code> only works in ES modules (<code>.mjs<\/code> or <code>\"type\":\"module\"<\/code>). In CommonJS, wrap your send call in an <code>async<\/code> IIFE or use <code>.then()<\/code>. The SDK works in both &#8211; just pick the right module format.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pit-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-editor-bar\"><span class=\"pt-dot-r\"><\/span><span class=\"pt-dot-y\"><\/span><span class=\"pt-dot-g\"><\/span><span class=\"pit-fname\">cjs-workaround.cjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-pre\"><code><span class=\"pt-c\">\/\/ CommonJS: wrap in async IIFE<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-fn\">(async<\/span><span class=\"pt-w\"> () <\/span><span class=\"pt-fn\">=><\/span><span class=\"pt-w\"> {<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"pt-k\">const<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-fn\">{ UnipileClient }<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-fn\">= await<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-k\">import<\/span><span class=\"pt-w\">(<\/span><span class=\"pt-s\">'unipile-node-sdk'<\/span><span class=\"pt-w\">);<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"pt-k\">const<\/span><span class=\"pt-w\"> client <\/span><span class=\"pt-fn\">= new<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-fn\">UnipileClient<\/span><span class=\"pt-w\">(process.env.<\/span><span class=\"pt-n\">UNIPILE_DSN<\/span><span class=\"pt-w\">, process.env.<\/span><span class=\"pt-n\">UNIPILE_TOKEN<\/span><span class=\"pt-w\">);<!-- [et_pb_line_break_holder] -->  <\/span><span class=\"pt-k\">await<\/span><span class=\"pt-w\"> client.email.<\/span><span class=\"pt-fn\">send<\/span><span class=\"pt-w\">({ <\/span><span class=\"pt-c\">\/* ... *\/<\/span><span class=\"pt-w\"> });<!-- [et_pb_line_break_holder] -->})();<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- 2 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">2<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Using Promise.all for bulk sends without rate-limit awareness<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">Firing 1,000 <code>Promise.all<\/code> sends simultaneously will hit rate limits and cause 429 errors. Use a concurrency limiter like <code>p-limit<\/code> to cap parallel requests.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pit-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-editor-bar\"><span class=\"pt-dot-r\"><\/span><span class=\"pt-dot-y\"><\/span><span class=\"pt-dot-g\"><\/span><span class=\"pit-fname\">bulk-send.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-pre\"><code><span class=\"pt-k\">import<\/span><span class=\"pt-w\"> pLimit <\/span><span class=\"pt-k\">from<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-s\">'p-limit'<\/span><span class=\"pt-w\">;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-k\">const<\/span><span class=\"pt-w\"> limit <\/span><span class=\"pt-fn\">= pLimit<\/span><span class=\"pt-w\">(<\/span><span class=\"pt-n\">5<\/span><span class=\"pt-w\">); <\/span><span class=\"pt-c\">\/\/ max 5 concurrent sends<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-k\">const<\/span><span class=\"pt-w\"> results <\/span><span class=\"pt-fn\">= await<\/span><span class=\"pt-w\"> <\/span><span class=\"pt-fn\">Promise.all<\/span><span class=\"pt-w\">(<!-- [et_pb_line_break_holder] -->  recipients.<\/span><span class=\"pt-fn\">map<\/span><span class=\"pt-w\">(r <\/span><span class=\"pt-fn\">=><\/span><span class=\"pt-w\"> <\/span><span class=\"pt-fn\">limit<\/span><span class=\"pt-w\">(() <\/span><span class=\"pt-fn\">=><\/span><span class=\"pt-w\"> client.email.<\/span><span class=\"pt-fn\">send<\/span><span class=\"pt-w\">({<!-- [et_pb_line_break_holder] -->    account_id: process.env.<\/span><span class=\"pt-n\">EMAIL_ACCOUNT_ID<\/span><span class=\"pt-w\">,<!-- [et_pb_line_break_holder] -->    to: [r], subject, body,<!-- [et_pb_line_break_holder] -->  })))<!-- [et_pb_line_break_holder] -->);<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- 3 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">3<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Wrong Buffer encoding for attachments<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">Always pass a raw <code>Buffer<\/code> object &#8211; not a base64 string, not a UTF-8 string. If you have base64 content (e.g. from a webhook or API response), convert it first: <code>Buffer.from(base64str, 'base64')<\/code>.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pit-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-editor-bar\"><span class=\"pt-dot-r\"><\/span><span class=\"pt-dot-y\"><\/span><span class=\"pt-dot-g\"><\/span><span class=\"pit-fname\">buffer-encoding.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-pre\"><code><span class=\"pt-c\">\/\/ WRONG: passing a string<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] -->attachments: [[<\/span><span class=\"pt-s\">'file.pdf'<\/span><span class=\"pt-w\">, <\/span><span class=\"pt-s\">'JVBERi0xLjQ...'<\/span><span class=\"pt-w\">]]  <\/span><span class=\"pt-c\">\/\/ base64 string - breaks!<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-c\">\/\/ CORRECT: Buffer object<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] -->attachments: [[<\/span><span class=\"pt-s\">'file.pdf'<\/span><span class=\"pt-w\">, <\/span><span class=\"pt-fn\">Buffer<\/span><span class=\"pt-w\">.<\/span><span class=\"pt-fn\">from<\/span><span class=\"pt-w\">(base64str, <\/span><span class=\"pt-s\">'base64'<\/span><span class=\"pt-w\">)]]<!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-c\">\/\/ or from disk:<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] -->attachments: [[<\/span><span class=\"pt-s\">'file.pdf'<\/span><span class=\"pt-w\">, <\/span><span class=\"pt-fn\">await<\/span><span class=\"pt-w\"> fs.<\/span><span class=\"pt-fn\">readFile<\/span><span class=\"pt-w\">(<\/span><span class=\"pt-s\">'.\/file.pdf'<\/span><span class=\"pt-w\">)]]<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- 4 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">4<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Unhandled Promise rejections crashing the process<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">In Node.js, an unhandled rejection in a fire-and-forget <code>send()<\/code> call will crash the process in Node 15+. Always <code>await<\/code> the result or attach a <code>.catch()<\/code> handler.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"pit-editor\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-editor-bar\"><span class=\"pt-dot-r\"><\/span><span class=\"pt-dot-y\"><\/span><span class=\"pt-dot-g\"><\/span><span class=\"pit-fname\">unhandled-rejection.mjs<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-pre\"><code><span class=\"pt-c\">\/\/ WRONG: fire-and-forget - crashes on error in Node 15+<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] -->client.email.<\/span><span class=\"pt-fn\">send<\/span><span class=\"pt-w\">(payload);  <\/span><span class=\"pt-c\">\/\/ no await, no .catch()<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-c\">\/\/ CORRECT: always handle the promise<\/span><span class=\"pt-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-k\">await<\/span><span class=\"pt-w\"> client.email.<\/span><span class=\"pt-fn\">send<\/span><span class=\"pt-w\">(payload)            <\/span><span class=\"pt-c\">\/\/ option 1: await<!-- [et_pb_line_break_holder] --><\/span><span class=\"pt-w\">  .<\/span><span class=\"pt-fn\">catch<\/span><span class=\"pt-w\">(err <\/span><span class=\"pt-fn\">=><\/span><span class=\"pt-w\"> logger.<\/span><span class=\"pt-fn\">error<\/span><span class=\"pt-w\">(err));   <\/span><span class=\"pt-c\">\/\/ option 2: .catch()<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- 5 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">5<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Using this API directly in browser JavaScript<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">The Unipile SDK and your <code>UNIPILE_TOKEN<\/code> are for server-side Node.js only. Browser fetch to the API directly would expose your token. Use a backend route (Next.js API route, Express endpoint, Netlify\/Vercel function) as a proxy.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- 6 --><!-- [et_pb_line_break_holder] -->      <div class=\"pit-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"pit-item-header\"><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-num\">6<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"pit-item-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-title\">Sending without a linked account (missing account_id)<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"pit-item-desc\">You cannot send from a generic address &#8211; every send must reference a valid <code>account_id<\/code> from a previously linked Gmail, Outlook, or IMAP account. The API returns 404 if the account_id is missing or was unlinked.<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; custom_padding=&#8221;0px|0px|0px|0px|false|false&#8221; da_disable_devices=&#8221;off|off|off&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221; da_is_popup=&#8221;off&#8221; da_exit_intent=&#8221;off&#8221; da_has_close=&#8221;on&#8221; da_alt_close=&#8221;off&#8221; da_dark_close=&#8221;off&#8221; da_not_modal=&#8221;on&#8221; da_is_singular=&#8221;off&#8221; da_with_loader=&#8221;off&#8221; da_has_shadow=&#8221;on&#8221;][et_pb_row _builder_version=&#8221;4.27.3&#8243; background_color=&#8221;transparent&#8221; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.3&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<div id=\"upl-faq-jsapi\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-faq-jsapi,<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi *,<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi *::before,<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi *::after {<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important; padding: 80px 20px !important; max-width: 900px !important; margin: 0 auto !important; background: #f4f5f7 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-header { text-align: center !important; margin-bottom: 60px !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-title { font-family: 'Poppins', sans-serif !important; font-size: clamp(32px, 5vw, 38px) !important; font-weight: 700 !important; color: #0f2736 !important; margin: 0 0 16px !important; line-height: 1.2 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-subtitle { font-size: 17px !important; color: #383838 !important; max-width: 700px !important; margin: 0 auto !important; line-height: 1.6 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-list { display: flex !important; flex-direction: column !important; gap: 12px !important; margin: 0 !important; padding: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item { background: #ffffff !important; border: 1px solid #e5e7eb !important; border-radius: 16px !important; overflow: hidden !important; transition: all 0.3s ease !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item:hover { border-color: #3BB98B !important; box-shadow: 0 4px 20px rgba(59,185,139,0.08) !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item.active { border-color: #3BB98B !important; box-shadow: 0 8px 30px rgba(59,185,139,0.12) !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-question { width: 100% !important; display: flex !important; align-items: flex-start !important; justify-content: space-between !important; gap: 20px !important; padding: 24px 28px !important; background: transparent !important; border: none !important; cursor: pointer !important; text-align: left !important; transition: all 0.2s ease !important; margin: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-question-content { display: flex !important; align-items: flex-start !important; gap: 16px !important; flex: 1 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-number { flex-shrink: 0 !important; padding: 6px 12px !important; background: rgba(59,185,139,0.12) !important; color: #3BB98B !important; border-radius: 20px !important; display: flex !important; align-items: center !important; justify-content: center !important; font-size: 0.8rem !important; font-weight: 600 !important; transition: all 0.3s ease !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item.active .upl-faq-number { background: rgba(59,185,139,0.2) !important; color: #2a9d6e !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-question-text { font-family: 'Poppins', sans-serif !important; font-size: 1.1rem !important; font-weight: 600 !important; color: #0f2736 !important; line-height: 1.4 !important; padding-top: 4px !important; margin: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-icon { flex-shrink: 0 !important; width: 36px !important; height: 36px !important; background: #f4f5f7 !important; border-radius: 50% !important; display: flex !important; align-items: center !important; justify-content: center !important; transition: all 0.3s ease !important; margin-top: 2px !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-icon svg { width: 18px !important; height: 18px !important; color: #64748b !important; transition: all 0.3s ease !important; display: block !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item:hover .upl-faq-icon { background: rgba(59,185,139,0.1) !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item:hover .upl-faq-icon svg { color: #3BB98B !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item.active .upl-faq-icon { background: #3BB98B !important; transform: rotate(45deg) !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item.active .upl-faq-icon svg { color: #ffffff !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer { max-height: 0 !important; overflow: hidden !important; transition: max-height 0.4s ease !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-item.active .upl-faq-answer { max-height: 800px !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content { padding: 0 28px 28px 76px !important; color: #475569 !important; font-size: 1rem !important; line-height: 1.7 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content p { margin: 0 0 12px !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content p:last-child { margin-bottom: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content code { font-family: monospace !important; font-size: 0.875rem !important; background: rgba(0,0,0,0.06) !important; padding: 1px 6px !important; border-radius: 3px !important; color: #0f2736 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content strong { font-weight: 700 !important; color: #0f2736 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content .faq-mini-code { background: #0d1117 !important; border-radius: 10px !important; padding: 14px 18px !important; margin-top: 12px !important; overflow-x: auto !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-answer-content .faq-mini-code code { font-family: 'Courier New', monospace !important; font-size: 12.5px !important; line-height: 1.8 !important; white-space: pre !important; display: block !important; background: transparent !important; padding: 0 !important; border-radius: 0 !important; color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .fq-c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .fq-k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .fq-fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .fq-s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .fq-w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta { margin-top: 50px !important; display: flex !important; align-items: center !important; justify-content: space-between !important; gap: 20px !important; padding: 20px 28px !important; background: #ffffff !important; border: 1px solid #e5e7eb !important; border-radius: 12px !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta-text { color: #475569 !important; font-size: 1rem !important; margin: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta-button { display: inline-flex !important; align-items: center !important; gap: 10px !important; background: #DDDF4C !important; color: #0F2836 !important; padding: 13px 20px !important; border-radius: 8px !important; text-decoration: none !important; font-weight: 700 !important; font-size: 1rem !important; border: none !important; cursor: pointer !important; transition: all 0.3s ease !important; white-space: nowrap !important; flex-shrink: 0 !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta-button:hover { transform: translateY(-2px) !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta-button svg { width: 18px !important; height: 18px !important; display: block !important; transition: transform 0.3s ease !important; }<!-- [et_pb_line_break_holder] -->#upl-faq-jsapi .upl-faq-cta-button:hover svg { transform: translateX(4px) !important; }<!-- [et_pb_line_break_holder] -->@media (max-width: 768px) {<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi { padding: 60px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-header { margin-bottom: 40px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-question { padding: 20px !important; gap: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-question-content { gap: 12px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-question-text { font-size: 1rem !important; padding-top: 2px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-icon { width: 32px !important; height: 32px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-icon svg { width: 16px !important; height: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-answer-content { padding: 0 20px 20px 60px !important; font-size: 0.95rem !important; }<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-cta { padding: 24px 20px !important; margin-top: 40px !important; flex-direction: column !important; text-align: center !important; gap: 16px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 480px) {<!-- [et_pb_line_break_holder] -->  #upl-faq-jsapi .upl-faq-answer-content { padding: 0 20px 20px 20px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><span id=\"anchor-faq\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] --><div class=\"upl-faq-header\"><!-- [et_pb_line_break_holder] -->  <h2 class=\"upl-faq-title\">Frequently Asked Questions<\/h2><!-- [et_pb_line_break_holder] -->  <pee class=\"upl-faq-subtitle\">Common questions about sending email in JavaScript and Node.js with the Unipile unified email API.<\/pee><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><div class=\"upl-faq-list\"><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">01<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">How do I send email in Node.js without SMTP?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\">Use the Unipile unified email API instead of a direct SMTP connection. Install <code>unipile-node-sdk<\/code>, initialise <code>UnipileClient<\/code> with your DSN and token, link a Gmail or Outlook account via OAuth, then call <code>client.email.send()<\/code>. No SMTP server, no port 587, no TLS configuration needed on your end &#8211; Unipile handles the transport layer.<\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">02<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">Can I use this API in the browser with JavaScript?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\"><pee>No &#8211; and you should not. Calling the Unipile API from browser JavaScript would expose your <code>UNIPILE_TOKEN<\/code> to any user who opens DevTools. Always call the API from a server-side Node.js context: an Express route, a Next.js API route (<code>app\/api\/<\/code>), a Vercel Edge Function, or a Netlify Function.<\/pee><pee>Your frontend sends a request to your own backend endpoint, which authenticates the user session and then calls Unipile server-side.<\/pee><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">03<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">What is the difference between Nodemailer and a unified email API?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\"><pee>Nodemailer connects directly to an SMTP server from your Node.js process. It requires you to manage SMTP credentials, handle TLS, configure DKIM yourself, and deal with each provider&#8217;s quirks separately.<\/pee><pee>The Unipile email API is a cloud abstraction layer: you link accounts via OAuth (no SMTP credentials needed for Gmail\/Outlook), get a single consistent SDK for all providers, and Unipile handles transport, retries, and token refresh. The trade-off is that your sends go through Unipile&#8217;s infrastructure rather than a direct SMTP connection.<\/pee><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">04<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">Does this work with TypeScript?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\"><pee>Yes. The <code>unipile-node-sdk<\/code> package ships with TypeScript type definitions. You get full autocomplete and type safety for the <code>send()<\/code> payload, including <code>Recipient<\/code>, <code>tracking_options<\/code>, and the response type.<\/pee><div class=\"faq-mini-code\"><code><span class=\"fq-k\">import<\/span><span class=\"fq-w\"> <\/span><span class=\"fq-fn\">{ UnipileClient }<\/span><span class=\"fq-w\"> <\/span><span class=\"fq-k\">from<\/span><span class=\"fq-w\"> <\/span><span class=\"fq-s\">'unipile-node-sdk'<\/span><span class=\"fq-w\">;<!-- [et_pb_line_break_holder] --><\/span><span class=\"fq-c\">\/\/ Full TS types - autocomplete works in VSCode<\/span><span class=\"fq-w\"><!-- [et_pb_line_break_holder] --><\/span><span class=\"fq-k\">const<\/span><span class=\"fq-w\"> client: <\/span><span class=\"fq-fn\">UnipileClient<\/span><span class=\"fq-w\"> <\/span><span class=\"fq-fn\">= new<\/span><span class=\"fq-w\"> <\/span><span class=\"fq-fn\">UnipileClient<\/span><span class=\"fq-w\">(dsn, token);<!-- [et_pb_line_break_holder] --><\/span><span class=\"fq-k\">const<\/span><span class=\"fq-w\"> result <\/span><span class=\"fq-fn\">= await<\/span><span class=\"fq-w\"> client.email.<\/span><span class=\"fq-fn\">send<\/span><span class=\"fq-w\">({ <\/span><span class=\"fq-c\">\/* typed! *\/<\/span><span class=\"fq-w\"> });<\/span><\/code><\/div><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">05<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">How do I send 10,000 emails from Node.js?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\"><pee>For high-volume sends, use a concurrency limiter (e.g. <code>p-limit<\/code> with 5-10 concurrent calls), add exponential backoff on 429 responses, and spread sends across multiple linked accounts if possible. Each linked email account has its own sending limits set by the provider (Gmail: ~500\/day for regular accounts, higher for Workspace).<\/pee><pee>For true bulk\/marketing email at scale (millions of recipients), consider a dedicated ESP (Mailgun, SendGrid) alongside Unipile for transactional and OAuth-based sends.<\/pee><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-item\"><!-- [et_pb_line_break_holder] -->    <button class=\"upl-faq-question\" aria-expanded=\"false\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-question-content\"><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-number\">06<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"upl-faq-question-text\">Can I use it with Next.js, Nuxt, or NestJS?<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"\/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->    <\/button><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-answer\"><!-- [et_pb_line_break_holder] -->      <div class=\"upl-faq-answer-content\"><pee><strong>Next.js:<\/strong> use API routes (<code>app\/api\/send-email\/route.js<\/code>) or Server Actions. Keep the SDK instantiation server-side only.<\/pee><pee><strong>Nuxt:<\/strong> use server routes (<code>server\/api\/send-email.post.ts<\/code>). The SDK is Node.js-only so it cannot go in a composable or plugin that runs on the client.<\/pee><pee><strong>NestJS:<\/strong> create an <code>EmailModule<\/code> with a service that wraps <code>UnipileClient<\/code>. Inject it wherever you need to trigger sends &#8211; in controllers, CRON jobs, or event handlers.<\/pee><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><div class=\"upl-faq-cta\"><!-- [et_pb_line_break_holder] -->  <pee class=\"upl-faq-cta-text\">Still have questions? Our team is here to help.<\/pee><!-- [et_pb_line_break_holder] -->  <button class=\"upl-faq-cta-button\" onclick=\"if(window.$crisp){$crisp.push(['do','chat:open'])}\"><span>Talk to an expert<\/span><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/button><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><\/div><!-- [et_pb_line_break_holder] --><script type=\"application\/ld+json\"><!-- [et_pb_line_break_holder] -->{<!-- [et_pb_line_break_holder] -->  \"@context\": \"https:\/\/schema.org\",<!-- [et_pb_line_break_holder] -->  \"@type\": \"FAQPage\",<!-- [et_pb_line_break_holder] -->  \"mainEntity\": [<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"How do I send email in Node.js without SMTP?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"Use the Unipile unified email API. Install unipile-node-sdk, initialise UnipileClient with your DSN and token, link a Gmail or Outlook account via OAuth, then call client.email.send(). No SMTP server, no port 587, no TLS configuration needed on your end.\"}},<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"Can I use this API in the browser with JavaScript?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"No. Calling the Unipile API from browser JavaScript would expose your UNIPILE_TOKEN. Always call the API from server-side Node.js: an Express route, a Next.js API route, a Vercel Edge Function, or a Netlify Function.\"}},<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"What is the difference between Nodemailer and a unified email API?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"Nodemailer connects directly to SMTP and requires managing credentials and TLS per provider. The Unipile email API is a cloud abstraction: link accounts via OAuth, use a single SDK for all providers, and Unipile handles transport, retries, and token refresh.\"}},<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"Does the Unipile email API work with TypeScript?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"Yes. The unipile-node-sdk package ships with TypeScript type definitions. You get full autocomplete and type safety for the send() payload including Recipient, tracking_options, and the response type.\"}},<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"How do I send 10,000 emails from Node.js?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"Use a concurrency limiter like p-limit with 5-10 concurrent calls, add exponential backoff on 429 responses, and spread sends across multiple linked accounts. Each provider has its own daily sending limits.\"}},<!-- [et_pb_line_break_holder] -->    {\"@type\": \"Question\",\"name\": \"Can I use the Unipile send email API with Next.js, Nuxt, or NestJS?\",\"acceptedAnswer\": {\"@type\": \"Answer\",\"text\": \"Yes. In Next.js use API routes or Server Actions. In Nuxt use server routes. In NestJS create an EmailModule with a service wrapping UnipileClient. The SDK must always run server-side.\"}}<!-- [et_pb_line_break_holder] -->  ]<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/script><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function(){<!-- [et_pb_line_break_holder] -->  function init(){<!-- [et_pb_line_break_holder] -->    document.querySelectorAll('#upl-faq-jsapi .upl-faq-question').forEach(function(btn){<!-- [et_pb_line_break_holder] -->      btn.addEventListener('click', function(){<!-- [et_pb_line_break_holder] -->        var item = btn.closest('.upl-faq-item');<!-- [et_pb_line_break_holder] -->        var isActive = item.classList.contains('active');<!-- [et_pb_line_break_holder] -->        document.querySelectorAll('#upl-faq-jsapi .upl-faq-item').forEach(function(i){<!-- [et_pb_line_break_holder] -->          i.classList.remove('active');<!-- [et_pb_line_break_holder] -->          i.querySelector('.upl-faq-question').setAttribute('aria-expanded','false');<!-- [et_pb_line_break_holder] -->        });<!-- [et_pb_line_break_holder] -->        if(!isActive){ item.classList.add('active'); btn.setAttribute('aria-expanded','true'); }<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->    });<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',init);}else{init();}<!-- [et_pb_line_break_holder] -->})();<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]\n","protected":false},"excerpt":{"rendered":"<p>JavaScript Tutorial How to Send Email via API in JavaScript (Node.js Tutorial) Skip the SMTP boilerplate. This guide shows you how to send email in Node.js using the Unipile unified email API &#8211; with copy-paste code for Gmail, Outlook, and SMTP in under 10 lines of JavaScript. send email api javascript node.js send email api [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":278466,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","inline_featured_image":false,"footnotes":""},"categories":[37],"tags":[],"post_folder":[],"class_list":["post-278358","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cat-guides"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Send Email via API in JavaScript (Node.js Tutorial) - Unipile<\/title>\n<meta name=\"description\" content=\"Learn how to send email via API in JavaScript with Node.js. Copy-paste examples for Gmail, Outlook &amp; SMTP using the Unipile unified API.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.unipile.com\/nl\/e-mail-verzenden-api-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Send Email via API in JavaScript (Node.js Tutorial) - Unipile\" \/>\n<meta property=\"og:description\" content=\"Learn how to send email via API in JavaScript with Node.js. Copy-paste examples for Gmail, Outlook &amp; SMTP using the Unipile unified API.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.unipile.com\/nl\/e-mail-verzenden-api-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Unipile\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/unipilefr\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-24T14:37:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-28T15:24:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/gmail-3.svg\" \/>\n<meta name=\"author\" content=\"Damien Girardeau\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@UnipileAPI\" \/>\n<meta name=\"twitter:site\" content=\"@UnipileAPI\" \/>\n<meta name=\"twitter:label1\" content=\"Geschreven door\" \/>\n\t<meta name=\"twitter:data1\" content=\"Damien Girardeau\" \/>\n\t<meta name=\"twitter:label2\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/\"},\"author\":{\"name\":\"Damien Girardeau\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#\\\/schema\\\/person\\\/a2ac44e22bdc27d497ce8b58716a673e\"},\"headline\":\"How to Send Email via API in JavaScript (Node.js Tutorial)\",\"datePublished\":\"2026-04-24T14:37:49+00:00\",\"dateModified\":\"2026-04-28T15:24:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/\"},\"wordCount\":3733,\"publisher\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/08-send-email-api-javascript.png\",\"articleSection\":[\"Guides\"],\"inLanguage\":\"nl-NL\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/\",\"name\":\"How to Send Email via API in JavaScript (Node.js Tutorial) - Unipile\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/08-send-email-api-javascript.png\",\"datePublished\":\"2026-04-24T14:37:49+00:00\",\"dateModified\":\"2026-04-28T15:24:47+00:00\",\"description\":\"Learn how to send email via API in JavaScript with Node.js. Copy-paste examples for Gmail, Outlook & SMTP using the Unipile unified API.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/08-send-email-api-javascript.png\",\"contentUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/08-send-email-api-javascript.png\",\"width\":2400,\"height\":1600,\"caption\":\"Quick Node.js tutorial with copy-paste examples for Gmail, Outlook and IMAP using the Unipile unified API.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/send-email-api-javascript\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.unipile.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Send Email via API in JavaScript (Node.js Tutorial)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#website\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/\",\"name\":\"Unipile\",\"description\":\"Integrate Messaging &amp; Email, Connect with Ease via API\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.unipile.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#organization\",\"name\":\"Unipile\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2021\\\/05\\\/logo-unipile.png\",\"contentUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2021\\\/05\\\/logo-unipile.png\",\"width\":200,\"height\":49,\"caption\":\"Unipile\"},\"image\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/unipilefr\",\"https:\\\/\\\/x.com\\\/UnipileAPI\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/unipile\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#\\\/schema\\\/person\\\/a2ac44e22bdc27d497ce8b58716a673e\",\"name\":\"Damien Girardeau\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g\",\"caption\":\"Damien Girardeau\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"E-mail versturen via API in JavaScript (Node.js Tutorial) - Unipile","description":"Leer hoe je e-mail verstuurt via een API in JavaScript met Node.js. Kopieer-plak voorbeelden voor Gmail, Outlook &amp; SMTP met de Unipile unified API.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.unipile.com\/nl\/e-mail-verzenden-api-javascript\/","og_locale":"nl_NL","og_type":"article","og_title":"How to Send Email via API in JavaScript (Node.js Tutorial) - Unipile","og_description":"Learn how to send email via API in JavaScript with Node.js. Copy-paste examples for Gmail, Outlook & SMTP using the Unipile unified API.","og_url":"https:\/\/www.unipile.com\/nl\/e-mail-verzenden-api-javascript\/","og_site_name":"Unipile","article_publisher":"https:\/\/www.facebook.com\/unipilefr","article_published_time":"2026-04-24T14:37:49+00:00","article_modified_time":"2026-04-28T15:24:47+00:00","og_image":[{"url":"https:\/\/www.unipile.com\/wp-content\/uploads\/2024\/02\/gmail-3.svg","type":"","width":"","height":""}],"author":"Damien Girardeau","twitter_card":"summary_large_image","twitter_creator":"@UnipileAPI","twitter_site":"@UnipileAPI","twitter_misc":{"Geschreven door":"Damien Girardeau","Geschatte leestijd":"11 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#article","isPartOf":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/"},"author":{"name":"Damien Girardeau","@id":"https:\/\/www.unipile.com\/#\/schema\/person\/a2ac44e22bdc27d497ce8b58716a673e"},"headline":"How to Send Email via API in JavaScript (Node.js Tutorial)","datePublished":"2026-04-24T14:37:49+00:00","dateModified":"2026-04-28T15:24:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/"},"wordCount":3733,"publisher":{"@id":"https:\/\/www.unipile.com\/#organization"},"image":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/04\/08-send-email-api-javascript.png","articleSection":["Guides"],"inLanguage":"nl-NL"},{"@type":"WebPage","@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/","url":"https:\/\/www.unipile.com\/send-email-api-javascript\/","name":"E-mail versturen via API in JavaScript (Node.js Tutorial) - Unipile","isPartOf":{"@id":"https:\/\/www.unipile.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#primaryimage"},"image":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/04\/08-send-email-api-javascript.png","datePublished":"2026-04-24T14:37:49+00:00","dateModified":"2026-04-28T15:24:47+00:00","description":"Leer hoe je e-mail verstuurt via een API in JavaScript met Node.js. Kopieer-plak voorbeelden voor Gmail, Outlook &amp; SMTP met de Unipile unified API.","breadcrumb":{"@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.unipile.com\/send-email-api-javascript\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#primaryimage","url":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/04\/08-send-email-api-javascript.png","contentUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/04\/08-send-email-api-javascript.png","width":2400,"height":1600,"caption":"Quick Node.js tutorial with copy-paste examples for Gmail, Outlook and IMAP using the Unipile unified API."},{"@type":"BreadcrumbList","@id":"https:\/\/www.unipile.com\/send-email-api-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.unipile.com\/"},{"@type":"ListItem","position":2,"name":"How to Send Email via API in JavaScript (Node.js Tutorial)"}]},{"@type":"WebSite","@id":"https:\/\/www.unipile.com\/#website","url":"https:\/\/www.unipile.com\/","name":"Eenpaal","description":"Integreer berichten en e-mail, maak eenvoudig verbinding via API","publisher":{"@id":"https:\/\/www.unipile.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.unipile.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/www.unipile.com\/#organization","name":"Eenpaal","url":"https:\/\/www.unipile.com\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/www.unipile.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.unipile.com\/wp-content\/uploads\/2021\/05\/logo-unipile.png","contentUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2021\/05\/logo-unipile.png","width":200,"height":49,"caption":"Unipile"},"image":{"@id":"https:\/\/www.unipile.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/unipilefr","https:\/\/x.com\/UnipileAPI","https:\/\/www.linkedin.com\/company\/unipile\/"]},{"@type":"Person","@id":"https:\/\/www.unipile.com\/#\/schema\/person\/a2ac44e22bdc27d497ce8b58716a673e","name":"Damien Girardeau","image":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/secure.gravatar.com\/avatar\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/12dd140720736a8db29f540c42a17d2680cd54a04fb26bb7b55423c179b065a9?s=96&d=mm&r=g","caption":"Damien Girardeau"}}]}},"_links":{"self":[{"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/posts\/278358","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/comments?post=278358"}],"version-history":[{"count":14,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/posts\/278358\/revisions"}],"predecessor-version":[{"id":278408,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/posts\/278358\/revisions\/278408"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/media\/278466"}],"wp:attachment":[{"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/media?parent=278358"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/categories?post=278358"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/tags?post=278358"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/www.unipile.com\/nl\/wp-json\/wp\/v2\/post_folder?post=278358"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}