{"id":279162,"date":"2026-06-05T10:52:54","date_gmt":"2026-06-05T08:52:54","guid":{"rendered":"https:\/\/www.unipile.com\/?p=279162"},"modified":"2026-06-08T16:59:12","modified_gmt":"2026-06-08T14:59:12","slug":"gmail-api-push-benachrichtigungen","status":"publish","type":"post","link":"https:\/\/www.unipile.com\/de\/gmail-api-push-notifications\/","title":{"rendered":"Gmail API Push-Benachrichtigungen: Vollst\u00e4ndiger Leitfaden zu Pub\/Sub, Watch &amp; History (2026)"},"content":{"rendered":"\n[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.0&#8243; background_color=&#8221;transparent&#8221; width=&#8221;100%&#8221; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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; da_disable_devices=&#8221;off|off|off&#8221;][et_pb_row _builder_version=&#8221;4.27.0&#8243; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<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\": \"TechArticle\",<!-- [et_pb_line_break_holder] -->  \"headline\": \"Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch & History (2026)\",<!-- [et_pb_line_break_holder] -->  \"description\": \"Set up Gmail API push notifications end-to-end. Pub\/Sub topic, watch endpoint, historyId reconciliation, renewal, troubleshooting, plus a unified webhook alternative.\",<!-- [et_pb_line_break_holder] -->  \"keywords\": \"gmail api push notifications, gmail api watch, gmail api history, gmail pub sub setup, gmail api real time, gmail watch endpoint, gmail pubsub notifications, gmail historyid\",<!-- [et_pb_line_break_holder] -->  \"author\": {<!-- [et_pb_line_break_holder] -->    \"@type\": \"Organization\",<!-- [et_pb_line_break_holder] -->    \"name\": \"Unipile\",<!-- [et_pb_line_break_holder] -->    \"url\": \"https:\/\/www.unipile.com\"<!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->  \"publisher\": {<!-- [et_pb_line_break_holder] -->    \"@type\": \"Organization\",<!-- [et_pb_line_break_holder] -->    \"name\": \"Unipile\",<!-- [et_pb_line_break_holder] -->    \"logo\": {<!-- [et_pb_line_break_holder] -->      \"@type\": \"ImageObject\",<!-- [et_pb_line_break_holder] -->      \"url\": \"https:\/\/www.unipile.com\/wp-content\/uploads\/unipile-logo.svg\"<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->  \"datePublished\": \"2026-06-05\",<!-- [et_pb_line_break_holder] -->  \"dateModified\": \"2026-06-05\",<!-- [et_pb_line_break_holder] -->  \"mainEntityOfPage\": {<!-- [et_pb_line_break_holder] -->    \"@type\": \"WebPage\",<!-- [et_pb_line_break_holder] -->    \"@id\": \"https:\/\/www.unipile.com\/gmail-api-push-notifications\/\"<!-- [et_pb_line_break_holder] -->  },<!-- [et_pb_line_break_holder] -->  \"proficiencyLevel\": \"Intermediate\",<!-- [et_pb_line_break_holder] -->  \"dependencies\": \"Gmail API, Google Cloud Pub\/Sub, Node.js or Python\"<!-- [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.0&#8243; background_color=&#8221;transparent&#8221; width=&#8221;100%&#8221; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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; da_disable_devices=&#8221;off|off|off&#8221;][et_pb_row _builder_version=&#8221;4.27.0&#8243; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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.0&#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;]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->\/* ============================================================<!-- [et_pb_line_break_holder] -->   UNIPILE TOC  -  Gmail Push Notifications article  -  Divi-safe<!-- [et_pb_line_break_holder] -->   ============================================================ *\/<!-- [et_pb_line_break_holder] -->#unipile-toc,<!-- [et_pb_line_break_holder] -->#unipile-toc *,<!-- [et_pb_line_break_holder] -->#unipile-toc *::before,<!-- [et_pb_line_break_holder] -->#unipile-toc *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: normal !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->  float: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  width: 100% !important;<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->  position: relative !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  font-size: 16px !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-card {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  padding: 32px !important;<!-- [et_pb_line_break_holder] -->  box-shadow: 0 2px 12px rgba(15, 39, 54, 0.04) !important;<!-- [et_pb_line_break_holder] -->  width: 100% !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-header {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: space-between !important;<!-- [et_pb_line_break_holder] -->  gap: 12px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 24px !important;<!-- [et_pb_line_break_holder] -->  padding-bottom: 20px !important;<!-- [et_pb_line_break_holder] -->  border-bottom: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-header-left {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 12px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-icon-box {<!-- [et_pb_line_break_holder] -->  width: 36px !important;<!-- [et_pb_line_break_holder] -->  height: 36px !important;<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-icon-box svg {<!-- [et_pb_line_break_holder] -->  width: 18px !important;<!-- [et_pb_line_break_holder] -->  height: 18px !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 15px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !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] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-toggle {<!-- [et_pb_line_break_holder] -->  display: none !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 6px !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  padding: 6px 10px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 6px !important;<!-- [et_pb_line_break_holder] -->  transition: background 0.2s ease !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-toggle svg {<!-- [et_pb_line_break_holder] -->  width: 14px !important;<!-- [et_pb_line_break_holder] -->  height: 14px !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc:not(.utc-expanded) .utc-toggle svg {<!-- [et_pb_line_break_holder] -->  transform: rotate(-90deg) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-grid {<!-- [et_pb_line_break_holder] -->  display: grid !important;<!-- [et_pb_line_break_holder] -->  grid-template-columns: repeat(4, 1fr) !important;<!-- [et_pb_line_break_holder] -->  gap: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-col {<!-- [et_pb_line_break_holder] -->  padding: 0 24px !important;<!-- [et_pb_line_break_holder] -->  border-left: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-col:first-child {<!-- [et_pb_line_break_holder] -->  padding-left: 0 !important;<!-- [et_pb_line_break_holder] -->  border-left: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-col:last-child {<!-- [et_pb_line_break_holder] -->  padding-right: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-col-label {<!-- [et_pb_line_break_holder] -->  font-size: 11px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #94a3b8 !important;<!-- [et_pb_line_break_holder] -->  text-transform: uppercase !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: 0.8px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 14px !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link-list {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 10px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: flex-start !important;<!-- [et_pb_line_break_holder] -->  gap: 10px !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  transition: all 0.2s ease !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  padding: 4px 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-num {<!-- [et_pb_line_break_holder] -->  width: 18px !important;<!-- [et_pb_line_break_holder] -->  height: 18px !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->  font-size: 10px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #94a3b8 !important;<!-- [et_pb_line_break_holder] -->  transition: all 0.2s ease !important;<!-- [et_pb_line_break_holder] -->  margin-top: 1px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-num.utc-num-faq {<!-- [et_pb_line_break_holder] -->  font-size: 8px !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: 0.2px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link-text {<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 500 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.45 !important;<!-- [et_pb_line_break_holder] -->  transition: color 0.2s ease !important;<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link:hover .utc-num {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.15) !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link:hover .utc-link-text {<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link.utc-active .utc-num {<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link.utc-active .utc-link-text {<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-link.utc-read .utc-num {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.15) !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#unipile-toc .utc-tag-best {<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  font-size: 9px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 6px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !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-left: 6px !important;<!-- [et_pb_line_break_holder] -->  vertical-align: middle !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 1000px) {<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-grid {<!-- [et_pb_line_break_holder] -->    grid-template-columns: repeat(2, 1fr) !important;<!-- [et_pb_line_break_holder] -->    gap: 24px 0 !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-col {<!-- [et_pb_line_break_holder] -->    padding: 0 20px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-col:nth-child(2n+1) {<!-- [et_pb_line_break_holder] -->    padding-left: 0 !important;<!-- [et_pb_line_break_holder] -->    border-left: none !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-col:nth-child(2n) {<!-- [et_pb_line_break_holder] -->    padding-right: 0 !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 700px) {<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-card {<!-- [et_pb_line_break_holder] -->    padding: 22px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-header {<!-- [et_pb_line_break_holder] -->    margin-bottom: 0 !important;<!-- [et_pb_line_break_holder] -->    padding-bottom: 0 !important;<!-- [et_pb_line_break_holder] -->    border-bottom: none !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-toggle {<!-- [et_pb_line_break_holder] -->    display: flex !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-grid {<!-- [et_pb_line_break_holder] -->    grid-template-columns: 1fr !important;<!-- [et_pb_line_break_holder] -->    gap: 22px !important;<!-- [et_pb_line_break_holder] -->    overflow: hidden !important;<!-- [et_pb_line_break_holder] -->    transition: max-height 0.4s ease, margin-top 0.3s ease, padding-top 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  \/* === COLLAPSED PAR DEFAUT EN CSS sur mobile (avant meme le JS) === *\/<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-grid {<!-- [et_pb_line_break_holder] -->    max-height: 0 !important;<!-- [et_pb_line_break_holder] -->    margin-top: 0 !important;<!-- [et_pb_line_break_holder] -->    padding-top: 0 !important;<!-- [et_pb_line_break_holder] -->    border-top: none !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  \/* Si le JS a tourne et l'utilisateur ouvre, cette classe re-affiche *\/<!-- [et_pb_line_break_holder] -->  #unipile-toc.utc-expanded .utc-grid {<!-- [et_pb_line_break_holder] -->    max-height: 2000px !important;<!-- [et_pb_line_break_holder] -->    margin-top: 22px !important;<!-- [et_pb_line_break_holder] -->    padding-top: 22px !important;<!-- [et_pb_line_break_holder] -->    border-top: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-col {<!-- [et_pb_line_break_holder] -->    padding: 0 !important;<!-- [et_pb_line_break_holder] -->    border-left: none !important;<!-- [et_pb_line_break_holder] -->    border-top: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->    padding-top: 18px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #unipile-toc .utc-col:first-child {<!-- [et_pb_line_break_holder] -->    border-top: none !important;<!-- [et_pb_line_break_holder] -->    padding-top: 0 !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"unipile-toc\"><!-- [et_pb_line_break_holder] -->  <div class=\"utc-card\"><!-- [et_pb_line_break_holder] -->    <div class=\"utc-header\"><!-- [et_pb_line_break_holder] -->      <div class=\"utc-header-left\"><!-- [et_pb_line_break_holder] -->        <div class=\"utc-icon-box\"><!-- [et_pb_line_break_holder] -->          <svg viewBox=\"0 0 24 24\"><!-- [et_pb_line_break_holder] -->            <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"\/><!-- [et_pb_line_break_holder] -->            <line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"\/><!-- [et_pb_line_break_holder] -->            <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"\/><!-- [et_pb_line_break_holder] -->            <line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"\/><!-- [et_pb_line_break_holder] -->            <line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"\/><!-- [et_pb_line_break_holder] -->            <line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"\/><!-- [et_pb_line_break_holder] -->          <\/svg><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <span class=\"utc-title\">Table of Contents<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <button type=\"button\" class=\"utc-toggle\" aria-label=\"Toggle table of contents\"><!-- [et_pb_line_break_holder] -->        <span class=\"utc-toggle-label\">Show<\/span><!-- [et_pb_line_break_holder] -->        <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <\/button><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"utc-grid\"><!-- [et_pb_line_break_holder] -->      <!-- COLUMN 1 : Concepts --><!-- [et_pb_line_break_holder] -->      <div class=\"utc-col\"><!-- [et_pb_line_break_holder] -->        <span class=\"utc-col-label\">Concepts<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"utc-link-list\"><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-what-it-is\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">01<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">What it is<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-architecture\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">02<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Architecture<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-prerequisites\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">03<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Prerequisites<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- COLUMN 2 : Implementation --><!-- [et_pb_line_break_holder] -->      <div class=\"utc-col\"><!-- [et_pb_line_break_holder] -->        <span class=\"utc-col-label\">Implementation<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"utc-link-list\"><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-setup\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">04<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Setup<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-webhook-payload\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">05<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Webhook payload<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-history-reconcile\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">06<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">History reconcile<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-renewal\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">07<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Renewal<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- COLUMN 3 : Reference --><!-- [et_pb_line_break_holder] -->      <div class=\"utc-col\"><!-- [et_pb_line_break_holder] -->        <span class=\"utc-col-label\">Reference<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"utc-link-list\"><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-troubleshooting\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">08<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Troubleshooting<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-quotas\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">09<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Quotas<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-tradeoffs\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">10<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Trade-offs<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- COLUMN 4 : Solution + FAQ --><!-- [et_pb_line_break_holder] -->      <div class=\"utc-col\"><!-- [et_pb_line_break_holder] -->        <span class=\"utc-col-label\">Solution<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"utc-link-list\"><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#gpn-unified\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num\">11<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Unified (Unipile)<span class=\"utc-tag-best\">Best<\/span><\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [et_pb_line_break_holder] -->          <a class=\"utc-link\" href=\"#faq-gpn\"><!-- [et_pb_line_break_holder] -->            <span class=\"utc-num utc-num-faq\">FAQ<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"utc-link-text\">Frequently Asked Questions<\/span><!-- [et_pb_line_break_holder] -->          <\/a><!-- [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] --><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function(){<!-- [et_pb_line_break_holder] -->  var toc = document.getElementById('unipile-toc');<!-- [et_pb_line_break_holder] -->  if (!toc) return;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  var MOBILE_BP = 700;<!-- [et_pb_line_break_holder] -->  var toggleBtn = toc.querySelector('.utc-toggle');<!-- [et_pb_line_break_holder] -->  var toggleLabel = toc.querySelector('.utc-toggle-label');<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  function syncInitial(){<!-- [et_pb_line_break_holder] -->    if (window.innerWidth <= MOBILE_BP) {<!-- [et_pb_line_break_holder] -->      toc.classList.remove('utc-expanded');<!-- [et_pb_line_break_holder] -->      if (toggleLabel) toggleLabel.textContent = 'Show';<!-- [et_pb_line_break_holder] -->    } else {<!-- [et_pb_line_break_holder] -->      toc.classList.add('utc-expanded');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  syncInitial();<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  if (toggleBtn) {<!-- [et_pb_line_break_holder] -->    toggleBtn.addEventListener('click', function(){<!-- [et_pb_line_break_holder] -->      var isOpen = toc.classList.toggle('utc-expanded');<!-- [et_pb_line_break_holder] -->      if (toggleLabel) toggleLabel.textContent = isOpen ? 'Hide' : 'Show';<!-- [et_pb_line_break_holder] -->    });<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  var resizeTimer = null;<!-- [et_pb_line_break_holder] -->  window.addEventListener('resize', function(){<!-- [et_pb_line_break_holder] -->    if (resizeTimer) clearTimeout(resizeTimer);<!-- [et_pb_line_break_holder] -->    resizeTimer = setTimeout(syncInitial, 150);<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  var links = toc.querySelectorAll('.utc-link');<!-- [et_pb_line_break_holder] -->  links.forEach(function(link){<!-- [et_pb_line_break_holder] -->    link.addEventListener('click', function(e){<!-- [et_pb_line_break_holder] -->      var href = link.getAttribute('href');<!-- [et_pb_line_break_holder] -->      if (!href || href.charAt(0) !== '#') return;<!-- [et_pb_line_break_holder] -->      var target = document.getElementById(href.substring(1));<!-- [et_pb_line_break_holder] -->      if (target) {<!-- [et_pb_line_break_holder] -->        e.preventDefault();<!-- [et_pb_line_break_holder] -->        var offset = 80;<!-- [et_pb_line_break_holder] -->        var top = target.getBoundingClientRect().top + window.pageYOffset - offset;<!-- [et_pb_line_break_holder] -->        window.scrollTo({ top: top, behavior: 'smooth' });<!-- [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] -->  var sectionIds = [];<!-- [et_pb_line_break_holder] -->  links.forEach(function(link){<!-- [et_pb_line_break_holder] -->    var href = link.getAttribute('href');<!-- [et_pb_line_break_holder] -->    if (href && href.charAt(0) === '#') sectionIds.push(href.substring(1));<!-- [et_pb_line_break_holder] -->  });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  function updateActive(){<!-- [et_pb_line_break_holder] -->    var scrollY = window.pageYOffset + 120;<!-- [et_pb_line_break_holder] -->    var activeId = null;<!-- [et_pb_line_break_holder] -->    var readIds = [];<!-- [et_pb_line_break_holder] -->    sectionIds.forEach(function(id){<!-- [et_pb_line_break_holder] -->      var el = document.getElementById(id);<!-- [et_pb_line_break_holder] -->      if (el) {<!-- [et_pb_line_break_holder] -->        var top = el.getBoundingClientRect().top + window.pageYOffset;<!-- [et_pb_line_break_holder] -->        if (top <= scrollY) {<!-- [et_pb_line_break_holder] -->          activeId = id;<!-- [et_pb_line_break_holder] -->          readIds.push(id);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    });<!-- [et_pb_line_break_holder] -->    links.forEach(function(link){<!-- [et_pb_line_break_holder] -->      var href = link.getAttribute('href');<!-- [et_pb_line_break_holder] -->      var id = href ? href.substring(1) : '';<!-- [et_pb_line_break_holder] -->      link.classList.remove('utc-active', 'utc-read');<!-- [et_pb_line_break_holder] -->      if (id === activeId) {<!-- [et_pb_line_break_holder] -->        link.classList.add('utc-active');<!-- [et_pb_line_break_holder] -->      } else if (readIds.indexOf(id) !== -1) {<!-- [et_pb_line_break_holder] -->        link.classList.add('utc-read');<!-- [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] -->  if ('IntersectionObserver' in window) {<!-- [et_pb_line_break_holder] -->    var observer = new IntersectionObserver(function(){<!-- [et_pb_line_break_holder] -->      updateActive();<!-- [et_pb_line_break_holder] -->    }, { rootMargin: '-120px 0px -60% 0px' });<!-- [et_pb_line_break_holder] -->    sectionIds.forEach(function(id){<!-- [et_pb_line_break_holder] -->      var el = document.getElementById(id);<!-- [et_pb_line_break_holder] -->      if (el) observer.observe(el);<!-- [et_pb_line_break_holder] -->    });<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  window.addEventListener('scroll', updateActive, { passive: true });<!-- [et_pb_line_break_holder] -->  updateActive();<!-- [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.0&#8243; background_color=&#8221;transparent&#8221; width=&#8221;100%&#8221; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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; da_disable_devices=&#8221;off|off|off&#8221;][et_pb_row _builder_version=&#8221;4.27.0&#8243; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-hero,<!-- [et_pb_line_break_holder] -->#upl-gpn-hero *,<!-- [et_pb_line_break_holder] -->#upl-gpn-hero *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-hero *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px 60px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-hero-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: 60px !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-hero-left {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 20px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-eyebrow-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero 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] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-accent {<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-desc {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-actions {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 14px !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->  margin-top: 8px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-cta-primary {<!-- [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: #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 14px 28px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.95rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-cta-primary:hover {<!-- [et_pb_line_break_holder] -->  transform: translateY(-5px) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-cta-secondary {<!-- [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: transparent !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 24px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #0f2736 !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.95rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  transition: all 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-cta-secondary:hover {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-cta-svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  stroke: currentColor !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Code mockup *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  box-shadow: 0 20px 60px rgba(15, 39, 54, 0.18) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-hero .gpn-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-pre {<!-- [et_pb_line_break_holder] -->  padding: 22px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-editor-ok {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.1) !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;<!-- [et_pb_line_break_holder] -->  padding: 11px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 12.5px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-hero .gpn-ok-dot {<!-- [et_pb_line_break_holder] -->  width: 8px !important;<!-- [et_pb_line_break_holder] -->  height: 8px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero .gpn-hero-inner {<!-- [et_pb_line_break_holder] -->    grid-template-columns: 1fr !important;<!-- [et_pb_line_break_holder] -->    gap: 40px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero 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-gpn-hero { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero h1 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero .gpn-desc { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero .gpn-actions { flex-direction: column !important; align-items: flex-start !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero .gpn-cta-primary,<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero .gpn-cta-secondary { width: 100% !important; justify-content: center !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 400px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-hero h1 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-hero\"><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-hero-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-hero-left\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-eyebrow\"><span class=\"gpn-eyebrow-dot\"><\/span><span>Gmail API Guide<\/span><\/div><!-- [et_pb_line_break_holder] -->      <h1>Gmail API <span class=\"gpn-accent\">Push Notifications<\/span>: Complete Guide to Pub\/Sub, Watch &#038; History (2026)<\/h1><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-desc\">Set up Gmail API push notifications end-to-end: create a Pub\/Sub topic, register a watch endpoint, decode webhook payloads, reconcile changes with <code style=\"background:rgba(59,185,139,0.12)!important;padding:2px 6px!important;border-radius:4px!important;font-family:'Courier New',monospace!important;font-size:0.85em!important;color:#2aaa7e!important;\">users.history.list<\/code>, automate watch renewal, and skip the entire GCP setup with a unified webhook alternative.<\/pee><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-actions\"><!-- [et_pb_line_break_holder] -->        <a class=\"gpn-cta-primary\" href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" rel=\"noopener\"><svg class=\"gpn-cta-svg\" viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><span>Start building for free<\/span><\/a><!-- [et_pb_line_break_holder] -->        <a class=\"gpn-cta-secondary\" href=\"https:\/\/developer.unipile.com\/docs\/getting-started\" target=\"_blank\" rel=\"noopener\"><span>View docs<\/span><\/a><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-hero-right\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-dot gpn-dot-r\"><\/span><span class=\"gpn-dot gpn-dot-y\"><\/span><span class=\"gpn-dot gpn-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-filename\">gmail-watch.js<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pre\"><code><span class=\"c\">\/\/ 1. Register Gmail watch via Unipile<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">const<\/span> <span class=\"w\">res<\/span> <span class=\"k\">=<\/span> <span class=\"k\">await<\/span> <span class=\"fn\">fetch<\/span><span class=\"w\">(<\/span><span class=\"s\">'https:\/\/api8.unipile.com:13815\/api\/v1'<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">+<\/span> <span class=\"s\">'\/accounts\/{id}\/watch'<\/span><span class=\"w\">,<\/span> <span class=\"w\">{<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">method:<\/span> <span class=\"s\">'POST'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">headers:<\/span> <span class=\"w\">{<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"s\">'X-API-KEY'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'YOUR_API_KEY'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"s\">'Content-Type'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'application\/json'<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">},<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">body:<\/span> <span class=\"fn\">JSON<\/span><span class=\"w\">.<\/span><span class=\"fn\">stringify<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">webhook_url:<\/span> <span class=\"s\">'https:\/\/app.you.com\/webhooks\/gmail'<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">})<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ 2. Receive unified webhook payload<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">app.<\/span><span class=\"fn\">post<\/span><span class=\"w\">(<\/span><span class=\"s\">'\/webhooks\/gmail'<\/span><span class=\"w\">,<\/span> <span class=\"w\">(req, res) => {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">{ event, account_id, email } =<\/span> <span class=\"w\">req.body;<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ event: \"new_email\" | historyId abstracted<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"fn\">handleNewEmail<\/span><span class=\"w\">(email);<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-editor-ok\"><span class=\"gpn-ok-dot\"><\/span><span>Real-time Gmail events &#8211; no GCP setup required<\/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_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.0&#8243; background_color=&#8221;transparent&#8221; width=&#8221;100%&#8221; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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; da_disable_devices=&#8221;off|off|off&#8221;][et_pb_row _builder_version=&#8221;4.27.0&#8243; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;][et_pb_code _builder_version=&#8221;4.27.0&#8243; global_colors_info=&#8221;{}&#8221; theme_builder_area=&#8221;post_content&#8221;]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-what,<!-- [et_pb_line_break_holder] -->#upl-gpn-what *,<!-- [et_pb_line_break_holder] -->#upl-gpn-what *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-what *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-definition {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 32px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-def-label {<!-- [et_pb_line_break_holder] -->  font-size: 11px !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.8px !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 12px !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-def-text {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  font-weight: 500 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-grid {<!-- [et_pb_line_break_holder] -->  display: grid !important;<!-- [et_pb_line_break_holder] -->  grid-template-columns: repeat(3, 1fr) !important;<!-- [et_pb_line_break_holder] -->  gap: 20px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-card {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 24px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-card-icon {<!-- [et_pb_line_break_holder] -->  width: 44px !important;<!-- [et_pb_line_break_holder] -->  height: 44px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.10) !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-card-icon svg {<!-- [et_pb_line_break_holder] -->  width: 22px !important;<!-- [et_pb_line_break_holder] -->  height: 22px !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-card-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 15px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-card-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.7 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-vs {<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 28px 32px !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: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-vs-col-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 12px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-vs-col-title svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-what .gpn-w-vs-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-what { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-what h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-what .gpn-w-grid { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-what .gpn-w-vs { grid-template-columns: 1fr !important; gap: 24px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-what { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-what h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-what .gpn-w-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-what\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-what-it-is\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-w-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-w-badge\"><span class=\"gpn-w-badge-dot\"><\/span><span>Core Concept<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>What are Gmail API push notifications?<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-w-intro\">Before implementing Gmail API push notifications in production, it helps to understand exactly what they are, how they differ from simple polling, and what infrastructure they require.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-w-definition\"><!-- [et_pb_line_break_holder] -->      <span class=\"gpn-w-def-label\">Definition<\/span><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-w-def-text\">Gmail API push notifications are a real-time delivery mechanism that uses Google Cloud Pub\/Sub to push mailbox change events to a developer-controlled HTTPS endpoint. When a new message arrives or an existing message is modified, Gmail publishes a notification containing an encoded <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 6px!important;border-radius:4px!important;font-family:'Courier New',monospace!important;font-size:0.85em!important;\">historyId<\/code> to a Pub\/Sub topic you own, which then forwards that event to your webhook. Your server calls <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 6px!important;border-radius:4px!important;font-family:'Courier New',monospace!important;font-size:0.85em!important;\">users.history.list<\/code> to retrieve the actual changes.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-w-grid\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-w-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-icon\"><!-- [et_pb_line_break_holder] -->          <svg viewBox=\"0 0 24 24\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12 19.79 19.79 0 0 1 1.65 3.4 2 2 0 0 1 3.62 1h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L7.91 8.91a16 16 0 0 0 6.18 6.18\"\/><\/svg><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-title\">Event-driven, not polling<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-w-card-text\">Gmail API push notifications eliminate the need to repeatedly call <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">messages.list<\/code> on a schedule. Events are delivered within seconds of the mailbox change, reducing both latency and API quota usage.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-w-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-icon\"><!-- [et_pb_line_break_holder] -->          <svg viewBox=\"0 0 24 24\"><polyline points=\"23 6 13.5 15.5 8.5 10.5 1 18\"\/><polyline points=\"17 6 23 6 23 12\"\/><\/svg><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-title\">Powered by Google Pub\/Sub<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-w-card-text\">The delivery channel is Google Cloud Pub\/Sub, not a direct HTTP callback from Gmail. This adds durability: if your endpoint is temporarily unavailable, Pub\/Sub can retry delivery according to its subscription ack deadline.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-w-card\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-icon\"><!-- [et_pb_line_break_holder] -->          <svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><polyline points=\"12 6 12 12 16 14\"\/><\/svg><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-card-title\">7-day watch expiry<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-w-card-text\">A Gmail API watch endpoint expires after 7 days. Your application must renew it proactively with a daily cron job or risk missing events silently. This is a critical operational detail covered in the Renewal section.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-w-vs\"><!-- [et_pb_line_break_holder] -->      <div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-vs-col-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#3BB98B\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><span>Push (Pub\/Sub)<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-w-vs-text\">Gmail API push notifications deliver events within 1-10 seconds of the change. No constant polling means lower quota consumption on the Gmail API and faster time-to-react for your application. Ideal for any inbox-level real-time use case: CRM sync, ticketing systems, workflow automation.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-w-vs-col-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#64748b\"><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><circle cx=\"12\" cy=\"12\" r=\"10\"\/><\/svg><span>Pull (polling)<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-w-vs-text\">Polling <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">messages.list<\/code> every 60 seconds is simpler to set up but introduces artificial lag, wastes quota on empty responses, and scales poorly across large numbers of authenticated user accounts. Acceptable for low-volume prototypes only.<\/pee><!-- [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.0&#8243; background_color=&#8221;transparent&#8221; width=&#8221;100%&#8221; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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; da_disable_devices=&#8221;off|off|off&#8221;][et_pb_row _builder_version=&#8221;4.27.0&#8243; max_width=&#8221;100%&#8221; custom_padding=&#8221;0px||0px||false|false&#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.0&#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;]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-arch,<!-- [et_pb_line_break_holder] -->#upl-gpn-arch *,<!-- [et_pb_line_break_holder] -->#upl-gpn-arch *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-arch *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->  float: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-badge {<!-- [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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  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] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Flow diagram *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-flow {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 36px 32px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-flow-title {<!-- [et_pb_line_break_holder] -->  font-size: 11px !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.8px !important;<!-- [et_pb_line_break_holder] -->  color: #94a3b8 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 28px !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-steps {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 20px !important;<!-- [et_pb_line_break_holder] -->  position: relative !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-left {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-num {<!-- [et_pb_line_break_holder] -->  width: 36px !important;<!-- [et_pb_line_break_holder] -->  height: 36px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-line {<!-- [et_pb_line_break_holder] -->  width: 2px !important;<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->  background: #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  margin: 6px 0 !important;<!-- [et_pb_line_break_holder] -->  min-height: 24px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step:last-child .gpn-arch-step-line {<!-- [et_pb_line_break_holder] -->  display: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-content {<!-- [et_pb_line_break_holder] -->  padding-bottom: 28px !important;<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->  min-width: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step:last-child .gpn-arch-step-content {<!-- [et_pb_line_break_holder] -->  padding-bottom: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 15px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 6px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-code {<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  background: rgba(0, 0, 0, 0.06) !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 8px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'JetBrains Mono', 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  font-size: 12px !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->  overflow-wrap: anywhere !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Inline <code> dans le step text - styling centralis\u00e9 (plus de styles inline) *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-step-text code {<!-- [et_pb_line_break_holder] -->  background: rgba(0, 0, 0, 0.06) !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 5px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 3px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'JetBrains Mono', 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.85em !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->  overflow-wrap: anywhere !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Key concepts grid *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-concepts {<!-- [et_pb_line_break_holder] -->  display: grid !important;<!-- [et_pb_line_break_holder] -->  grid-template-columns: repeat(3, 1fr) !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-concept {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-concept-term {<!-- [et_pb_line_break_holder] -->  font-family: 'JetBrains Mono', 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->  overflow-wrap: anywhere !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-arch .gpn-arch-concept-def {<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.65 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-intro { font-size: 16px !important; margin-bottom: 32px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-concepts { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch h2 { font-size: 24px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-intro { font-size: 15px !important; line-height: 1.7 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-flow { padding: 22px 16px !important; border-radius: 14px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-flow-title { margin-bottom: 22px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step { gap: 14px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-num {<!-- [et_pb_line_break_holder] -->    width: 30px !important;<!-- [et_pb_line_break_holder] -->    height: 30px !important;<!-- [et_pb_line_break_holder] -->    font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-content { padding-bottom: 22px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-title { font-size: 14px !important; gap: 6px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-code { font-size: 11.5px !important; padding: 2px 6px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-text { font-size: 13.5px !important; line-height: 1.7 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-concept { padding: 18px 16px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 400px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch h2 { font-size: 22px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-flow { padding: 20px 14px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step { gap: 12px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-arch .gpn-arch-step-num { width: 28px !important; height: 28px !important; font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-arch\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-architecture\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-arch-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-arch-badge\"><span class=\"gpn-arch-badge-dot\"><\/span><span>Architecture<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Architecture: watch + Pub\/Sub + historyId in one flow<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-arch-intro\">Gmail API push notifications involve four distinct layers working in sequence. Understanding each layer before writing code prevents the most common implementation mistakes.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-arch-flow\"><!-- [et_pb_line_break_holder] -->      <span class=\"gpn-arch-flow-title\">End-to-end flow<\/span><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-arch-steps\"><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">1<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-line\"><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Your app calls<\/span><span class=\"gpn-arch-step-code\">users.watch<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">You POST to <code>https:\/\/gmail.googleapis.com\/gmail\/v1\/users\/me\/watch<\/code> with your Pub\/Sub topic name and optionally a label filter. Gmail returns a <code>historyId<\/code> and an <code>expiration<\/code> Unix timestamp. Store both. This watch expires in 7 days.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">2<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-line\"><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Gmail publishes to<\/span><span class=\"gpn-arch-step-code\">Pub\/Sub topic<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">When any change occurs in the watched mailbox (new message, label change, read\/unread toggle), Gmail publishes a JSON notification to your Cloud Pub\/Sub topic. The payload is a base64-encoded object containing the user's email address and a new <code>historyId<\/code>.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">3<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-line\"><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Pub\/Sub pushes to your<\/span><span class=\"gpn-arch-step-code\">webhook<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">Your Pub\/Sub subscription forwards the message to a registered HTTPS push endpoint. This is your webhook URL, which must respond with HTTP 200-299 within the ack deadline (default 10-600 seconds). A non-2xx response triggers automatic retries.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">4<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-line\"><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Your webhook extracts<\/span><span class=\"gpn-arch-step-code\">historyId<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">Decode the base64 Pub\/Sub message data. Extract the new <code>historyId<\/code>. Compare it against the <code>lastHistoryId<\/code> stored in your database for this user.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">5<\/div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-line\"><\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Call<\/span><span class=\"gpn-arch-step-code\">users.history.list<\/span><span>to reconcile<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">Call <code>users.history.list<\/code> with <code>startHistoryId<\/code> set to your stored value. Gmail returns all changes (new messages, label additions, deletions) between the two IDs. Update your stored <code>lastHistoryId<\/code> to the new value. Never use the historyId from the Pub\/Sub notification as <code>startHistoryId<\/code> directly.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-step\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-left\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-num\">6<\/div><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-arch-step-content\"><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-arch-step-title\"><span>Renew watch before expiry<\/span><\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-arch-step-text\">Schedule a daily cron job to call <code>users.watch<\/code> again for each authenticated user account. Watch renewal is idempotent: a new call replaces the previous expiry. The returned <code>historyId<\/code> becomes your new baseline.<\/pee><!-- [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] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-arch-concepts\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-arch-concept\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-concept-term\">historyId<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-arch-concept-def\">A monotonically increasing integer assigned by Gmail to every mailbox change. It is your cursor for incremental sync. Always store the latest historyId per user in your database.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-arch-concept\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-concept-term\">users.watch<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-arch-concept-def\">The Gmail API endpoint that registers a push notification subscription for a mailbox. Returns a historyId baseline and a Unix ms expiration timestamp. Must be renewed within 7 days.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-arch-concept\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-arch-concept-term\">users.history.list<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-arch-concept-def\">The reconciliation endpoint. Given a startHistoryId, it returns all message additions, deletions, and label changes that occurred after that point. This is where you get the actual message data.<\/pee><!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.4\" hover_enabled=\"0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" sticky_enabled=\"0\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-prereq,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq *,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->  float: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Inline <code> dans l'intro, items et alerte - styling centralis\u00e9 *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-intro code,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-text code {<!-- [et_pb_line_break_holder] -->  background: rgba(0, 0, 0, 0.06) !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 5px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 3px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'JetBrains Mono', 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.85em !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->  overflow-wrap: anywhere !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-intro code {<!-- [et_pb_line_break_holder] -->  background: rgba(59,185,139,0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.85em !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-intro a,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-text a,<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-alert-text a {<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !important;<!-- [et_pb_line_break_holder] -->  text-decoration: underline !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->  overflow-wrap: anywhere !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-list {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 20px !important;<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  padding: 24px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-num {<!-- [et_pb_line_break_holder] -->  width: 36px !important;<!-- [et_pb_line_break_holder] -->  height: 36px !important;<!-- [et_pb_line_break_holder] -->  min-width: 36px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-body {<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->  min-width: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 15px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-item-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-alert {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.08) !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid rgba(59, 185, 139, 0.3) !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px 24px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->  align-items: flex-start !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-alert-icon {<!-- [et_pb_line_break_holder] -->  width: 22px !important;<!-- [et_pb_line_break_holder] -->  height: 22px !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  margin-top: 1px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-alert-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  min-width: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-strip {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 32px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: space-between !important;<!-- [et_pb_line_break_holder] -->  gap: 24px !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-body {<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->  min-width: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-text {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 18px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-sub {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  color: rgba(255,255,255,0.7) !important;<!-- [et_pb_line_break_holder] -->  margin-top: 6px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-btn {<!-- [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: #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 14px 28px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.95rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-btn:hover {<!-- [et_pb_line_break_holder] -->  transform: translateY(-5px) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-prereq .gpn-pr-cta-btn svg {<!-- [et_pb_line_break_holder] -->  width: 14px !important;<!-- [et_pb_line_break_holder] -->  height: 14px !important;<!-- [et_pb_line_break_holder] -->  stroke: currentColor !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-intro { font-size: 16px !important; margin-bottom: 32px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-strip {<!-- [et_pb_line_break_holder] -->    flex-direction: column !important;<!-- [et_pb_line_break_holder] -->    align-items: stretch !important;<!-- [et_pb_line_break_holder] -->    text-align: left !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq {<!-- [et_pb_line_break_holder] -->    padding: 40px 16px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq h2 { font-size: 24px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-intro { font-size: 15px !important; line-height: 1.7 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-item {<!-- [et_pb_line_break_holder] -->    padding: 20px 18px !important;<!-- [et_pb_line_break_holder] -->    gap: 14px !important;<!-- [et_pb_line_break_holder] -->    border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-item-num {<!-- [et_pb_line_break_holder] -->    width: 32px !important;<!-- [et_pb_line_break_holder] -->    height: 32px !important;<!-- [et_pb_line_break_holder] -->    min-width: 32px !important;<!-- [et_pb_line_break_holder] -->    font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-item-title { font-size: 14.5px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-item-text { font-size: 13.5px !important; line-height: 1.7 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-alert {<!-- [et_pb_line_break_holder] -->    padding: 18px !important;<!-- [et_pb_line_break_holder] -->    gap: 12px !important;<!-- [et_pb_line_break_holder] -->    border-radius: 10px !important;<!-- [et_pb_line_break_holder] -->    margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-alert-text { font-size: 13.5px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-strip {<!-- [et_pb_line_break_holder] -->    padding: 24px 20px !important;<!-- [et_pb_line_break_holder] -->    border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-text { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-sub { font-size: 13.5px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-btn {<!-- [et_pb_line_break_holder] -->    width: 100% !important;<!-- [et_pb_line_break_holder] -->    justify-content: center !important;<!-- [et_pb_line_break_holder] -->    white-space: normal !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 400px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq h2 { font-size: 22px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-item { padding: 18px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-prereq .gpn-pr-cta-strip { padding: 22px 18px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-prereq\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-prerequisites\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-pr-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-pr-badge\"><span class=\"gpn-pr-badge-dot\"><\/span><span>Setup<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Prerequisites: GCP project, Pub\/Sub topic, IAM grant<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-pr-intro\">Gmail API push notifications require three GCP-side resources before your first <code>users.watch<\/code> call. Most implementation failures trace back to a missing IAM grant on the Pub\/Sub topic, the step developers most frequently skip.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-pr-list\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-pr-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-num\">1<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-body\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-pr-item-title\">GCP project with Gmail API enabled<\/div><!-- [et_pb_line_break_holder] -->          <pee class=\"gpn-pr-item-text\">In the Google Cloud Console, create or select an existing project. Navigate to <strong>APIs and Services > Library<\/strong> and enable the <strong>Gmail API<\/strong>. You also need the <strong>Cloud Pub\/Sub API<\/strong> enabled in the same project. Ensure your OAuth 2.0 client credentials include the <code>https:\/\/www.googleapis.com\/auth\/gmail.readonly<\/code> scope (or a broader scope if you need write access). For multi-user applications, see our guide on <a href=\"https:\/\/www.unipile.com\/gmail-oauth-20-integration-complete-guide\/\">Gmail OAuth 2.0 integration<\/a> and the <a href=\"https:\/\/www.unipile.com\/google-oauth-app-verification-complete-guide\/\">Google OAuth app verification<\/a> requirements.<\/pee><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-pr-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-num\">2<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-body\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-pr-item-title\">Create a Cloud Pub\/Sub topic<\/div><!-- [et_pb_line_break_holder] -->          <pee class=\"gpn-pr-item-text\">In the GCP Console under <strong>Pub\/Sub > Topics<\/strong>, click <strong>Create Topic<\/strong>. Give it a name like <code>gmail-notifications<\/code>. The full topic name will be <code>projects\/YOUR_PROJECT_ID\/topics\/gmail-notifications<\/code>. You will pass this exact string to <code>users.watch<\/code> in the <code>topicName<\/code> field.<\/pee><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-pr-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-num\">3<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-body\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-pr-item-title\">Grant Publisher role to gmail-api-push@system.gserviceaccount.com<\/div><!-- [et_pb_line_break_holder] -->          <pee class=\"gpn-pr-item-text\">This is the step most developers miss. Gmail uses a Google-managed service account (<code>gmail-api-push@system.gserviceaccount.com<\/code>) to publish notifications to your Pub\/Sub topic. Without granting this account the <strong>Pub\/Sub Publisher<\/strong> role on your topic, <code>users.watch<\/code> will succeed but no notifications will ever be delivered. In the Console: Topics > select your topic > Permissions > Add principal > enter <code>gmail-api-push@system.gserviceaccount.com<\/code> > assign role <strong>Pub\/Sub Publisher<\/strong>.<\/pee><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-pr-item\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-num\">4<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-item-body\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-pr-item-title\">Create a Push subscription pointing to your webhook<\/div><!-- [et_pb_line_break_holder] -->          <pee class=\"gpn-pr-item-text\">Under your Pub\/Sub topic, create a <strong>Push subscription<\/strong>. Set the push endpoint to your HTTPS webhook URL (must use a valid TLS certificate, self-signed certs are rejected). Optionally configure a token validation header so your endpoint can verify requests come from Google. Note the subscription name, you may need it to monitor delivery metrics in Cloud Monitoring.<\/pee><!-- [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=\"gpn-pr-alert\"><!-- [et_pb_line_break_holder] -->      <svg class=\"gpn-pr-alert-icon\" 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><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-pr-alert-text\"><strong>100-user cap on unverified apps:<\/strong> If your OAuth consent screen is in \"Testing\" status, only 100 Gmail accounts can authorize your app. This cap applies to <em>all<\/em> OAuth scopes, including the watch endpoint. For production deployments with more than 100 users, you must complete Google's verification process. See our full guide on the <a href=\"https:\/\/www.unipile.com\/google-oauth-app-verification-complete-guide\/\">100-user limit and verification path<\/a>.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-pr-cta-strip\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-pr-cta-body\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-pr-cta-text\">Skip GCP setup entirely<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-pr-cta-sub\">No Pub\/Sub topic. No IAM grant. No 7-day watch renewal cron. Build Gmail push notifications with one webhook URL.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-pr-cta-btn\" href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" rel=\"noopener\"><!-- [et_pb_line_break_holder] -->        <span>Build Now<\/span><!-- [et_pb_line_break_holder] -->        <svg viewBox=\"0 0 24 24\"><polyline points=\"9 18 15 12 9 6\"><\/polyline><\/svg><!-- [et_pb_line_break_holder] -->      <\/a><!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-setup,<!-- [et_pb_line_break_holder] -->#upl-gpn-setup *,<!-- [et_pb_line_break_holder] -->#upl-gpn-setup *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-setup *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-badge {<!-- [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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  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] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-tabs {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 0 !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-tab {<!-- [et_pb_line_break_holder] -->  padding: 8px 18px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px 8px 0 0 !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->  background: #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  transition: all 0.2s ease !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-tab.active {<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  color: #e6edf3 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-code-panel {<!-- [et_pb_line_break_holder] -->  display: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-code-panel.active {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Code editor *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 0 14px 14px 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 24px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-setup .gpn-su-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-pre {<!-- [et_pb_line_break_holder] -->  padding: 22px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .gpn-su-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-setup .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-setup { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-setup 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-gpn-setup { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-setup h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-setup .gpn-su-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-setup .gpn-su-pre { font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-setup\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-setup\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-su-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-su-badge\"><span class=\"gpn-su-badge-dot\"><\/span><span>Step by Step<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Step-by-step: create topic, subscription, and users.watch<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-su-intro\">With GCP prerequisites in place, here is the complete code to register a Gmail API watch endpoint in both Node.js and Python, using the Google API client library.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-su-tabs\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-su-tab active\" data-target=\"su-node\">Node.js<\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-su-tab\" data-target=\"su-python\">Python<\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div id=\"su-node\" class=\"gpn-su-code-panel active\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-su-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-su-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-su-dot gpn-su-dot-r\"><\/span><span class=\"gpn-su-dot gpn-su-dot-y\"><\/span><span class=\"gpn-su-dot gpn-su-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-su-filename\">watch.js<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-su-pre\"><code><span class=\"k\">const<\/span> <span class=\"w\">{ google } =<\/span> <span class=\"fn\">require<\/span><span class=\"w\">(<\/span><span class=\"s\">'googleapis'<\/span><span class=\"w\">);<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ Assumes OAuth2 client is already authorized with a valid access token<\/span><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ See: https:\/\/www.unipile.com\/gmail-oauth-20-integration-complete-guide\/<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">async function<\/span> <span class=\"fn\">registerGmailWatch<\/span><span class=\"w\">(auth, userId = <\/span><span class=\"s\">'me'<\/span><span class=\"w\">) {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">gmail =<\/span> <span class=\"fn\">google<\/span><span class=\"w\">.<\/span><span class=\"fn\">gmail<\/span><span class=\"w\">({ version:<\/span> <span class=\"s\">'v1'<\/span><span class=\"w\">, auth });<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">response =<\/span> <span class=\"k\">await<\/span> <span class=\"w\">gmail.users.<\/span><span class=\"fn\">watch<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">userId,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">requestBody: {<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Your full Pub\/Sub topic name<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">topicName:<\/span> <span class=\"s\">'projects\/YOUR_PROJECT_ID\/topics\/gmail-notifications'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Optional: filter to specific labels only<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">labelIds: [<\/span><span class=\"s\">'INBOX'<\/span><span class=\"w\">],<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">labelFilterBehavior:<\/span> <span class=\"s\">'INCLUDE'<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">{ historyId, expiration } = response.data;<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ Store these per-user in your database<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">upsert<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">userId,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">lastHistoryId: historyId,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ expiration is Unix ms timestamp<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">watchExpiry:<\/span> <span class=\"k\">new<\/span> <span class=\"fn\">Date<\/span><span class=\"w\">(<\/span><span class=\"fn\">parseInt<\/span><span class=\"w\">(expiration))<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"w\">console.<\/span><span class=\"fn\">log<\/span><span class=\"w\">(<\/span><span class=\"s\">`Watch registered. historyId: ${historyId}, expires: ${expiration}`<\/span><span class=\"w\">);<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">return<\/span> <span class=\"w\">response.data;<\/span><!-- [et_pb_line_break_holder] --><span class=\"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] -->    <div id=\"su-python\" class=\"gpn-su-code-panel\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-su-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-su-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-su-dot gpn-su-dot-r\"><\/span><span class=\"gpn-su-dot gpn-su-dot-y\"><\/span><span class=\"gpn-su-dot gpn-su-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-su-filename\">watch.py<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-su-pre\"><code><span class=\"k\">from<\/span> <span class=\"w\">googleapiclient.discovery<\/span> <span class=\"k\">import<\/span> <span class=\"fn\">build<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">from<\/span> <span class=\"w\">google.oauth2.credentials<\/span> <span class=\"k\">import<\/span> <span class=\"fn\">Credentials<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"k\">def<\/span> <span class=\"fn\">register_gmail_watch<\/span><span class=\"w\">(credentials: Credentials, user_id:<\/span> <span class=\"fn\">str<\/span> <span class=\"w\">= <\/span><span class=\"s\">'me'<\/span><span class=\"w\">) -> dict:<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\"\"\"Register Gmail API push notifications watch for an authenticated user.\"\"\"<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">service =<\/span> <span class=\"fn\">build<\/span><span class=\"w\">(<\/span><span class=\"s\">'gmail'<\/span><span class=\"w\">,<\/span> <span class=\"s\">'v1'<\/span><span class=\"w\">, credentials=credentials)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"w\">body = {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"s\">'topicName'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'projects\/YOUR_PROJECT_ID\/topics\/gmail-notifications'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"s\">'labelIds'<\/span><span class=\"w\">: [<\/span><span class=\"s\">'INBOX'<\/span><span class=\"w\">],<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"s\">'labelFilterBehavior'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'INCLUDE'<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"w\">result = service.users().<\/span><span class=\"fn\">watch<\/span><span class=\"w\">(userId=user_id, body=body).<\/span><span class=\"fn\">execute<\/span><span class=\"w\">()<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"c\"># Store per-user in your database<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"fn\">db_upsert<\/span><span class=\"w\">(user_id=user_id,<\/span><!-- [et_pb_line_break_holder] -->              <span class=\"w\">last_history_id=result[<\/span><span class=\"s\">'historyId'<\/span><span class=\"w\">],<\/span><!-- [et_pb_line_break_holder] -->              <span class=\"w\">watch_expiry=<\/span><span class=\"fn\">int<\/span><span class=\"w\">(result[<\/span><span class=\"s\">'expiration'<\/span><span class=\"w\">]) \/\/ 1000)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"k\">return<\/span> <span class=\"w\">result<\/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_line_break_holder] --><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function(){<!-- [et_pb_line_break_holder] -->  var container = document.getElementById('upl-gpn-setup');<!-- [et_pb_line_break_holder] -->  if (!container) return;<!-- [et_pb_line_break_holder] -->  var tabs = container.querySelectorAll('.gpn-su-tab');<!-- [et_pb_line_break_holder] -->  tabs.forEach(function(tab){<!-- [et_pb_line_break_holder] -->    tab.addEventListener('click', function(){<!-- [et_pb_line_break_holder] -->      var target = tab.getAttribute('data-target');<!-- [et_pb_line_break_holder] -->      tabs.forEach(function(t){ t.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->      tab.classList.add('active');<!-- [et_pb_line_break_holder] -->      container.querySelectorAll('.gpn-su-code-panel').forEach(function(p){ p.classList.remove('active'); });<!-- [et_pb_line_break_holder] -->      var panel = document.getElementById(target);<!-- [et_pb_line_break_holder] -->      if (panel) panel.classList.add('active');<!-- [et_pb_line_break_holder] -->    });<!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-webhook,<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook *,<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-layout {<!-- [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: 24px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-webhook .gpn-wh-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-pre {<!-- [et_pb_line_break_holder] -->  padding: 20px 22px !important;<!-- [et_pb_line_break_holder] -->  font-size: 12.5px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-webhook .gpn-wh-payload-label {<!-- [et_pb_line_break_holder] -->  font-size: 11px !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.8px !important;<!-- [et_pb_line_break_holder] -->  color: #94a3b8 !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 16px 22px 0 22px !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook .gpn-wh-layout { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook .gpn-wh-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-webhook .gpn-wh-pre { font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-webhook\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-webhook-payload\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-wh-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-wh-badge\"><span class=\"gpn-wh-badge-dot\"><\/span><span>Implementation<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Handling the Gmail API push notifications webhook payload<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-wh-intro\">When Gmail fires a push notification, your HTTPS endpoint receives a Pub\/Sub push message. The actual Gmail change data is double-encoded: the Pub\/Sub envelope contains a base64-encoded JSON string that itself contains the user email and historyId.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-wh-layout\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-wh-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-wh-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-wh-dot gpn-wh-dot-r\"><\/span><span class=\"gpn-wh-dot gpn-wh-dot-y\"><\/span><span class=\"gpn-wh-dot gpn-wh-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-wh-filename\">webhook.js (Express)<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-wh-payload-label\">Node.js - Express handler<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-wh-pre\"><code><span class=\"w\">app.<\/span><span class=\"fn\">post<\/span><span class=\"w\">(<\/span><span class=\"s\">'\/webhooks\/gmail'<\/span><span class=\"w\">, async (req, res) => {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ Acknowledge immediately : Pub\/Sub retries on non-2xx<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">res.<\/span><span class=\"fn\">status<\/span><span class=\"w\">(<\/span><span class=\"n\">200<\/span><span class=\"w\">).<\/span><span class=\"fn\">end<\/span><span class=\"w\">();<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"k\">try<\/span> <span class=\"w\">{<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">message = req.body.message;<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">if<\/span> <span class=\"w\">(!message?.data) return;<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ Decode the base64 Pub\/Sub data field<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">decoded =<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"fn\">Buffer<\/span><span class=\"w\">.<\/span><span class=\"fn\">from<\/span><span class=\"w\">(message.data,<\/span> <span class=\"s\">'base64'<\/span><span class=\"w\">).<\/span><span class=\"fn\">toString<\/span><span class=\"w\">(<\/span><span class=\"s\">'utf-8'<\/span><span class=\"w\">);<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">payload =<\/span> <span class=\"fn\">JSON<\/span><span class=\"w\">.<\/span><span class=\"fn\">parse<\/span><span class=\"w\">(decoded);<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ payload = { emailAddress: \"user@gmail.com\", historyId: \"12345\" }<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">{ emailAddress, historyId } = payload;<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ Queue reconciliation (don't block the ack)<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">await<\/span> <span class=\"fn\">queue<\/span><span class=\"w\">.<\/span><span class=\"fn\">enqueue<\/span><span class=\"w\">({ emailAddress, historyId });<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">} catch (err) {<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ Log but don't re-throw : ack was already sent<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">console.<\/span><span class=\"fn\">error<\/span><span class=\"w\">(<\/span><span class=\"s\">'Webhook parse error'<\/span><span class=\"w\">, err);<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-wh-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-wh-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-wh-dot gpn-wh-dot-r\"><\/span><span class=\"gpn-wh-dot gpn-wh-dot-y\"><\/span><span class=\"gpn-wh-dot gpn-wh-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-wh-filename\">webhook.py (Flask)<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-wh-payload-label\">Python - Flask handler<\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-wh-pre\"><code><span class=\"k\">import<\/span> <span class=\"w\">base64, json<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">from<\/span> <span class=\"w\">flask<\/span> <span class=\"k\">import<\/span> <span class=\"fn\">Flask, request, jsonify<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"w\">app =<\/span> <span class=\"fn\">Flask<\/span><span class=\"w\">(__name__)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"w\">@app.<\/span><span class=\"fn\">route<\/span><span class=\"w\">(<\/span><span class=\"s\">'\/webhooks\/gmail'<\/span><span class=\"w\">, methods=[<\/span><span class=\"s\">'POST'<\/span><span class=\"w\">])<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">def<\/span> <span class=\"fn\">gmail_webhook<\/span><span class=\"w\">():<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"c\"># Acknowledge immediately<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">data = request.<\/span><span class=\"fn\">get_json<\/span><span class=\"w\">(silent=True) or {}<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">message = data.<\/span><span class=\"fn\">get<\/span><span class=\"w\">(<\/span><span class=\"s\">'message'<\/span><span class=\"w\">, {})<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"k\">if<\/span> <span class=\"s\">'data'<\/span> <span class=\"k\">in<\/span> <span class=\"w\">message:<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"c\"># Decode base64 and parse JSON<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">raw = base64.<\/span><span class=\"fn\">b64decode<\/span><span class=\"w\">(message[<\/span><span class=\"s\">'data'<\/span><span class=\"w\">] +<\/span> <span class=\"s\">'=='<\/span><span class=\"w\">)<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">payload =<\/span> <span class=\"fn\">json<\/span><span class=\"w\">.<\/span><span class=\"fn\">loads<\/span><span class=\"w\">(raw)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <span class=\"c\"># { \"emailAddress\": \"user@gmail.com\", \"historyId\": \"12345\" }<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">email = payload.<\/span><span class=\"fn\">get<\/span><span class=\"w\">(<\/span><span class=\"s\">'emailAddress'<\/span><span class=\"w\">)<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">history_id = payload.<\/span><span class=\"fn\">get<\/span><span class=\"w\">(<\/span><span class=\"s\">'historyId'<\/span><span class=\"w\">)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <span class=\"c\"># Enqueue async reconciliation<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"fn\">enqueue_reconcile<\/span><span class=\"w\">(email, history_id)<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"k\">return<\/span> <span class=\"fn\">jsonify<\/span><span class=\"w\">({}),<\/span> <span class=\"n\">200<\/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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-history,<!-- [et_pb_line_break_holder] -->#upl-gpn-history *,<!-- [et_pb_line_break_holder] -->#upl-gpn-history *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-history *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-badge {<!-- [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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  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] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-history .gpn-hi-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-pre {<!-- [et_pb_line_break_holder] -->  padding: 22px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-rules {<!-- [et_pb_line_break_holder] -->  display: grid !important;<!-- [et_pb_line_break_holder] -->  grid-template-columns: repeat(2, 1fr) !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-rule {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-rule-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-rule-title svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-history .gpn-hi-rule-text {<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.7 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-history { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-history h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-history .gpn-hi-rules { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-history { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-history h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-history .gpn-hi-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-history .gpn-hi-pre { font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-history\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-history-reconcile\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-hi-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-hi-badge\"><span class=\"gpn-hi-badge-dot\"><\/span><span>Reconciliation<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Reconciling changes with users.history.list<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-hi-intro\">The Pub\/Sub notification only tells you <em>something changed<\/em>. It does not tell you what. You must call <code style=\"background:rgba(221,223,76,0.18)!important;padding:2px 6px!important;border-radius:4px!important;font-family:'Courier New',monospace!important;font-size:0.85em!important;color:#8a8c2e!important;\">users.history.list<\/code> with your stored <code style=\"background:rgba(221,223,76,0.18)!important;padding:2px 6px!important;border-radius:4px!important;font-family:'Courier New',monospace!important;font-size:0.85em!important;color:#8a8c2e!important;\">lastHistoryId<\/code> as the cursor to get the actual delta.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-hi-code-wrap\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-editor-bar\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-hi-dot gpn-hi-dot-r\"><\/span><span class=\"gpn-hi-dot gpn-hi-dot-y\"><\/span><span class=\"gpn-hi-dot gpn-hi-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-hi-filename\">reconcile.js<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-pre\"><code><span class=\"k\">async function<\/span> <span class=\"fn\">reconcileHistory<\/span><span class=\"w\">(auth, emailAddress, newHistoryId) {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">gmail =<\/span> <span class=\"fn\">google<\/span><span class=\"w\">.<\/span><span class=\"fn\">gmail<\/span><span class=\"w\">({ version:<\/span> <span class=\"s\">'v1'<\/span><span class=\"w\">, auth });<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ Retrieve our stored lastHistoryId for this user<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">user =<\/span> <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">findByEmail<\/span><span class=\"w\">(emailAddress);<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">startHistoryId = user.lastHistoryId;<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"k\">try<\/span> <span class=\"w\">{<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">response =<\/span> <span class=\"k\">await<\/span> <span class=\"w\">gmail.users.history.<\/span><span class=\"fn\">list<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">userId:<\/span> <span class=\"s\">'me'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Use the STORED ID as cursor : NOT the new notification historyId<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">startHistoryId,<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Filter to message additions only (optional)<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">historyTypes: [<\/span><span class=\"s\">'messageAdded'<\/span><span class=\"w\">]<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"k\">const<\/span> <span class=\"w\">histories = response.data.history || [];<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"k\">for<\/span> <span class=\"w\">(<\/span><span class=\"k\">const<\/span> <span class=\"w\">record of histories) {<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">for<\/span> <span class=\"w\">(<\/span><span class=\"k\">const<\/span> <span class=\"w\">added of (record.messagesAdded || [])) {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"c\">\/\/ added.message = { id, threadId, labelIds }<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"k\">await<\/span> <span class=\"fn\">processNewMessage<\/span><span class=\"w\">(auth, added.message.id);<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"c\">\/\/ Update cursor to the new historyId from the notification<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">updateLastHistoryId<\/span><span class=\"w\">(emailAddress, newHistoryId);<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"w\">} catch (err) {<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">if<\/span> <span class=\"w\">(err.code ===<\/span> <span class=\"n\">404<\/span><span class=\"w\">) {<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ historyId is too old (> 7 days). Re-initialize from messages.list<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">await<\/span> <span class=\"fn\">reinitializeFromMessages<\/span><span class=\"w\">(auth, emailAddress);<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">} else {<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">throw<\/span> <span class=\"w\">err;<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">}<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-hi-rules\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-rule\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-hi-rule-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#3BB98B\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><span>Always use stored cursor, not notification historyId<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-hi-rule-text\">The historyId in the Pub\/Sub notification is the <em>current<\/em> state. Your <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">startHistoryId<\/code> must be the <em>previous<\/em> value you stored. Using the notification historyId directly as startHistoryId means you will miss all the changes between your last processed point and now.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-rule\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-hi-rule-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#3BB98B\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><span>Handle duplicate notifications idempotently<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-hi-rule-text\">Pub\/Sub may deliver the same notification more than once. Your reconciliation logic must be idempotent: processing the same message ID twice should be a no-op. Use a unique constraint on message IDs in your database, or check for existence before inserting.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-rule\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-hi-rule-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#ff7b72\"><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><circle cx=\"12\" cy=\"12\" r=\"10\"\/><\/svg><span>Handle 404 historyId too old<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-hi-rule-text\">If you pass a startHistoryId older than 7 days, the API returns a 404. In this case, fall back to <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">messages.list<\/code> to re-sync from scratch, then call <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">users.watch<\/code> again to get a fresh historyId baseline.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-hi-rule\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-hi-rule-title\"><svg viewBox=\"0 0 24 24\" stroke=\"#3BB98B\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><span>Paginate history.list results<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-hi-rule-text\">If many changes occurred between your last historyId and now, the history.list response may be paginated. Always follow <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">nextPageToken<\/code> until exhausted before updating your stored cursor.<\/pee><!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-renewal,<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal *,<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-renewal .gpn-rn-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-pre {<!-- [et_pb_line_break_holder] -->  padding: 22px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-callout {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.08) !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid rgba(59, 185, 139, 0.3) !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px 24px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->  align-items: flex-start !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-callout-icon {<!-- [et_pb_line_break_holder] -->  width: 22px !important;<!-- [et_pb_line_break_holder] -->  height: 22px !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  margin-top: 1px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-callout-text {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-strip {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 32px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: space-between !important;<!-- [et_pb_line_break_holder] -->  gap: 24px !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-text {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 18px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-sub {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  color: rgba(255,255,255,0.7) !important;<!-- [et_pb_line_break_holder] -->  margin-top: 6px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-btn {<!-- [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: #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 14px 28px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.95rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-btn:hover { transform: translateY(-5px) !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-renewal .gpn-rn-cta-btn svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  stroke: currentColor !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal .gpn-rn-cta-strip { 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-gpn-renewal { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal .gpn-rn-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal .gpn-rn-pre { font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-renewal .gpn-rn-cta-btn { width: 100% !important; justify-content: center !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-renewal\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-renewal\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-rn-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rn-badge\"><span class=\"gpn-rn-badge-dot\"><\/span><span>Operations<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Watch renewal strategy: the 7-day expiration problem<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-rn-intro\">A Gmail API watch expires silently after 7 days. There is no automatic renewal and no warning notification. If your cron fails, new emails arrive but your application receives nothing - with no errors on either end. This makes renewal the most operationally critical part of any Gmail push notifications implementation.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rn-callout\"><!-- [et_pb_line_break_holder] -->      <svg class=\"gpn-rn-callout-icon\" viewBox=\"0 0 24 24\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"\/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"\/><\/svg><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-rn-callout-text\"><strong>Renew daily, not every 7 days.<\/strong> Run your renewal cron every 24 hours (not every 6 or 7 days). Watch renewal is idempotent - calling <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">users.watch<\/code> again simply resets the 7-day timer. A daily cadence gives you a 6-day safety buffer against transient failures.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rn-code-wrap\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-rn-editor-bar\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rn-dot gpn-rn-dot-r\"><\/span><span class=\"gpn-rn-dot gpn-rn-dot-y\"><\/span><span class=\"gpn-rn-dot gpn-rn-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rn-filename\">renew-watches.js<\/span><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-rn-pre\"><code><span class=\"c\">\/\/ Daily cron: 0 3 * * * (runs at 3am daily)<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">async function<\/span> <span class=\"fn\">renewAllWatches<\/span><span class=\"w\">() {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ Get all authenticated users from your database<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">users =<\/span> <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">getAllActiveUsers<\/span><span class=\"w\">();<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"k\">for<\/span> <span class=\"w\">(<\/span><span class=\"k\">const<\/span> <span class=\"w\">user of users) {<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"k\">try<\/span> <span class=\"w\">{<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Refresh the access token if needed<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">const<\/span> <span class=\"w\">auth =<\/span> <span class=\"k\">await<\/span> <span class=\"fn\">getAuthClient<\/span><span class=\"w\">(user.id);<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">const<\/span> <span class=\"w\">gmail =<\/span> <span class=\"fn\">google<\/span><span class=\"w\">.<\/span><span class=\"fn\">gmail<\/span><span class=\"w\">({ version:<\/span> <span class=\"s\">'v1'<\/span><span class=\"w\">, auth });<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <span class=\"k\">const<\/span> <span class=\"w\">res =<\/span> <span class=\"k\">await<\/span> <span class=\"w\">gmail.users.<\/span><span class=\"fn\">watch<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">userId:<\/span> <span class=\"s\">'me'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">requestBody: {<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"w\">topicName:<\/span> <span class=\"s\">'projects\/YOUR_PROJECT_ID\/topics\/gmail-notifications'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"w\">labelIds: [<\/span><span class=\"s\">'INBOX'<\/span><span class=\"w\">]<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <span class=\"c\">\/\/ Update historyId baseline : new watch returns a fresh historyId<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">update<\/span><span class=\"w\">(user.id, {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">lastHistoryId: res.data.historyId,<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">watchExpiry:<\/span> <span class=\"k\">new<\/span> <span class=\"fn\">Date<\/span><span class=\"w\">(<\/span><span class=\"fn\">parseInt<\/span><span class=\"w\">(res.data.expiration))<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <span class=\"w\">} catch (err) {<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"k\">if<\/span> <span class=\"w\">(err.code ===<\/span> <span class=\"n\">401<\/span><span class=\"w\">) {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"c\">\/\/ Refresh token revoked : user needs to re-authorize<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"k\">await<\/span> <span class=\"fn\">db<\/span><span class=\"w\">.<\/span><span class=\"fn\">markUserDisconnected<\/span><span class=\"w\">(user.id);<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">} else if (err.code ===<\/span> <span class=\"n\">404<\/span><span class=\"w\">) {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"c\">\/\/ Watch expired : call watch again (already doing this, so 404 = retry next run)<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">console.<\/span><span class=\"fn\">warn<\/span><span class=\"w\">(<\/span><span class=\"s\">`Watch already expired for ${user.email}, will retry`<\/span><span class=\"w\">);<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">} else {<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"c\">\/\/ Log and continue : don't abort the entire cron for one user<\/span><!-- [et_pb_line_break_holder] -->        <span class=\"w\">console.<\/span><span class=\"fn\">error<\/span><span class=\"w\">(<\/span><span class=\"s\">`Watch renewal failed for ${user.email}`<\/span><span class=\"w\">, err);<\/span><!-- [et_pb_line_break_holder] -->      <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">}<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">}<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rn-cta-strip\"><!-- [et_pb_line_break_holder] -->      <div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rn-cta-text\">Build real-time Gmail sync with one webhook<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-rn-cta-sub\">Unipile handles watch renewal automatically on behalf of each authenticated user. No cron job needed.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rn-cta-btn\" href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" rel=\"noopener\"><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><span>Build it with Unipile<\/span><\/a><!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-trouble,<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble *,<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-badge {<!-- [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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  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] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Table *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-table-wrap {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble table {<!-- [et_pb_line_break_holder] -->  width: 100% !important;<!-- [et_pb_line_break_holder] -->  border-collapse: collapse !important;<!-- [et_pb_line_break_holder] -->  min-width: 600px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble thead tr {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble th {<!-- [et_pb_line_break_holder] -->  padding: 14px 20px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 12px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  text-align: left !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] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble tbody tr {<!-- [et_pb_line_break_holder] -->  border-bottom: 1px solid #f0f2f5 !important;<!-- [et_pb_line_break_holder] -->  transition: background 0.15s ease !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble tbody tr:last-child {<!-- [et_pb_line_break_holder] -->  border-bottom: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble tbody tr:hover {<!-- [et_pb_line_break_holder] -->  background: #f8fafc !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble td {<!-- [et_pb_line_break_holder] -->  padding: 16px 20px !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.65 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  vertical-align: top !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-error-code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  background: rgba(0,0,0,0.05) !important;<!-- [et_pb_line_break_holder] -->  padding: 3px 8px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-chip-red {<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  background: rgba(239, 68, 68, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #dc2626 !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 8px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !important;<!-- [et_pb_line_break_holder] -->  font-size: 11px !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.3px !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-trouble .gpn-tr-chip-yellow {<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  background: rgba(234, 179, 8, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #a16207 !important;<!-- [et_pb_line_break_holder] -->  padding: 2px 8px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 4px !important;<!-- [et_pb_line_break_holder] -->  font-size: 11px !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.3px !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* Mobile cards *\/<!-- [et_pb_line_break_holder] -->@media (max-width: 768px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble { padding: 50px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-table-wrap { border-radius: 12px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble table { display: none !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-cards { display: flex !important; flex-direction: column !important; gap: 14px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-card {<!-- [et_pb_line_break_holder] -->    background: #ffffff !important;<!-- [et_pb_line_break_holder] -->    border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->    border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->    padding: 18px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-card-error {<!-- [et_pb_line_break_holder] -->    font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->    font-size: 14px !important;<!-- [et_pb_line_break_holder] -->    font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->    color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->    margin-bottom: 6px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-card-cause {<!-- [et_pb_line_break_holder] -->    font-size: 12px !important;<!-- [et_pb_line_break_holder] -->    color: #64748b !important;<!-- [et_pb_line_break_holder] -->    margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->    line-height: 1.6 !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-card-fix {<!-- [et_pb_line_break_holder] -->    font-size: 13px !important;<!-- [et_pb_line_break_holder] -->    color: #383838 !important;<!-- [et_pb_line_break_holder] -->    line-height: 1.65 !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (min-width: 769px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble .gpn-tr-cards { display: none !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-trouble h2 { font-size: 24px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-trouble\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-troubleshooting\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-tr-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-tr-badge\"><span class=\"gpn-tr-badge-dot\"><\/span><span>Troubleshooting<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Troubleshooting Gmail API push notifications<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-tr-intro\">These are the four error classes that account for nearly all Gmail push notifications failures. Most have a single root cause once you know what to look for.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-tr-table-wrap\"><!-- [et_pb_line_break_holder] -->      <table><!-- [et_pb_line_break_holder] -->        <thead><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <th>Error \/ Symptom<\/th><!-- [et_pb_line_break_holder] -->            <th>Root Cause<\/th><!-- [et_pb_line_break_holder] -->            <th>Fix<\/th><!-- [et_pb_line_break_holder] -->            <th>Severity<\/th><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->        <\/thead><!-- [et_pb_line_break_holder] -->        <tbody><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-error-code\">403<\/span> on users.watch<\/td><!-- [et_pb_line_break_holder] -->            <td>Gmail service account <code style=\"font-family:monospace!important;background:rgba(0,0,0,0.05)!important;padding:2px 5px!important;border-radius:3px!important;font-size:0.85em!important;\">gmail-api-push@system.gserviceaccount.com<\/code> was not granted Pub\/Sub Publisher role on the topic.<\/td><!-- [et_pb_line_break_holder] -->            <td>In GCP Console: Pub\/Sub > Topics > your topic > Permissions. Add the service account with the Pub\/Sub Publisher role.<\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-chip-red\">Blocker<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td>watch succeeds but no notifications received<\/td><!-- [et_pb_line_break_holder] -->            <td>Pub\/Sub subscription push endpoint URL is not registered, rejected by Google (invalid TLS), or push subscription type is \"Pull\" instead of \"Push\".<\/td><!-- [et_pb_line_break_holder] -->            <td>Verify your subscription is type \"Push\" with your webhook URL as the endpoint. Ensure TLS certificate is valid (not self-signed). Test endpoint returns 200.<\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-chip-red\">Blocker<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-error-code\">404<\/span> on history.list - historyId too old<\/td><!-- [et_pb_line_break_holder] -->            <td>Your stored <code style=\"font-family:monospace!important;background:rgba(0,0,0,0.05)!important;padding:2px 5px!important;border-radius:3px!important;font-size:0.85em!important;\">lastHistoryId<\/code> is older than 7 days. Gmail only retains history for 7 days.<\/td><!-- [et_pb_line_break_holder] -->            <td>Fall back to <code style=\"font-family:monospace!important;background:rgba(0,0,0,0.05)!important;padding:2px 5px!important;border-radius:3px!important;font-size:0.85em!important;\">messages.list<\/code> to resync. Then call <code style=\"font-family:monospace!important;background:rgba(0,0,0,0.05)!important;padding:2px 5px!important;border-radius:3px!important;font-size:0.85em!important;\">users.watch<\/code> for a fresh historyId baseline.<\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-chip-yellow\">Recoverable<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td>Push endpoint validation token rejected<\/td><!-- [et_pb_line_break_holder] -->            <td>Google sends an X-Goog-Channel-Token header. If your endpoint validates it and the token doesn't match, it returns non-2xx and Pub\/Sub retries indefinitely.<\/td><!-- [et_pb_line_break_holder] -->            <td>Either disable token validation during initial setup, or configure the same token value in both the GCP subscription settings and your application config.<\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-tr-chip-yellow\">Recoverable<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->        <\/tbody><!-- [et_pb_line_break_holder] -->      <\/table><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <!-- Mobile cards version --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-tr-cards\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-tr-card\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-error\"><span class=\"gpn-tr-error-code\">403<\/span> on users.watch<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-cause\">Missing IAM: <code style=\"font-family:monospace!important;background:rgba(0,0,0,0.05)!important;padding:1px 4px!important;border-radius:3px!important;font-size:0.85em!important;\">gmail-api-push@system.gserviceaccount.com<\/code> not granted Pub\/Sub Publisher.<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-fix\">Add service account as Publisher in GCP Console > Pub\/Sub > Topics > Permissions.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-tr-card\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-error\">watch succeeds but no notifications<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-cause\">Subscription is Pull type, or push endpoint URL invalid\/TLS rejected.<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-fix\">Set subscription to Push type. Ensure HTTPS endpoint with valid TLS. Verify 200 response.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-tr-card\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-error\"><span class=\"gpn-tr-error-code\">404<\/span> historyId too old<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-cause\">Stored cursor is older than 7 days.<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-fix\">Resync via messages.list, then re-register watch for fresh historyId.<\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-tr-card\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-error\">Validation token rejected<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-cause\">Token mismatch between Pub\/Sub subscription config and app config.<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-tr-card-fix\">Match token values in both GCP subscription settings and application 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_line_break_holder] --><\/div>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-quotas,<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas *,<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !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-gpn-quotas .gpn-qt-quota-row {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px 24px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [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] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-quota-num {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 22px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  min-width: 120px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-quota-label {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.65 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-note {<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 60px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.7 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Trade-offs section *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-h2-2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-badge-2 {<!-- [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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-badge-2-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  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] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-intro-2 {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Comparison table *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-table-wrap {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas table {<!-- [et_pb_line_break_holder] -->  width: 100% !important;<!-- [et_pb_line_break_holder] -->  border-collapse: collapse !important;<!-- [et_pb_line_break_holder] -->  min-width: 560px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas thead tr {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas th {<!-- [et_pb_line_break_holder] -->  padding: 14px 18px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 12px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  text-align: left !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] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas tbody tr {<!-- [et_pb_line_break_holder] -->  border-bottom: 1px solid #f0f2f5 !important;<!-- [et_pb_line_break_holder] -->  transition: background 0.15s ease !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas tbody tr:last-child { border-bottom: none !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas tbody tr:hover { background: #f8fafc !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas td {<!-- [et_pb_line_break_holder] -->  padding: 14px 18px !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.6 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  vertical-align: top !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-td-method {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-td-latency { color: #2aaa7e !important; font-weight: 600 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-td-bad { color: #dc2626 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-td-good { color: #2aaa7e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-quotas .gpn-qt-td-medium { color: #a16207 !important; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* Mobile cards for table *\/<!-- [et_pb_line_break_holder] -->@media (max-width: 768px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas table { display: none !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mobile-cards { display: flex !important; flex-direction: column !important; gap: 12px !important; padding: 16px !important; background: #ffffff !important; border: 1px solid #e5e7eb !important; border-radius: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc {<!-- [et_pb_line_break_holder] -->    border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->    border-radius: 10px !important;<!-- [et_pb_line_break_holder] -->    padding: 14px !important;<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc-method { font-weight: 700 !important; color: #0f2736 !important; margin-bottom: 8px !important; font-size: 14px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc-row { display: flex !important; justify-content: space-between !important; font-size: 13px !important; padding: 4px 0 !important; border-bottom: 1px solid #f0f2f5 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc-row:last-child { border-bottom: none !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc-label { color: #64748b !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mc-val { font-weight: 600 !important; color: #383838 !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (min-width: 769px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-mobile-cards { display: none !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas h2,<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-h2-2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-quota-row { flex-direction: column !important; align-items: flex-start !important; gap: 8px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (max-width: 600px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas h2,<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-h2-2 { font-size: 24px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-intro,<!-- [et_pb_line_break_holder] -->  #upl-gpn-quotas .gpn-qt-intro-2 { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-quotas\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-quotas\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-qt-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-badge\"><span class=\"gpn-qt-badge-dot\"><\/span><span>Limits<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Quotas & rate limits for Gmail API push notifications<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-qt-intro\">Gmail API push notifications have specific quota constraints that differ from standard Gmail API quota buckets. The key constraint is per-user event throughput.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-quota-row\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-qt-quota-num\">1 event\/sec<\/div><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-qt-quota-label\">Maximum Pub\/Sub notification rate per authenticated user. Bursts may temporarily exceed this but are throttled over time. If a mailbox receives more than 1 change per second continuously, notifications will be batched or delayed, not dropped.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-quota-row\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-qt-quota-num\">7 days<\/div><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-qt-quota-label\">Maximum watch expiration. All watches must be renewed before this deadline. Gmail retains <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">history.list<\/code> data for the same 7-day window - a historyId older than 7 days returns a 404.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-quota-row\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-qt-quota-num\">1M units\/day<\/div><!-- [et_pb_line_break_holder] -->      <pee class=\"gpn-qt-quota-label\">Default Gmail API daily quota per project. Each <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">users.history.list<\/code> call costs 5 units. <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">users.watch<\/code> costs 100 units per call. Plan your reconciliation volume accordingly.<\/pee><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-qt-note\">For a deeper breakdown of per-method quotas, per-user limits, and quota increase request procedures, see our dedicated <a href=\"https:\/\/www.unipile.com\/gmail-api-rate-limits-and-quotas\/\" style=\"color:#2aaa7e!important;text-decoration:underline!important;\">Gmail API rate limits and quotas guide<\/a>.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <!-- TRADE-OFFS section --><!-- [et_pb_line_break_holder] -->    <span id=\"gpn-tradeoffs\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-badge-2\"><span class=\"gpn-qt-badge-2-dot\"><\/span><span>Comparison<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2 class=\"gpn-qt-h2-2\">Trade-offs: Pub\/Sub vs IMAP IDLE vs polling vs unified webhook<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-qt-intro-2\">Choosing the right Gmail push notifications strategy depends on your infrastructure constraints, provider coverage needs, and operational tolerance. Here is a direct comparison of the four approaches.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-qt-table-wrap\"><!-- [et_pb_line_break_holder] -->      <table><!-- [et_pb_line_break_holder] -->        <thead><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <th>Approach<\/th><!-- [et_pb_line_break_holder] -->            <th>Latency<\/th><!-- [et_pb_line_break_holder] -->            <th>Setup complexity<\/th><!-- [et_pb_line_break_holder] -->            <th>Multi-provider<\/th><!-- [et_pb_line_break_holder] -->            <th>Ops overhead<\/th><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->        <\/thead><!-- [et_pb_line_break_holder] -->        <tbody><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-method\">Gmail Pub\/Sub watch<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-latency\">1-10s<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-bad\">High - GCP, IAM, cron<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-bad\">Gmail only<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-bad\">7-day renewal cron<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-method\">IMAP IDLE<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-latency\">1-30s<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-medium\">Medium - persistent TCP<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">Gmail + IMAP servers<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-medium\">Keep-alive management<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-method\">Polling<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-bad\">30-300s lag<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">Low<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">Any provider<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-bad\">High quota burn<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->          <tr><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-method\">Unified webhook (Unipile)<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-latency\">1-10s<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">Low - 1 webhook URL<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">Gmail + Outlook + IMAP<\/span><\/td><!-- [et_pb_line_break_holder] -->            <td><span class=\"gpn-qt-td-good\">None - managed<\/span><\/td><!-- [et_pb_line_break_holder] -->          <\/tr><!-- [et_pb_line_break_holder] -->        <\/tbody><!-- [et_pb_line_break_holder] -->      <\/table><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-qt-mobile-cards\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-qt-mc\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-method\">Gmail Pub\/Sub watch<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Latency<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#2aaa7e!important;\">1-10s<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Setup<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#dc2626!important;\">High (GCP + IAM + cron)<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Providers<\/span><span class=\"gpn-qt-mc-val\">Gmail only<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-qt-mc\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-method\">IMAP IDLE<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Latency<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#2aaa7e!important;\">1-30s<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Setup<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#a16207!important;\">Medium (persistent TCP)<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Providers<\/span><span class=\"gpn-qt-mc-val\">Gmail + IMAP<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-qt-mc\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-method\">Polling<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Latency<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#dc2626!important;\">30-300s lag<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Setup<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#2aaa7e!important;\">Low<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Providers<\/span><span class=\"gpn-qt-mc-val\">Any<\/span><\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-qt-mc\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-method\">Unified webhook (Unipile)<\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Latency<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#2aaa7e!important;\">1-10s<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Setup<\/span><span class=\"gpn-qt-mc-val\" style=\"color:#2aaa7e!important;\">Low (1 webhook)<\/span><\/div><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-qt-mc-row\"><span class=\"gpn-qt-mc-label\">Providers<\/span><span class=\"gpn-qt-mc-val\">Gmail + Outlook + IMAP<\/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_section][et_pb_section fb_built=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-unified,<!-- [et_pb_line_break_holder] -->#upl-gpn-unified *,<!-- [et_pb_line_break_holder] -->#upl-gpn-unified *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-unified *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: #f4f5f7 !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 20px !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 35px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-intro {<!-- [et_pb_line_break_holder] -->  font-size: 17px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  color: #383838 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-layout {<!-- [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: 32px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefits {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefit {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  gap: 14px !important;<!-- [et_pb_line_break_holder] -->  align-items: flex-start !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefit-icon {<!-- [et_pb_line_break_holder] -->  width: 36px !important;<!-- [et_pb_line_break_holder] -->  height: 36px !important;<!-- [et_pb_line_break_holder] -->  min-width: 36px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 10px !important;<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.10) !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: center !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefit-icon svg {<!-- [et_pb_line_break_holder] -->  width: 18px !important;<!-- [et_pb_line_break_holder] -->  height: 18px !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefit-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 4px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-benefit-text {<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.7 !important;<!-- [et_pb_line_break_holder] -->  color: #64748b !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Code *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-code-wrap {<!-- [et_pb_line_break_holder] -->  border-radius: 14px !important;<!-- [et_pb_line_break_holder] -->  overflow: hidden !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-editor-bar {<!-- [et_pb_line_break_holder] -->  background: #161b22 !important;<!-- [et_pb_line_break_holder] -->  padding: 12px 18px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  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-gpn-unified .gpn-un-dot {<!-- [et_pb_line_break_holder] -->  width: 12px !important;<!-- [et_pb_line_break_holder] -->  height: 12px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-dot-r { background: #ff5f57 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-dot-y { background: #febc2e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-dot-g { background: #28c840 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-filename {<!-- [et_pb_line_break_holder] -->  color: #8b949e !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  margin-left: 6px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  line-height: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-pre {<!-- [et_pb_line_break_holder] -->  padding: 22px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 13px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.8 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: auto !important;<!-- [et_pb_line_break_holder] -->  background: #0d1117 !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-pre code {<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  white-space: pre-wrap !important;<!-- [et_pb_line_break_holder] -->  word-break: break-word !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .c { color: #8b949e !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .k { color: #ff7b72 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .fn { color: #d2a8ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .s { color: #a5d6ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .w { color: #e6edf3 !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .n { color: #79c0ff !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-ok {<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.1) !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;<!-- [et_pb_line_break_holder] -->  padding: 11px 24px !important;<!-- [et_pb_line_break_holder] -->  font-size: 12.5px !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Courier New', monospace !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-ok-dot {<!-- [et_pb_line_break_holder] -->  width: 8px !important;<!-- [et_pb_line_break_holder] -->  height: 8px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Compliance blocks *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-compliance {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 16px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-compliance-block {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 12px !important;<!-- [et_pb_line_break_holder] -->  padding: 20px 24px !important;<!-- [et_pb_line_break_holder] -->  border-left: 4px solid #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-compliance-title {<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  gap: 8px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 8px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-compliance-eyebrow {<!-- [et_pb_line_break_holder] -->  font-size: 10px !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.8px !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-compliance-text {<!-- [et_pb_line_break_holder] -->  font-size: 13.5px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.75 !important;<!-- [et_pb_line_break_holder] -->  color: rgba(255,255,255,0.82) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* CTA *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-strip {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 36px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: space-between !important;<!-- [et_pb_line_break_holder] -->  gap: 24px !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-text {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 20px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.3 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-sub {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  color: rgba(255,255,255,0.7) !important;<!-- [et_pb_line_break_holder] -->  margin-top: 8px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.6 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-btn {<!-- [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: #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 16px 32px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  font-size: 1rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-btn:hover { transform: translateY(-5px) !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-unified .gpn-un-cta-btn svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  stroke: currentColor !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified { padding: 50px 20px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified h2 { font-size: 28px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified .gpn-un-layout { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified .gpn-un-cta-strip { 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-gpn-unified { padding: 40px 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified h2 { font-size: 26px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified .gpn-un-intro { font-size: 16px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified .gpn-un-pre { font-size: 12px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-unified .gpn-un-cta-btn { width: 100% !important; justify-content: center !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-unified\"><!-- [et_pb_line_break_holder] -->  <span id=\"gpn-unified\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-un-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-un-badge\"><span class=\"gpn-un-badge-dot\"><\/span><span>Unified Alternative<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>The Unified Webhook Alternative: Gmail + Outlook + IMAP with one endpoint<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"gpn-un-intro\">If you need Gmail API push notifications plus real-time events from Outlook and IMAP mailboxes - with a unified payload format and no GCP infrastructure - Unipile's <a href=\"https:\/\/www.unipile.com\/communication-api\/email-api\/gmail-api\/\" style=\"color:#2aaa7e!important;text-decoration:underline!important;\">Gmail API<\/a> abstracts the entire Pub\/Sub layer. As an independent technical intermediary, Unipile acts on behalf of each authenticated user to deliver email events through a single webhook URL your application already controls.<\/pee><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-un-layout\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-un-benefits\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-benefit\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-un-benefit-icon\"><svg viewBox=\"0 0 24 24\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->          <div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-un-benefit-title\">No GCP setup<\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-un-benefit-text\">No Pub\/Sub topic to create, no IAM grant to configure, no GCP project to maintain. Watch registration and renewal happen inside Unipile's infrastructure, not yours.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-benefit\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-un-benefit-icon\"><svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><polyline points=\"12 6 12 12 16 14\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->          <div><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-un-benefit-title\">Watch renewal is managed<\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-un-benefit-text\">The 7-day watch expiration is handled on behalf of each linked account. You never need a renewal cron job. If a refresh token is revoked, Unipile surfaces an account status webhook instead of silently dropping events.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-benefit\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-un-benefit-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><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-un-benefit-title\">historyId reconciliation abstracted<\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-un-benefit-text\">You receive a parsed, normalized email object - not a raw historyId. There is no need to call <code style=\"background:rgba(0,0,0,0.06)!important;padding:2px 5px!important;border-radius:3px!important;font-family:monospace!important;font-size:0.85em!important;\">users.history.list<\/code> or manage per-user cursors. Unipile resolves the delta and delivers structured message data.<\/pee><!-- [et_pb_line_break_holder] -->          <\/div><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-benefit\"><!-- [et_pb_line_break_holder] -->          <div class=\"gpn-un-benefit-icon\"><svg viewBox=\"0 0 24 24\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"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><!-- [et_pb_line_break_holder] -->            <div class=\"gpn-un-benefit-title\">Gmail + Outlook + IMAP in one payload<\/div><!-- [et_pb_line_break_holder] -->            <pee class=\"gpn-un-benefit-text\">The same webhook endpoint and the same event schema covers Gmail, Outlook (including Microsoft 365 \/ Exchange Online), and IMAP. No per-provider integration logic, no separate webhooks for Microsoft Graph subscriptions vs Gmail pub sub notifications.<\/pee><!-- [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=\"gpn-un-code-wrap\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-editor-bar\"><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-un-dot gpn-un-dot-r\"><\/span><span class=\"gpn-un-dot gpn-un-dot-y\"><\/span><span class=\"gpn-un-dot gpn-un-dot-g\"><\/span><!-- [et_pb_line_break_holder] -->          <span class=\"gpn-un-filename\">unified-webhook.js<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-pre\"><code><span class=\"c\">\/\/ 1. Link user Gmail account (OAuth on behalf of authenticated user)<\/span><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ See: https:\/\/developer.unipile.com\/docs\/getting-started<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ 2. Configure your webhook once<\/span><!-- [et_pb_line_break_holder] --><span class=\"k\">const<\/span> <span class=\"w\">config =<\/span> <span class=\"k\">await<\/span> <span class=\"fn\">fetch<\/span><span class=\"w\">(<\/span><span class=\"s\">'https:\/\/api8.unipile.com:13815\/api\/v1\/webhooks'<\/span><span class=\"w\">, {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">method:<\/span> <span class=\"s\">'POST'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">headers: {<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"s\">'X-API-KEY'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'YOUR_API_KEY'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"s\">'Content-Type'<\/span><span class=\"w\">:<\/span> <span class=\"s\">'application\/json'<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">},<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">body:<\/span> <span class=\"fn\">JSON<\/span><span class=\"w\">.<\/span><span class=\"fn\">stringify<\/span><span class=\"w\">({<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">url:<\/span> <span class=\"s\">'https:\/\/app.you.com\/webhooks\/email'<\/span><span class=\"w\">,<\/span><!-- [et_pb_line_break_holder] -->    <span class=\"w\">events: [<\/span><span class=\"s\">'email.new'<\/span><span class=\"w\">]<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">})<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">});<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><span class=\"c\">\/\/ 3. Handle unified payload : same shape for Gmail, Outlook, IMAP<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">app.<\/span><span class=\"fn\">post<\/span><span class=\"w\">(<\/span><span class=\"s\">'\/webhooks\/email'<\/span><span class=\"w\">, (req, res) => {<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"k\">const<\/span> <span class=\"w\">{ event, account_id, email } = req.body;<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ event: \"email.new\"<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ email.provider: \"gmail\" | \"outlook\" | \"imap\"<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ email.subject, .from, .to, .body_html...<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"c\">\/\/ No historyId. No base64. No cursor to manage.<\/span><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <span class=\"fn\">processInboundEmail<\/span><span class=\"w\">(email);<\/span><!-- [et_pb_line_break_holder] -->  <span class=\"w\">res.<\/span><span class=\"fn\">status<\/span><span class=\"w\">(<\/span><span class=\"n\">200<\/span><span class=\"w\">).<\/span><span class=\"fn\">end<\/span><span class=\"w\">();<\/span><!-- [et_pb_line_break_holder] --><span class=\"w\">});<\/span><\/code><\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-ok\"><span class=\"gpn-un-ok-dot\"><\/span><span>Works for Gmail, Outlook and IMAP linked accounts<\/span><\/div><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <!-- Compliance blocks --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-un-compliance\"><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-un-compliance-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-compliance-title\"><span class=\"gpn-un-compliance-eyebrow\">Data Handling Note<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-un-compliance-text\">Unipile does not build a parallel email archive or store message content independently. Access is scoped to the session of each authenticated user. Unipile retrieves email data on behalf of each linked account and delivers it to your webhook endpoint in real time. No data is retained beyond what is necessary to deliver the webhook payload.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-un-compliance-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-compliance-title\"><span class=\"gpn-un-compliance-eyebrow\">How Unipile Operates<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-un-compliance-text\">Unipile is an independent technical intermediary. It acts on behalf of each authenticated user who has authorized your application via OAuth. Unipile is not affiliated with, endorsed by, or sponsored by Google. It uses the same Gmail API endpoints described in this guide, on a per-user basis, under each user's own OAuth authorization. Credentials are never shared between accounts. All operations are a customer-side decision delegated to Unipile's infrastructure.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <div class=\"gpn-un-compliance-block\"><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-compliance-title\"><span class=\"gpn-un-compliance-eyebrow\">Platform Limits and Responsible Use<\/span><\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-un-compliance-text\">Unipile relays the Gmail API rate limits and quota constraints to your application through its own quota management layer. Decisions about event volume, polling frequency, and message handling remain a customer-side decision. Unipile surfaces Gmail API quota errors as structured webhook events so your application can respond appropriately.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-un-cta-strip\"><!-- [et_pb_line_break_holder] -->      <div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-un-cta-text\">Start building with unified webhooks<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-un-cta-sub\">Connect your first Gmail account in minutes. No GCP project. No Pub\/Sub billing. No watch renewal cron. See our <a href=\"https:\/\/www.unipile.com\/gmail-api-integration-complete-guide\/\" style=\"color:#DDDF4C!important;text-decoration:underline!important;\">Gmail API integration guide<\/a> and the <a href=\"https:\/\/www.unipile.com\/email-api-providers\/\" style=\"color:#DDDF4C!important;text-decoration:underline!important;\">Email API provider overview<\/a> to explore all supported providers.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-un-cta-btn\" href=\"https:\/\/dashboard.unipile.com\/signup\/\" target=\"_blank\" rel=\"noopener\"><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><span>Build it with Unipile<\/span><\/a><!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<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] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"How do Gmail API push notifications work?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Gmail API push notifications use Google Cloud Pub\/Sub to deliver real-time mailbox change events to your HTTPS webhook. You register a watch endpoint via the users.watch API, which links a Gmail mailbox to a Pub\/Sub topic you own. When a change occurs (new message, label change), Gmail publishes a notification to that topic, which forwards it to your webhook. Your webhook then calls users.history.list with a stored historyId cursor to retrieve the actual message delta.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"What is the difference between watch and history in Gmail API?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"users.watch registers a push notification subscription for a Gmail mailbox and returns a historyId baseline. It is the entry point that connects Gmail to your Pub\/Sub topic. users.history.list is the reconciliation endpoint you call after receiving a push notification to get the actual changes (message additions, deletions, label changes) that occurred since your stored historyId cursor. Watch tells Gmail where to send alerts; history.list tells you what actually changed.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"How often do I need to renew Gmail watch?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Gmail API watch endpoints expire after 7 days. You must renew them before expiry by calling users.watch again. Best practice is to run a daily cron job (not weekly) so you have a 6-day safety buffer against transient failures. Watch renewal is idempotent: a new call simply resets the 7-day timer and returns a fresh historyId baseline.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"Why is Gmail Pub\/Sub not receiving notifications?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"The most common cause is a missing IAM grant. Gmail uses a Google-managed service account (gmail-api-push@system.gserviceaccount.com) to publish to your Pub\/Sub topic. If this account does not have the Pub\/Sub Publisher role on your topic, users.watch succeeds but no notifications are ever delivered. Other causes include a Pull-type subscription instead of Push, an invalid TLS certificate on your webhook endpoint, or a push endpoint URL that returns non-200 responses.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"What is the historyId in Gmail API?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"The historyId is a monotonically increasing integer that Gmail assigns to every mailbox change. It acts as a cursor for incremental sync. When you call users.watch, Gmail returns a historyId baseline representing the current state. When a push notification arrives, it includes a new historyId. You call users.history.list with your stored (previous) historyId as startHistoryId to get all changes between the two points. You must store the latest historyId per user in your database.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"Can you use Gmail push notifications without Pub\/Sub?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Not directly via the Gmail API. The Gmail API push notification mechanism requires Google Cloud Pub\/Sub as the delivery channel. However, you can avoid building the GCP infrastructure yourself by using a unified email API like Unipile, which abstracts the Pub\/Sub layer and delivers Gmail push notifications to your webhook using a normalized payload, with no GCP project, IAM configuration, or watch renewal cron required.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"How do I handle Gmail watch expiration?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Run a daily cron job that calls users.watch for all active authenticated users. Store the returned historyId as your new baseline and update the watchExpiry timestamp. Handle errors per user without aborting the entire job: 401 means the refresh token was revoked (user needs to re-authorize), 404 means the watch already expired (retry on next run). Never wait for the expiry date to renew.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"What is the rate limit for Gmail push notifications?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Gmail API push notifications are limited to approximately 1 event per second per authenticated user. Bursts above this rate may be batched or delayed by Pub\/Sub. Each users.history.list call costs 5 Gmail API quota units and users.watch costs 100 units per call. The default Gmail API daily quota is 1 million units per project. For details on quota increase requests and per-method limits, see the Gmail API limits documentation.\"<!-- [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] --><\/script><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@600;700&#038;display=swap\" rel=\"stylesheet\"><span id=\"faq-gpn\" style=\"display:block;position:relative;top:-80px;visibility:hidden;\"><\/span><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-faq { font-family:'Inter',sans-serif; padding:80px 20px; max-width:900px; margin:0 auto; background:transparent!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq *, #upl-gpn-faq *::before, #upl-gpn-faq *::after { margin:0!important; padding:0!important; box-sizing:border-box!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-header { text-align:center!important; margin-bottom:60px!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-title { font-family:'Poppins',sans-serif!important; font-size:clamp(32px,5vw,38px)!important; font-weight:700!important; color:#0f2736!important; margin-bottom:16px!important; line-height:1.2!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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-gpn-faq .upl-faq-list { display:flex!important; flex-direction:column!important; gap:12px!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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-gpn-faq .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-gpn-faq .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-gpn-faq .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; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-question-content { display:flex!important; align-items:flex-start!important; gap:16px!important; flex:1!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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; font-size:0.8rem!important; font-weight:600!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item.active .upl-faq-number { background:rgba(59,185,139,0.2)!important; color:#2a9d6e!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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-gpn-faq .upl-faq-icon svg { width:18px!important; height:18px!important; color:#64748b!important; transition:all 0.3s ease!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item:hover .upl-faq-icon { background:rgba(59,185,139,0.1)!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item:hover .upl-faq-icon svg { color:#3BB98B!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item.active .upl-faq-icon { background:#3BB98B!important; transform:rotate(45deg)!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item.active .upl-faq-icon svg { color:#ffffff!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-answer { max-height:0!important; overflow:hidden!important; transition:max-height 0.4s ease!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-item.active .upl-faq-answer { max-height:600px!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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-gpn-faq .upl-faq-answer-content strong { color:#0f2736!important; font-weight:600!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-answer-content a { color:#3BB98B!important; text-decoration:underline!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-answer-content code { font-family:monospace!important; background:#f1f5f9!important; padding:2px 6px!important; border-radius:3px!important; font-size:0.85em!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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-gpn-faq .upl-faq-cta-text { color:#475569!important; font-size:1rem!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .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; white-space:nowrap!important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-faq .upl-faq-cta-button:hover { transform:translateY(-2px)!important; }<!-- [et_pb_line_break_holder] -->@media (max-width:768px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-faq { padding:60px 16px!important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-faq .upl-faq-answer-content { padding:0 20px 20px 20px!important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-faq .upl-faq-question { padding:18px 20px!important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-faq .upl-faq-cta { flex-direction:column!important; align-items:flex-start!important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><section id=\"upl-gpn-faq\"><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-header\"><!-- [et_pb_line_break_holder] -->    <h2 class=\"upl-faq-title\">Gmail API Push Notifications - FAQ<\/h2><!-- [et_pb_line_break_holder] -->    <pee class=\"upl-faq-subtitle\">Answers to the most common questions about Gmail API push notifications, Pub\/Sub setup, historyId, watch renewal, and real-time email sync alternatives.<\/pee><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] -->  <div class=\"upl-faq-list\"><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"upl-faq-item active\"><!-- [et_pb_line_break_holder] -->      <button class=\"upl-faq-question\" aria-expanded=\"true\"><!-- [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 Gmail API push notifications work?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>Gmail API push notifications use <strong>Google Cloud Pub\/Sub<\/strong> to deliver real-time mailbox change events to your HTTPS webhook. You register a watch endpoint via <code>users.watch<\/code>, which links a Gmail mailbox to a Pub\/Sub topic you own. When a change occurs - new message, label change - Gmail publishes a notification to that topic, which forwards it to your push webhook. Your webhook then calls <code>users.history.list<\/code> with a stored <code>historyId<\/code> cursor to retrieve the actual message delta. The Pub\/Sub notification itself contains only the user email and a new historyId - not the message content.<\/pee><\/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=\"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\">What is the difference between watch and history in Gmail API?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>users.watch<\/strong> registers a push notification subscription for a Gmail mailbox and returns a historyId baseline. It is the entry point that connects Gmail to your Pub\/Sub topic. <strong>users.history.list<\/strong> is the reconciliation endpoint you call after receiving a Gmail push notification to get the actual changes (message additions, deletions, label changes) that occurred since your stored historyId cursor. Watch tells Gmail where to send alerts. History tells you what actually changed.<\/pee><\/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=\"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\">How often do I need to renew Gmail watch?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>Gmail API watch endpoints expire after <strong>7 days<\/strong>. Best practice is to run a <strong>daily cron job<\/strong> rather than every 6 or 7 days, so you have a multi-day buffer against transient failures. Watch renewal is idempotent: a new <code>users.watch<\/code> call simply resets the timer and returns a fresh historyId baseline. Expiration happens silently - there is no warning notification, so a failed cron means missed events with no errors on either side.<\/pee><\/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=\"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\">Why is Gmail Pub\/Sub not receiving notifications?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>The most common cause is a <strong>missing IAM grant<\/strong>. Gmail uses the service account <code>gmail-api-push@system.gserviceaccount.com<\/code> to publish to your Pub\/Sub topic. Without the <strong>Pub\/Sub Publisher<\/strong> role on your topic for this account, <code>users.watch<\/code> succeeds but no notifications are ever delivered. Other causes: subscription type is \"Pull\" instead of \"Push\", invalid TLS certificate on your webhook endpoint, or your endpoint returns non-2xx responses causing Pub\/Sub to stop delivering.<\/pee><\/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=\"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\">What is the historyId in Gmail API?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>The <strong>historyId<\/strong> is a monotonically increasing integer that Gmail assigns to every mailbox change event. It acts as an incremental sync cursor. When you register a <code>users.watch<\/code>, Gmail returns a historyId baseline representing the current state. Subsequent Gmail push notifications include a new historyId. You pass your stored (previous) historyId as <code>startHistoryId<\/code> to <code>users.history.list<\/code> to get all changes between the two points. You must store the latest historyId per authenticated user in your database. HistoryIds older than 7 days return a 404 error.<\/pee><\/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=\"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 you use Gmail push notifications without Pub\/Sub?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>Not directly through the Gmail API - Pub\/Sub is the required delivery channel for Gmail push notifications. However, you can skip the GCP infrastructure entirely by using a unified email API like <a href=\"https:\/\/www.unipile.com\/communication-api\/email-api\/gmail-api\/\">Unipile<\/a>, which acts as an independent technical intermediary on behalf of each authenticated user, abstracts the Pub\/Sub layer, and delivers Gmail push notifications to your webhook with a normalized payload. No GCP project, no IAM grant, no watch renewal cron required.<\/pee><\/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=\"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\">07<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"upl-faq-question-text\">How do I handle Gmail watch expiration?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>Run a <strong>daily cron job<\/strong> that calls <code>users.watch<\/code> for all active authenticated users. Store the returned historyId as the new baseline and update the stored expiry timestamp. Handle per-user errors without aborting the batch: a 401 means the OAuth refresh token was revoked (user must re-authorize), a 404 means the watch was already expired. Never wait until the 7-day expiry to renew - treat the daily run as maintenance, not a reactive fix.<\/pee><\/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=\"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\">08<\/span><!-- [et_pb_line_break_holder] -->          <span class=\"upl-faq-question-text\">What is the rate limit for Gmail push notifications?<\/span><!-- [et_pb_line_break_holder] -->        <\/div><!-- [et_pb_line_break_holder] -->        <div class=\"upl-faq-icon\"><!-- [et_pb_line_break_holder] -->          <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><!-- [et_pb_line_break_holder] -->        <\/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>Gmail API push notifications are capped at approximately <strong>1 event per second per authenticated user<\/strong>. Bursts above this are batched or delayed, not dropped. The <code>users.history.list<\/code> call costs 5 quota units and <code>users.watch<\/code> costs 100 units per call. The default Gmail API daily quota is 1 million units per project. For a complete breakdown of per-method limits and quota increase procedures, see our <a href=\"https:\/\/www.unipile.com\/gmail-api-rate-limits-and-quotas\/\">Gmail API rate limits guide<\/a>.<\/pee><\/div><!-- [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 class=\"upl-faq-cta\"><!-- [et_pb_line_break_holder] -->    <pee class=\"upl-faq-cta-text\">Need help setting up Gmail API push notifications for your app? Our team can walk you through it.<\/pee><!-- [et_pb_line_break_holder] -->    <span 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><\/span><!-- [et_pb_line_break_holder] -->  <\/div><!-- [et_pb_line_break_holder] --><\/section><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function(){<!-- [et_pb_line_break_holder] -->  function initFaq(){<!-- [et_pb_line_break_holder] -->    var faq=document.getElementById('upl-gpn-faq');<!-- [et_pb_line_break_holder] -->    if(!faq)return;<!-- [et_pb_line_break_holder] -->    faq.querySelectorAll('.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] -->        faq.querySelectorAll('.upl-faq-item').forEach(function(i){i.classList.remove('active');i.querySelector('.upl-faq-question').setAttribute('aria-expanded','false');});<!-- [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',initFaq);}else{initFaq();}<!-- [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=\"1\" _builder_version=\"4.27.0\" background_color=\"transparent\" width=\"100%\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\" da_is_popup=\"off\" da_exit_intent=\"off\" da_has_close=\"on\" da_alt_close=\"off\" da_dark_close=\"off\" da_not_modal=\"on\" da_is_singular=\"off\" da_with_loader=\"off\" da_has_shadow=\"on\" da_disable_devices=\"off|off|off\"][et_pb_row _builder_version=\"4.27.0\" max_width=\"100%\" custom_padding=\"0px||0px||false|false\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_column type=\"4_4\" _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"][et_pb_code _builder_version=\"4.27.0\" global_colors_info=\"{}\" theme_builder_area=\"post_content\"]<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&#038;family=Poppins:wght@700;800&#038;display=swap\" rel=\"stylesheet\"><!-- [et_pb_line_break_holder] --><style><!-- [et_pb_line_break_holder] -->#upl-gpn-related,<!-- [et_pb_line_break_holder] -->#upl-gpn-related *,<!-- [et_pb_line_break_holder] -->#upl-gpn-related *::before,<!-- [et_pb_line_break_holder] -->#upl-gpn-related *::after {<!-- [et_pb_line_break_holder] -->  margin: 0 !important;<!-- [et_pb_line_break_holder] -->  padding: 0 !important;<!-- [et_pb_line_break_holder] -->  box-sizing: border-box !important;<!-- [et_pb_line_break_holder] -->  border: none !important;<!-- [et_pb_line_break_holder] -->  outline: none !important;<!-- [et_pb_line_break_holder] -->  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: normal !important;<!-- [et_pb_line_break_holder] -->  text-transform: none !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  list-style: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related {<!-- [et_pb_line_break_holder] -->  display: block !important;<!-- [et_pb_line_break_holder] -->  background: transparent !important;<!-- [et_pb_line_break_holder] -->  padding: 70px 0 !important;<!-- [et_pb_line_break_holder] -->  overflow-x: hidden !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-inner {<!-- [et_pb_line_break_holder] -->  max-width: 1100px !important;<!-- [et_pb_line_break_holder] -->  margin: 0 auto !important;<!-- [et_pb_line_break_holder] -->  padding: 0 20px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-badge {<!-- [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(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #2aaa7e !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] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 16px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-badge-dot {<!-- [et_pb_line_break_holder] -->  width: 7px !important;<!-- [et_pb_line_break_holder] -->  height: 7px !important;<!-- [et_pb_line_break_holder] -->  background: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  border-radius: 50% !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->  display: inline-block !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related h2 {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 28px !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.2 !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 32px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-grid {<!-- [et_pb_line_break_holder] -->  display: grid !important;<!-- [et_pb_line_break_holder] -->  grid-template-columns: repeat(3, 1fr) !important;<!-- [et_pb_line_break_holder] -->  gap: 20px !important;<!-- [et_pb_line_break_holder] -->  margin-bottom: 40px !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card {<!-- [et_pb_line_break_holder] -->  background: #ffffff !important;<!-- [et_pb_line_break_holder] -->  border: 1px solid #e5e7eb !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 24px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  flex-direction: column !important;<!-- [et_pb_line_break_holder] -->  gap: 12px !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.2s ease, border-color 0.2s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card:hover {<!-- [et_pb_line_break_holder] -->  border-color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  transform: translateY(-4px) !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card-tag {<!-- [et_pb_line_break_holder] -->  display: inline-flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  padding: 4px 10px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 999px !important;<!-- [et_pb_line_break_holder] -->  font-size: 11px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  text-transform: uppercase !important;<!-- [et_pb_line_break_holder] -->  letter-spacing: 0.6px !important;<!-- [et_pb_line_break_holder] -->  width: fit-content !important;<!-- [et_pb_line_break_holder] -->  background: rgba(59, 185, 139, 0.12) !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card-title {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 15px !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.3 !important;<!-- [et_pb_line_break_holder] -->  flex: 1 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card-arrow {<!-- [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: 12px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  color: #3BB98B !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-card-arrow svg {<!-- [et_pb_line_break_holder] -->  width: 14px !important;<!-- [et_pb_line_break_holder] -->  height: 14px !important;<!-- [et_pb_line_break_holder] -->  stroke: #3BB98B !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->\/* Pillar CTA *\/<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar {<!-- [et_pb_line_break_holder] -->  background: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  border-radius: 16px !important;<!-- [et_pb_line_break_holder] -->  padding: 32px !important;<!-- [et_pb_line_break_holder] -->  display: flex !important;<!-- [et_pb_line_break_holder] -->  align-items: center !important;<!-- [et_pb_line_break_holder] -->  justify-content: space-between !important;<!-- [et_pb_line_break_holder] -->  gap: 24px !important;<!-- [et_pb_line_break_holder] -->  flex-wrap: wrap !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar-text {<!-- [et_pb_line_break_holder] -->  font-family: 'Poppins', sans-serif !important;<!-- [et_pb_line_break_holder] -->  font-size: 18px !important;<!-- [et_pb_line_break_holder] -->  font-weight: 700 !important;<!-- [et_pb_line_break_holder] -->  color: #ffffff !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.4 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar-sub {<!-- [et_pb_line_break_holder] -->  font-size: 14px !important;<!-- [et_pb_line_break_holder] -->  color: rgba(255,255,255,0.7) !important;<!-- [et_pb_line_break_holder] -->  margin-top: 6px !important;<!-- [et_pb_line_break_holder] -->  line-height: 1.5 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar-btn {<!-- [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: #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  color: #0f2736 !important;<!-- [et_pb_line_break_holder] -->  padding: 14px 28px !important;<!-- [et_pb_line_break_holder] -->  border-radius: 8px !important;<!-- [et_pb_line_break_holder] -->  font-size: 0.95rem !important;<!-- [et_pb_line_break_holder] -->  font-weight: 600 !important;<!-- [et_pb_line_break_holder] -->  border: 2px solid #DDDF4C !important;<!-- [et_pb_line_break_holder] -->  transition: transform 0.3s ease !important;<!-- [et_pb_line_break_holder] -->  cursor: pointer !important;<!-- [et_pb_line_break_holder] -->  white-space: nowrap !important;<!-- [et_pb_line_break_holder] -->  text-decoration: none !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar-btn:hover { transform: translateY(-5px) !important; }<!-- [et_pb_line_break_holder] -->#upl-gpn-related .gpn-rel-pillar-btn svg {<!-- [et_pb_line_break_holder] -->  width: 16px !important;<!-- [et_pb_line_break_holder] -->  height: 16px !important;<!-- [et_pb_line_break_holder] -->  stroke: currentColor !important;<!-- [et_pb_line_break_holder] -->  fill: none !important;<!-- [et_pb_line_break_holder] -->  stroke-width: 2.5 !important;<!-- [et_pb_line_break_holder] -->  stroke-linecap: round !important;<!-- [et_pb_line_break_holder] -->  stroke-linejoin: round !important;<!-- [et_pb_line_break_holder] -->  flex-shrink: 0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->@media (max-width: 900px) {<!-- [et_pb_line_break_holder] -->  #upl-gpn-related { padding: 50px 0 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-related .gpn-rel-grid { grid-template-columns: repeat(2, 1fr) !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-related .gpn-rel-pillar { 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-gpn-related { padding: 40px 0 !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-related .gpn-rel-grid { grid-template-columns: 1fr !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-related h2 { font-size: 22px !important; }<!-- [et_pb_line_break_holder] -->  #upl-gpn-related .gpn-rel-pillar-btn { width: 100% !important; justify-content: center !important; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><div id=\"upl-gpn-related\"><!-- [et_pb_line_break_holder] -->  <div class=\"gpn-rel-inner\"><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rel-badge\"><span class=\"gpn-rel-badge-dot\"><\/span><span>Related Guides<\/span><\/div><!-- [et_pb_line_break_holder] -->    <h2>Continue learning: Gmail API, OAuth & Email Sync<\/h2><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rel-grid\"><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/gmail-api-integration-complete-guide\/\" data-upl-link=\"https:\/\/www.unipile.com\/gmail-api-integration-complete-guide\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>Gmail Hub<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">Gmail API Integration: Complete Guide for Developers<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/google-oauth-app-verification-complete-guide\/\" data-upl-link=\"https:\/\/www.unipile.com\/google-oauth-app-verification-complete-guide\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>Verification Hub<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">Google OAuth App Verification: Complete Guide<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/gmail-api-rate-limits-and-quotas\/\" data-upl-link=\"https:\/\/www.unipile.com\/gmail-api-rate-limits-and-quotas\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>Limits & Quotas<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">Gmail API Rate Limits & Quotas: Full Reference<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/gmail-oauth-20-integration-complete-guide\/\" data-upl-link=\"https:\/\/www.unipile.com\/gmail-oauth-20-integration-complete-guide\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>Refresh Token<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">Gmail OAuth 2.0 Integration: Refresh Tokens & Scopes<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/imap-api-complete-guide-for-developers\/\" data-upl-link=\"https:\/\/www.unipile.com\/imap-api-complete-guide-for-developers\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>IMAP Hub<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">IMAP API Guide: IDLE, Sync & Real-Time Events<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-card\" href=\"https:\/\/www.unipile.com\/ms-graph-api-email-complete-guide\/\" data-upl-link=\"https:\/\/www.unipile.com\/ms-graph-api-email-complete-guide\/\" data-upl-target=\"_self\"><!-- [et_pb_line_break_holder] -->        <span class=\"gpn-rel-card-tag\"><span>MS Graph Hub<\/span><\/span><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-title\">Microsoft Graph API Email: Subscriptions & Webhooks<\/div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-card-arrow\"><span>Read guide<\/span><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg><\/div><!-- [et_pb_line_break_holder] -->      <\/a><!-- [et_pb_line_break_holder] -->    <\/div><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <div class=\"gpn-rel-pillar\"><!-- [et_pb_line_break_holder] -->      <div><!-- [et_pb_line_break_holder] -->        <div class=\"gpn-rel-pillar-text\">The complete Email API guide<\/div><!-- [et_pb_line_break_holder] -->        <pee class=\"gpn-rel-pillar-sub\">Everything you need to send, receive, and sync email via API - Gmail, Outlook, and IMAP covered end-to-end.<\/pee><!-- [et_pb_line_break_holder] -->      <\/div><!-- [et_pb_line_break_holder] -->      <a class=\"gpn-rel-pillar-btn\" href=\"https:\/\/www.unipile.com\/email-api-guide\/\" data-upl-link=\"https:\/\/www.unipile.com\/email-api-guide\/\" data-upl-target=\"_self\"><svg viewBox=\"0 0 24 24\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/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><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function(){<!-- [et_pb_line_break_holder] -->  document.addEventListener('click', function(e){<!-- [et_pb_line_break_holder] -->    var el = e.target.closest('[data-upl-link]');<!-- [et_pb_line_break_holder] -->    if (!el) return;<!-- [et_pb_line_break_holder] -->    e.preventDefault();<!-- [et_pb_line_break_holder] -->    var href = el.getAttribute('data-upl-link');<!-- [et_pb_line_break_holder] -->    var target = el.getAttribute('data-upl-target') || '_self';<!-- [et_pb_line_break_holder] -->    if (href) window.open(href, target);<!-- [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]\n","protected":false},"excerpt":{"rendered":"<p>Step by Step Step-by-step: create topic, subscription, and users.watch With GCP prerequisites in place, here is the complete code to register a Gmail API watch endpoint in both Node.js and Python, using the Google API client library. Node.js Python watch.js const { google } = require(&#8216;googleapis&#8217;);\/\/ Assumes OAuth2 client is already authorized with a valid [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":279182,"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":[69],"tags":[],"post_folder":[],"class_list":["post-279162","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-api-guidelines"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch &amp; History (2026) - Unipile<\/title>\n<meta name=\"description\" content=\"Set up Gmail API push notifications end-to-end. Pub\/Sub topic, watch endpoint, historyId reconciliation, renewal, troubleshooting, plus a unified webhook alternative.\" \/>\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\/de\/gmail-api-push-benachrichtigungen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch &amp; History (2026) - Unipile\" \/>\n<meta property=\"og:description\" content=\"Set up Gmail API push notifications end-to-end. Pub\/Sub topic, watch endpoint, historyId reconciliation, renewal, troubleshooting, plus a unified webhook alternative.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.unipile.com\/de\/gmail-api-push-benachrichtigungen\/\" \/>\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-06-05T08:52:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-08T14:59:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1600\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\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=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Damien Girardeau\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"15\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/\"},\"author\":{\"name\":\"Damien Girardeau\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#\\\/schema\\\/person\\\/a2ac44e22bdc27d497ce8b58716a673e\"},\"headline\":\"Gmail API Push Notifications: Complete Guide to Pub\\\/Sub, Watch &#038; History (2026)\",\"datePublished\":\"2026-06-05T08:52:54+00:00\",\"dateModified\":\"2026-06-08T14:59:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/\"},\"wordCount\":4378,\"publisher\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/gmail-api-push-notifications.png\",\"articleSection\":[\"API Guidelines\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/\",\"name\":\"Gmail API Push Notifications: Complete Guide to Pub\\\/Sub, Watch & History (2026) - Unipile\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/gmail-api-push-notifications.png\",\"datePublished\":\"2026-06-05T08:52:54+00:00\",\"dateModified\":\"2026-06-08T14:59:12+00:00\",\"description\":\"Set up Gmail API push notifications end-to-end. Pub\\\/Sub topic, watch endpoint, historyId reconciliation, renewal, troubleshooting, plus a unified webhook alternative.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/gmail-api-push-notifications.png\",\"contentUrl\":\"https:\\\/\\\/www.unipile.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/gmail-api-push-notifications.png\",\"width\":2400,\"height\":1600,\"caption\":\"Gmail API Push Notifications: Pub\\\/Sub, Watch & History (2026)\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/gmail-api-push-notifications\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.unipile.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Gmail API Push Notifications: Complete Guide to Pub\\\/Sub, Watch &#038; History (2026)\"}]},{\"@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\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.unipile.com\\\/#organization\",\"name\":\"Unipile\",\"url\":\"https:\\\/\\\/www.unipile.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@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\":\"de\",\"@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":"Gmail API Push-Benachrichtigungen: Der komplette Leitfaden zu Pub\/Sub, Watch &amp; History (2026) - Unipile","description":"Gmail API Push-Benachrichtigungen Ende-zu-Ende einrichten. Pub\/Sub-Thema, Watch-Endpunkt, historyId-Abgleich, Erneuerung, Fehlerbehebung plus eine einheitliche Webhook-Alternative.","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\/de\/gmail-api-push-benachrichtigungen\/","og_locale":"de_DE","og_type":"article","og_title":"Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch & History (2026) - Unipile","og_description":"Set up Gmail API push notifications end-to-end. Pub\/Sub topic, watch endpoint, historyId reconciliation, renewal, troubleshooting, plus a unified webhook alternative.","og_url":"https:\/\/www.unipile.com\/de\/gmail-api-push-benachrichtigungen\/","og_site_name":"Unipile","article_publisher":"https:\/\/www.facebook.com\/unipilefr","article_published_time":"2026-06-05T08:52:54+00:00","article_modified_time":"2026-06-08T14:59:12+00:00","og_image":[{"width":2400,"height":1600,"url":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png","type":"image\/png"}],"author":"Damien Girardeau","twitter_card":"summary_large_image","twitter_creator":"@UnipileAPI","twitter_site":"@UnipileAPI","twitter_misc":{"Verfasst von":"Damien Girardeau","Gesch\u00e4tzte Lesezeit":"15\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#article","isPartOf":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/"},"author":{"name":"Damien Girardeau","@id":"https:\/\/www.unipile.com\/#\/schema\/person\/a2ac44e22bdc27d497ce8b58716a673e"},"headline":"Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch &#038; History (2026)","datePublished":"2026-06-05T08:52:54+00:00","dateModified":"2026-06-08T14:59:12+00:00","mainEntityOfPage":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/"},"wordCount":4378,"publisher":{"@id":"https:\/\/www.unipile.com\/#organization"},"image":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png","articleSection":["API Guidelines"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/","url":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/","name":"Gmail API Push-Benachrichtigungen: Der komplette Leitfaden zu Pub\/Sub, Watch &amp; History (2026) - Unipile","isPartOf":{"@id":"https:\/\/www.unipile.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#primaryimage"},"image":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png","datePublished":"2026-06-05T08:52:54+00:00","dateModified":"2026-06-08T14:59:12+00:00","description":"Gmail API Push-Benachrichtigungen Ende-zu-Ende einrichten. Pub\/Sub-Thema, Watch-Endpunkt, historyId-Abgleich, Erneuerung, Fehlerbehebung plus eine einheitliche Webhook-Alternative.","breadcrumb":{"@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.unipile.com\/gmail-api-push-notifications\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#primaryimage","url":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png","contentUrl":"https:\/\/www.unipile.com\/wp-content\/uploads\/2026\/06\/gmail-api-push-notifications.png","width":2400,"height":1600,"caption":"Gmail API Push Notifications: Pub\/Sub, Watch & History (2026)"},{"@type":"BreadcrumbList","@id":"https:\/\/www.unipile.com\/gmail-api-push-notifications\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.unipile.com\/"},{"@type":"ListItem","position":2,"name":"Gmail API Push Notifications: Complete Guide to Pub\/Sub, Watch &#038; History (2026)"}]},{"@type":"WebSite","@id":"https:\/\/www.unipile.com\/#website","url":"https:\/\/www.unipile.com\/","name":"Unipile","description":"Integration von Messaging und E-Mail, einfache Verbindung \u00fcber 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":"de"},{"@type":"Organization","@id":"https:\/\/www.unipile.com\/#organization","name":"Unipile","url":"https:\/\/www.unipile.com\/","logo":{"@type":"ImageObject","inLanguage":"de","@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":"de","@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\/de\/wp-json\/wp\/v2\/posts\/279162","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/comments?post=279162"}],"version-history":[{"count":7,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/posts\/279162\/revisions"}],"predecessor-version":[{"id":279177,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/posts\/279162\/revisions\/279177"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/media\/279182"}],"wp:attachment":[{"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/media?parent=279162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/categories?post=279162"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/tags?post=279162"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/www.unipile.com\/de\/wp-json\/wp\/v2\/post_folder?post=279162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}