руководство · sendgrid api
Как продуктовой команде безопасно внедрить SendGrid API?
Вызывайте SendGrid API из серверного почтового сервиса, используя аутентифицированный домен отправки и API-ключ, ограниченный правом Mail Send. Проверяйте каждое письмо перед вызовом `POST /v3/mail/send`, сохраняйте собственную запись об отправке и фиксируйте `X-Message-ID` из ответа. Обрабатывайте подписанные данные Event Webhook по исходным байтам, устраняйте дубликаты событий и учитывайте отказы, жалобы на спам и отписки. Считайте `202 Accepted`, доставку на сервер получателя и попадание во «Входящие» разными состояниями и применяйте ограниченные повторы только к временным сбоям.
Определите узкую и легитимную задачу отправки
v3 Mail Send API от SendGrid — это эндпоинт провайдера для исходящей почты, а не почтовый ящик пользователя общего назначения. Размещайте его за доверенным сервисом приложения или воркером очереди и определите, какие продуктовые события могут создавать письма: подтверждение аккаунта, чек, уведомление безопасности или запрошенное оповещение. Не открывайте ключ провайдера браузерам, мобильным клиентам, шаблонам, промптам или журналам. Разделяйте транзакционные письма и рассылки, зависящие от согласия, на уровне модели данных, чтобы ожидания получателей, обработку предпочтений и репутацию можно было вести независимо. До начала реализации решите, кто владеет доменом отправителя, кто утверждает шаблоны, из каких окружений можно отправлять письма наружу и какие получатели разрешены при разработке. Эти рамки станут границей для прав API-ключа, настройки домена, записей аудита, оповещений и реагирования на инциденты. Кроме того, они делают возможной смену провайдера, потому что код продукта запрашивает одобренную почтовую операцию, а не формирует произвольные запросы к SendGrid по всему приложению.
Аутентифицируйте отдельный домен отправки
Настройте в SendGrid Domain Authentication для домена или специального поддомена под вашим контролем, затем опубликуйте в точности те DNS-записи, которые сгенерированы для этой идентичности, и подтвердите их в SendGrid. В документации провайдера отмечается, что поддомены не наследуют аутентификацию родительского домена, поэтому подтверждайте именно тот домен, который используется в адресах From. Изучите существующие SPF- и DMARC-записи до изменения DNS; не создавайте вторую SPF-политику для того же имени хоста и не заменяйте существующую политику DMARC организации без участия её владельца. Держите транзакционный и промо-трафик на осознанно выбранных идентичностях, если их аудитории и риски различаются. Проверьте на полученном тестовом письме видимый адрес From, обратный путь, домен подписи DKIM, путь для ответов и поведение брендирования ссылок. Аутентификация устанавливает авторизованную идентичность и сигналы выравнивания, но не определяет итоговую папку у принимающей системы. Продолжайте отслеживать отказы, жалобы, ожидания получателей и содержимое и после успешного подтверждения DNS.
Выпускайте API-ключи с минимальными правами для каждого окружения
Создайте API-ключ Custom Access только с теми правами, которые нужны нагрузке, — обычно это доступ Mail Send для воркера отправки. Не давайте обычному отправителю Full Access к шаблонам, стоп-листам, участникам команды, статистике, настройкам IP или администрированию аккаунта. Используйте отдельные ключи для разработки, стейджинга и продакшена с названиями, указывающими на сервис-владелец и цель ротации. SendGrid показывает новый ключ один раз, поэтому сразу помещайте его в менеджер секретов окружения и никогда не копируйте в систему контроля версий или общий документ. Во время выполнения читайте его из конфигурации на основе секретов и передавайте только в заголовке `Authorization: Bearer` по HTTPS. Отрабатывайте ротацию ключей как операционную последовательность: создайте замену с такими же узкими правами, разверните её, убедитесь в успешной отправке контролируемого трафика, а затем отзовите старый ключ. Настройте оповещения о неожиданных ответах 401 или 403: они могут указывать на отсутствующий ключ, отозванные учётные данные, несоответствие прав или небезопасное изменение конфигурации.
Формируйте и фиксируйте каждый запрос Mail Send
Создайте одну внутреннюю запись об исходящей отправке до обращения к SendGrid. Присвойте ей стабильный ключ события приложения, тенанта, адрес отправителя, одобренных получателей, класс письма, версию шаблона и состояние. Формируйте полезную нагрузку провайдера из этой записи с помощью `personalizations`, `from`, `subject` и хотя бы одной поддерживаемой части содержимого или одобренного динамического шаблона. До сетевого вызова проверяйте синтаксис адресов, число получателей, размер вложений, данные шаблона и пользовательские заголовки. Согласно актуальному обзору Mail Send от SendGrid, общий размер запроса вместе с вложениями должен быть меньше 30 MB, а общее число получателей в To, Cc и Bcc — не более 1 000. Небольшие запросы под конкретную задачу проще проверять и восстанавливать. При ответе `202 Accepted` сохраните заголовок `X-Message-ID` и привяжите его к записи об отправке. Не помещайте персональные данные в категории или уникальные аргументы: SendGrid предупреждает, что эти значения могут храниться и просматриваться вне тех мер защиты, которые ожидаются для содержимого писем.
Проверяйте и обрабатывайте Event Webhook
Настройте Event Webhook SendGrid на HTTPS-эндпоинт, способный сохранить исходное тело запроса. Включите криптографическую подпись, OAuth 2.0 или оба механизма. При подписанной доставке проверяйте временную метку и `X-Twilio-Email-Event-Webhook-Signature` по точным исходным байтам до разбора JSON; Twilio предупреждает, что повторная сериализация полезной нагрузки может изменить байты и сделать проверку недействительной. Отклоняйте неаутентифицированные входные данные, применяйте разумный лимит на размер запроса и защищайтесь от повторного воспроизведения в соответствии с выбранной командой политикой временных меток. После проверки поставьте пакет событий в очередь или надёжно сохраните его до возврата успешного ответа. Устраняйте дубликаты по `sg_event_id`, затем сопоставляйте `sg_message_id`, сохранённый `X-Message-ID` и неконфиденциальное внутреннее значение корреляции. Делайте переходы состояний монотонными, чтобы запоздавшее событие processed не перезаписало более поздний результат delivered или bounce. Храните исходное событие провайдера в хранилище с ограниченным доступом для диагностики, но сводите хранение адресов, текстов ответов и данных о вовлечённости к тому, что действительно требуется продукту и политике.
Точно моделируйте приём, доставку и попадание во «Входящие»
HTTP-ответ `202 Accepted` от SendGrid означает, что запрос принят и поставлен в очередь на обработку. Он не говорит о том, что сервер назначения принял письмо. Событие вебхука `processed` означает, что SendGrid принял письмо и может попытаться его доставить. Событие `delivered` означает, что, по данным SendGrid, принимающий почтовый сервер принял письмо — часто с указанием SMTP-ответа. Но и это не подтверждает попадание во «Входящие»: принимающая система может поместить принятое письмо на вкладку «Входящие», в карантин, в папку «Нежелательная почта» или в другое место. Храните и показывайте в интерфейсах эти состояния раздельно: запрошено, принято провайдером, обработано, отложено, принято сервером получателя, отказ, отброшено, жалоба или в стоп-листе. Не превращайте каждый HTTP-ответ без ошибки в «доставлено». Сигналы вовлечённости, например открытия, тоже не доказывают доставку, и на них могут влиять функции защиты приватности. Точные названия состояний делают расследования в поддержке, повторы и решения по доставляемости безопаснее.
Классифицируйте сбои до повтора
Обрабатывайте ошибки провайдера по классам, а не повторяйте каждый ответ, отличный от 202. Ответ 400 обычно требует исправить полезную нагрузку, отправителя, данные шаблона или зарезервированные заголовки. 401 указывает на проблему аутентификации; 403 может означать недостаточные права или политику аккаунта; 413 требует уменьшить размер письма. SendGrid документирует заголовки лимитов запросов для каждого эндпоинта и возвращает 429, когда лимит на период обновления исчерпан, поэтому ждите до времени сброса и добавляйте случайный разброс, а не создавайте синхронные повторы. Повторяйте ошибки 5xx и транспортные сбои с экспоненциальной задержкой, конечным числом попыток и оперативным оповещением. Неоднозначные тайм-ауты требуют особого внимания: провайдер мог принять запрос, даже если клиент не получил ответа. Держите запись об отправке в состоянии «неизвестно», ищите связанные события и требуйте осознанного правила сверки перед повторной отправкой. API провайдера не отменяют необходимости предотвращать дубликаты на уровне продукта. Никогда не повторяйте отправку на адрес с известным постоянным отказом, некорректного получателя, отписавшегося или пожаловавшегося на спам так, будто это временный сбой инфраструктуры.
Соблюдайте стоп-листы и выбор получателей
Принимайте события отказа (bounce), отброшенного письма (dropped), жалобы на спам (spam report), отписки (unsubscribe) и групповой отписки (group unsubscribe) в модель безопасности получателей. SendGrid поддерживает глобальные стоп-листы и группы отписки для разных классов писем. Связывайте каждое промо- или необязательное письмо с правильной группой, предоставляйте понятный способ управления предпочтениями и прекращайте отправку, когда действует соответствующий стоп-лист. Не используйте параметры обхода стоп-листа как обычный способ доставки. Для критичного для продукта письма может понадобиться отдельно задокументированная юридическая и операционная политика, но она не должна незаметно отменять выбор человека в отношении промо-рассылок или защитные механизмы репутации провайдера. Защищайте инструменты поддержки, удаляющие адреса из стоп-листа, строгой авторизацией, видимой причиной и журналом аудита. Отслеживайте постоянные и временные сбои доставки раздельно и проверяйте любое ручное восстановление получателя перед следующей отправкой. Эти меры защищают получателей и сокращают повторные попытки на адреса, которые уже отклонили трафик или отказались от него. Кроме того, они не дают транзакционной отправке унаследовать небезопасное поведение рассылок.
Протестируйте весь жизненный цикл до запуска трафика в продакшене
Начните с ключа SendGrid для непродуктивного окружения и контролируемого аутентифицированного поддомена. Подтвердите DNS, затем отправьте текстовый и HTML-варианты в почтовые ящики, которыми владеет команда. Проверьте ответ `202` и `X-Message-ID` и убедитесь, что подписанные события вебхука сопоставляются с локальной записью об отправке. Проверьте сценарии некорректной полезной нагрузки, отозванного ключа, отсутствующих прав, слишком большого вложения, лимита запросов, отложенной доставки, отказа, отброшенного письма и дублирующего события, не используя реальные адреса клиентов. Убедитесь, что проверка вебхука отклоняет изменённое тело и что обработчик подтверждает приём только после надёжного сохранения. Протестируйте ротацию ключей, откат шаблона, применение стоп-листа и неоднозначный тайм-аут клиента. Добавьте панели мониторинга для сбоев запросов, отставания событий, отложенных доставок, отказов, жалоб на спам и ошибок подписи вебхуков — с идентификаторами тенантов и писем, но без учётных данных и полного содержимого. Наконец, при запуске сверьтесь с актуальной документацией SendGrid и лимитами аккаунта, потому что права по тарифу, региональные функции, квоты и политики провайдера могут меняться независимо от кода приложения.
Сравните зависимости, специфичные для провайдера
Прямая интеграция с SendGrid уместна, когда команда осознанно зависит от специфичных для SendGrid полей запросов, шаблонов, контроля аккаунта, форматов вебхуков, стоп-листов и операционной ответственности. Публичная документация SendHQ описывает email API в рамках рабочего пространства с отправкой с подтверждённого домена, входящей почтой, хранимыми шаблонами, событиями доставки, стоп-листами и веб-панелью управления. Перед миграцией изучите полезную нагрузку (payload), события, средства контроля идентификаторов, стоп-листы, региональные требования и сохранённые идентификаторы двух провайдеров.
Частые вопросы
Означает ли 202 Accepted от SendGrid, что письмо доставлено?
Нет. Это означает, что SendGrid принял API-запрос на обработку. Чтобы узнать, принял ли письмо сервер получателя, используйте события доставки Event Webhook, а попадание во «Входящие» считайте отдельным результатом, который ответ API не устанавливает.
Какие права должны быть у ключа SendGrid для отправки?
Используйте ключ Custom Access, ограниченный возможностью Mail Send, которая нужна воркеру. Не используйте Full Access для обычной отправки и заведите отдельные ключи в менеджере секретов для разработки, стейджинга, продакшена, администрирования и любой другой нагрузки с существенно иными полномочиями.
Как проверять подпись Event Webhook SendGrid?
Сохраните точное исходное тело HTTP-запроса, прочитайте заголовки подписи и временной метки Twilio и проверьте их до разбора JSON или повторной сериализации. Примените защиту от повторного воспроизведения, отклоните запрос при неудачной проверке, а затем надёжно сохраните пакет событий или поставьте его в очередь до подтверждения доставки.
Нужно ли повторять каждый неудачный запрос Mail Send?
Нет. Ошибки полезной нагрузки, аутентификации, авторизации, размера и постоянные ошибки получателя исправляйте, а не повторяйте. При ответах 429 ждите до задокументированного сброса, временные сетевые сбои и ошибки 5xx повторяйте с ограниченной задержкой, а неоднозначные тайм-ауты сверяйте до повторной отправки.
Можно ли обходить стоп-листы SendGrid для транзакционных писем?
SendGrid предоставляет параметры обхода, но продукту не стоит использовать их регулярно. Разделяйте классы писем, соблюдайте применимую отписку или стоп-лист и требуйте задокументированной авторизации и истории аудита для любого исключительного восстановления получателя или решения об отправке по особой политике.
Что команда должна оценить перед сравнением SendGrid и SendHQ?
До планирования миграции сравните полезную нагрузку (payload), события, средства контроля идентификаторов, стоп-листы, региональные требования и сохранённые идентификаторы провайдеров.
Источники
- Обзор Mail Send API — Twilio SendGrid
- Эндпоинт Mail Send — Twilio SendGrid
- API-ключи SendGrid — Twilio SendGrid
- Настройка аутентификации домена — Twilio SendGrid
- Обзор Event Webhook в Twilio SendGrid — Twilio SendGrid
- Справочник по Event Webhook — Twilio SendGrid
- Функции безопасности Event Webhook — Twilio SendGrid
- Лимиты запросов SendGrid API — Twilio SendGrid
- Стоп-листы SendGrid — Twilio SendGrid
- SendGrid API возвращает 202 Accepted, но не отправляет письмо — Twilio Help Center
- Заголовок X-Message-ID — Twilio SendGrid
- Контракт OpenAPI SendHQ — SendHQ