API S2S для Web Performance Measurement позволяет отправлять веб-посещения и события в AppsFlyer напрямую с вашего сервера, обходя ограничения браузера, такие как блокировщики рекламы и ограничения cookie. Используйте его вместе с Web SDK или отдельно, чтобы получить более полные и качественные данные атрибуции.
О S2S API для веб-атрибуции
AppsFlyer поддерживает два способа отправки веб-данных для атрибуции: Web SDK (на стороне клиента) и S2S API (server-to-server, или S2S). Вы можете использовать каждый из этих методов по отдельности или комбинировать их в зависимости от ваших настроек и потребностей.
Web SDK работает в браузере. API S2S вместо этого позволяет отправлять те же данные с вашего собственного бэкенда. Вот почему это важно: браузеры и блокировщики рекламы, ориентированные на конфиденциальность, включая Safari ITP, Firefox ETP и Brave, могут заблокировать или ограничивать измерение на стороне клиента. По оценкам отрасли, блокировка на уровне браузера затрагивает 25–40 % веб-пользователей. Поскольку S2S-запросы инициируются вашим сервером и никогда не проходят через браузер, на них эти ограничения никак не распространяются.
Как это работает
- Пользователь посещает ваш веб-сайт или запускает событие в браузере.
- Ваш сервер получает событие.
- Ваш сервер отправляет событие непосредственно на сервер AppsFlyer для идентификации.
Зачем использовать S2S
Вот что дает вам использование API S2S, с разбивкой по преимуществам:
- Измеряйте события на стороне сервера: Некоторые конверсии вообще не попадают в браузер, например, продление подписки, обрабатываемое в бэкенде , или события, инициированные в CRM-системе. S2S — единственный способ интегрировать их в AppsFlyer и привязать к нужной кампании.
- Расширенный охват измерений: Вызовы S2S исходят с вашего сервера, а не из браузера, поэтому к ним не применяются блокировщики рекламы, лимиты cookie Safari ITP и другие браузерные ограничения. Вы можете отслеживать посещения и конверсии, которые невозможно зафиксировать с помощью одних только измерений на стороне клиента.
- Обогащение данных из бэкенда: С помощью S2S ваш сервер может добавлять к событиям дополнительные данные перед их отправкой, включая Customer User ID, хешированные адреса электронной почты или номера телефонов, атрибуты CRM, статус подписки или любые внутренние идентификаторы. Это улучшает разрешение идентификаторов и повышает качество сигналов.
- Безопасность: Ключи разработчика, пользовательские идентификаторы и любые добавленные данные остаются на вашем сервере и передаются по защищённому соединению, обеспечивая вам полный контроль над тем, что покидает вашу инфраструктуру.
Спецификация API
Базовый URL: https://events.appsflyer.com
Аутентификация
Все запросы должны содержать действительный токен API S2S и корректный тип контента в заголовках запроса.
| header | Тип | Описание |
|---|---|---|
Авторизация |
Ключ API |
Ваш токен S2S API включен в заголовок в следующем формате: Авторизация: Bearer {s2s-token} |
Content-Type |
наименование налога на чистую выручку | Должно бытьapplication/json . Обязательно для всех запросов. |
Примечание
Для создания токена API S2S см. инструкции в разделе «Управление токенами AppsFlyer» .
Измерить событие
POST /v2.0/s2s/inapps/app/web/{appId}
Измеряет веб- событие (например, покупку, регистрацию или действие клиента) для конкретного приложения.
Параметры пути
| Параметр | Необязательно | Описание |
|---|---|---|
appId |
Необязательно |
unified_app_id как определено в AppsFlyer. Например: website-www.example.com
|
Тело запроса
| Поле | Тип | Необязательно | Описание |
|---|---|---|---|
user_id |
объект | Необязательно | Идентификатор пользователя. Идентификатор пользователя Должен содержать хотя бы один из следующих элементов:customer_user_id илиappsflyer_id . |
Установите как TRUE или FALSE |
наименование налога на чистую выручку | Необязательно | Название события Формат: Строка. 1–64 символа. Не может содержать@ = + - . Пример: af_purchase
|
event_revenue |
число (двойное) | НЕОБЯЗАТЕЛЬНОЕ | Сумма дохода для событий покупки или монетизации. |
SDK (пакет средств разработки ПО) |
строка (ISO-4217) | НЕОБЯЗАТЕЛЬНОЕ | Код валюты для значения дохода. Например: USD или EUR
|
event_value |
объект | НЕОБЯЗАТЕЛЬНОЕ | Произвольные параметры события. Поддерживаетcustom_parameters подобъект. |
event_url |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | URL страницы, где произошло событие. Допустимый URL-адрес HTTP (не более 4096 символов) |
Атрибуция |
целое число (int64) | НЕОБЯЗАТЕЛЬНОЕ | Время Unix в миллисекундах (UTC). Если значение не указано, AppsFlyer использует время получения. Если параметр опущен, AppsFlyer использует время получения Окно позднего приёма: события должны поступить не позднее 00:30 следующего календарного дня в часовом поясе приложения. |
ip |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | IP адрес устройства (IPv4 или IPv6). Максимально 46 символов |
user_agent |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | Полная строка пользовательского агента из браузера. Максимально 1,024 символов |
http_referrer |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | URL-адрес страницы, с которой был осуществлен переход. |
af_customer_event_id |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ |
Ваш собственный уникальный идентификатор события, который вы используете для дедупликации конверсий на платформах рекламных сетей. AppsFlyer передает его в сеть как идентификатор события. Отправляйте его в любом из следующих случаев:
Когда вы его отправляете, также передавайте то же значение в событии пикселя самой сети (например, Если не указать его, AppsFlyer сгенерирует собственный идентификатор, и рекламная сеть не сможет сопоставить события пикселя. Ограничения: Максимум 256 символов. Сопоставление выполняется с точным учетом регистра. |
email_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованного (в нижнем регистре, без пробелов) адреса электронной почты. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
phone_number_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 номера телефона. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
phone_number_e164_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 номера телефона E.164 (например,+14155552671 ). Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
first_name_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованной фамилии. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
last_name_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованной фамилии. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
Пример запроса
{"user_id":{"customer_user_id":"15667737-366d-4994-ac8b-653fe6b2be4a"},"event_name":"af_purchase","event_revenue":49.99,"event_revenue_currency":"USD","af_customer_event_id": "550e8400-e29b-41d4-a716-446655440000","event_value":{"af_content_id":"SKU-001","af_quantity":2,"custom_parameters":{"promo_code":"SUMMER10"}},"event_url":"https://example.com/checkout/success","timestamp":1712000000000,"ip":"35.244.183.10","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...","email_hashed":"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"}Ответы
| В. Статус | Обзор |
|---|---|
| 202 приняты | Запрос принят. Возвращает статус, сообщение и, при необходимости, опциональный параметрmessageId . |
| 400 Неверный запрос | Недопустимые или отсутствующие поля. |
| 401 Не авторизовано | Приложение не существует или аутентификация не пройдена. |
| 403 Запрещено | Трафик приложения заблокирован. |
| 415 Неподдерживаемый тип медиа |
Content-Type должно бытьapplication/json . |
Измерить посещение
POST /v2.0/s2s/visits/app/web/{appId}
Измеряет количество посещений страниц для данного веб-приложения. Этот конечный пункт использует все базовые поля, что и конечный пункт событий, с двумя ключевыми отличиями: event_url обязательно, а поля имени события и дохода не применяются.
Параметры пути
| Параметр | Необязательно | Обзор |
|---|---|---|
appId |
Необязательно |
unified_app_id как определено в AppsFlyer. Например: website-www.example.com
|
Тело запроса
| Поле | Тип | Необязательно | Обзор |
|---|---|---|---|
user_id |
объект | Необязательно | Идентификатор пользователя. Идентификатор пользователя Должен содержать хотя бы один из следующих элементов:customer_user_id илиappsflyer_id . |
event_url |
строка | Необязательно | URL посещенной страницы. Допустимый URL-адрес HTTP (не более 4096 символов) |
Атрибуция |
целое число (int64) | НЕОБЯЗАТЕЛЬНОЕ | Время Unix в миллисекундах (UTC). Если значение не указано, AppsFlyer использует время получения. Если параметр опущен, AppsFlyer использует время получения Окно позднего одобрения: заявки на посещение принимаются не позднее 00:30 следующего календарного дня по времени часового пояса приложения. |
ip |
строка | НЕОБЯЗАТЕЛЬНОЕ | IP адрес устройства (IPv4 или IPv6). Максимально 46 символов |
user_agent |
строка | НЕОБЯЗАТЕЛЬНОЕ | Полная строка пользовательского агента из браузера. Максимально 1,024 символов |
http_referrer |
строка | НЕОБЯЗАТЕЛЬНОЕ | URL-адрес страницы, с которой был осуществлен переход. |
event_value (значение события) |
объект | НЕОБЯЗАТЕЛЬНОЕ | Произвольные параметры события, включая под-объектcustom_parameters. |
customer_dedup_id |
строка | НЕОБЯЗАТЕЛЬНОЕ | Идентификатор дедупликации, предоставленный клиентом. |
email_hashed |
строка | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованного адреса электронной почты. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
phone_number_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 номера телефона. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
phone_number_e164_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованного имени. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
first_name_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованной фамилии. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
last_name_hashed |
наименование налога на чистую выручку | НЕОБЯЗАТЕЛЬНОЕ | SHA256 нормализованной фамилии. Должна представлять собой шестнадцатеричную строку длиной в 64 символа. |
Пример запроса
{"user_id":{"appsflyer_id":"1234567890abcdef","customer_user_id":"15667737-366d-4994-ac8b-653fe6b2be4a"},"event_url":"https://example.com/products/sneakers","timestamp":1712000000000,"ip":"35.244.183.10","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...","http_referrer":"https://www.google.com/","email_hashed":"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"}Ответы
| В. Статус | Описание |
|---|---|
| 202 приняты | Запрос принят. Возвращает статус, сообщение и, при необходимости, опциональный параметрmessageId . |
| 400 Неверный запрос | Недопустимые или отсутствующие поля. |
| 401 Не авторизовано | Приложение не существует или аутентификация не пройдена. |
| 403 Запрещено | Трафик приложения заблокирован. |
| 415 Неподдерживаемый тип медиа |
Content-Type должно бытьapplication/json . |
Настройте полную интеграцию на стороне сервера.
Если вы запускаете Web SDK совместно с S2S, используйте вместо этого Извлечение Web SDK afUserID . Этот раздел предназначен только для интеграций без SDK.
Если на вашем сайте вообще не работает Web SDK , вы несёте ответственность за все, что он обычно делает: присвоение пользовательского cookie, передачу правильных идентификаторов и обеспечение полноты данных каждого события. При правильной настройке вы получите все преимущества, описанные в разделе «Почему стоит использовать S2S» , но это зависит от правильной проработки следующих деталей.
Отправляйте визиты, а не только события
Посещение содержит параметры атрибуции, на которых основывается каждое последующее событие, и система ожидает посещения до любого события пользователя. Если вы отправляете событие перед посещением, система классифицирует его как органическое.
Присвойте файл cookie первой стороны через HTTP.
Поскольку на сайте не используется Web SDK, который мог бы установить afUserIdcookie за вас, назначать и управлять им придётся самостоятельно – это должен быть HTTP-cookie, задаваемый в Set-Cookieзаголовке ответа, а не cookie на стороне клиента, созданный на JavaScript.
Вот почему это важно: срок действия cookie-файла на стороне клиента (устанавливается черезdocument.cookie) истекает быстро: всего за 7 дней в Safari или за 24 часа в доменах, находящихся под управлением ITP. После истечения срока действия идентификатор сбрасывается, и вернувшийся посетитель выглядит как новый. Файл cookie, установленный вашим сервером, не подпадает под это ограничение и может сохраняться в течение максимального срока, установленного браузером (Chrome разрешает до 400 дней). Его также можно пометитьHttpOnly таким образом, что скрипты страницы и блокировщики рекламы не могут прочитать или удалить его, и он вообще не зависит от каких-либо скриптов, запущенных на странице.
Как задать и прочитать его:
- При первом запросе от посетителя, у которого нет cookie, сгенерируйте на своем сервере стабильный уникальный идентификатор (например, UUID).
-
Верните его в собственном файле cookie:
Set-Cookie: af_web_id=<generated-id>; Max-Age=34128000; Path=/; Secure; HttpOnly; SameSite=Lax - При каждом последующем запросе считывайте значение из входящего заголовка Cookie и используйте его повторно. Не генерируйте его заново.
- Отправляйте это значение в AppsFlyer при каждом вызове как
appsflyer_idв составе объекта запросаuser_id.
Вы можете назвать cookie-файл как угодно; AppsFlyer считывает отправленное вами значение , а не название cookie-файла. Просто убедитесь, что вы указываете его своего собственного домена.
При каждом вызове отправляйте правильные идентификаторы.
Каждый вызов требует объектuser_id, имеющий хотя бы один из параметров:appsflyer_id ( значение cookie) илиcustomer_user_id (ваш внутренний идентификатор пользователя). Отправка обоих, если они у вас есть, повышает точность идентификации.
Вот что следует помнить: посещения в основном анонимны, поэтому всегда отправляйте значение cookie. Для событий на сайте добавляйте customer_user_id после идентификации пользователя и продолжайте передавать cookie вместе с ним. Для событий, которые не инициируются в браузере, достаточноcustomer_user_id, если AppsFlyer уже знает этого пользователя из ранее идентифицированной сессии.
Что следует учесть
Идентификация пользователя
Объектuser_id требуется при каждом запросе. Необходимо указать хотя бы один из следующих идентификаторов.
| Поле | Тип | Описание |
|---|---|---|
Тип конверсии ретаргетинга |
строка (от 1 до 64 символов) | Ваш внутренний идентификатор пользователя, установленный в вашей системе. |
appsflyer_id |
строка (минимум 1 символ) | Внутренний идентификатор AppsFlyer для веб-пользователя. Если вы используете AppsFlyer Web SDK, тоappsflyer_id значение извлекается из cookie-файла Web SDK . Извлечь его изafUserId . См. Извлечение Web SDK afUserIdWeb SDK afUserId
|
Поздние сроки принятия
Информация о мероприятиях и посещениях должна быть получена не позднее 00:30 следующего календарного дня по времени часового пояса приложения. В случае задержки события учитываются по времени получения данных сервером.
Хэшированные поля PII
Все поля с персональными данными должны быть хешированы с помощью алгоритма SHA256 перед отправкой. Перед хешированием выполните нормализацию текста (преобразование в нижний регистр, обрезка). Каждый хеш должен состоять ровно из 64 шестнадцатеричных символов (регистр не имеет значения).
- Шаблон для всех хешированных полей:
^[a-fA-F0-9]{64}$ - Номера телефонов, использующие поле
phone_number_e164_hashedдолжны соответствовать формату E.164 (например,+14155552671) перед хешированием.
Извлечение afUserID из веб-SDK
-
afUserId— это уникальный идентификатор, устанавливаемый Web SDK при первом посещении пользователем вашего сайта. - Если вам нужен
afUserId, воспользуйтесь одним из следующих способов.
Получение afUserId из заголовка HTTP cookie
- Значение
afUserIdотправляется браузером посетителя при обращении к вашему сайту. - При необходимости извлеките его из заголовка HTTP cookie.
Просмотр afUserId в браузере посетителя
- Просмотрите
afUserIdв браузере посетителя, чтобы устранить неполадки и для отладки. - Чтобы параметр стал доступен, посетитель должен хотя бы один раз зайти на страницу с веб-SDK.
- Файл cookie, содержащий
afUserId, является файлом cookie первой стороны по отношению к вашему домену. - Следующая процедура была подготовлена с использованием Chrome 81. Возможны различия в зависимости от браузера и операционной системы.
Чтобы получить afUserId из браузера посетителя:
- В своём браузере перейдите на свой сайт.
- Нажмите на правую кнопку мыши, выберите Проверить. Откроется окно браузера для проверки элементов.
- Перейти на вкладку (A) Заявка.
- В боковом меню (B) раскройте Cookies.
- Выберите свой сайт. Если он не отображается, обновите браузер.
- В поле (C) фильтр введите
afUserId. Отобразится значение afUserID.
Отправка событий через Segment (CDP)
Вы можете использовать Segment для маршрутизации событий в ваш S2S API. (Segment — это платформа данных о клиентах, инструмент, используемый для сбора клиентских событий и их отправки в настроенные назначения.)
Web SDK и Segment — это два отдельных параллельных пути в AppsFlyer, а не один, подпитывающий другой: Web SDK продолжает отправлять визиты, которые содержат параметры атрибуции, а Segment отправляет события для ресурсов, где нет SDK. Ни один из этих путей не знает о другом; они пересекаются в AppsFlyer, где визит связывается с его событиями с помощью идентификатора, который вы отправляете по обоим путям.
Примечание:
Здесь рассматриваются веб-события, отправляемые по S2S из пользовательского назначения Segment. О мобильной обертке SDK Segment, которая связывает установки приложения и события в приложении с мобильным SDK AppsFlyer, см. статью Интеграция с Segment; это другая интеграция для другой платформы.
Настройте назначение в Segment
В AppsFlyer пока нет готового назначения Segment для S2S API, поэтому вам нужно настроить его как пользовательское назначение в Segment, которое будет отправлять каждое событие в конечную точку S2S. Это можно сделать двумя способами — в зависимости от того, насколько большой контроль над форматом данных вам нужен.
Вариант 1: назначение Webhooks (Actions)
Это рекомендуемая отправная точка. Код не требуется, а вся настройка выполняется в пользовательском интерфейсе Segment.
Чтобы настроить это, выполните следующее:
- В Segment добавьте назначение Webhooks из каталога назначений.
- Подключите его к источнику, который собирает события, которые вы хотите отправить.
- Для каждого типа события создайте сопоставление, которое определяет URL-адрес AppsFlyer, задаёт метод POST, добавляет необходимые заголовки и формирует JSON-данные из полей события.
Вариант 2: функция назначения
Используйте этот параметр только в том случае, если сопоставление Webhooks не может сформировать формат данных, который нужен AppsFlyer. Функция назначения — это небольшая функция JavaScript, которая выполняется в Segment, получает каждое событие и отправляет его в конечную точку AppsFlyer через fetch.
Используйте этот параметр, когда:
- Для данных нужна вложенная структура — например,
user_id, вложенный в объектuser, — которую пользовательский интерфейс сопоставления Webhooks не может построить. - Перед отправкой данные события нужно преобразовать, например изменить формат метки времени.
Конечная точка AppsFlyer
Какой бы вариант настройки вы ни использовали, укажите эту конечную точку:
POST https://events.appsflyer.com/v2.0/s2s/inapps/app/web/website-{your_domain}
Authorization: Bearer {s2s-token}
Content-Type: application/json
Получите свой ключ API S2S на странице управления токенами AppsFlyer (см. Аутентификация). В пути используйте идентификатор веб-приложения (например, website-www.your_domain), а не UUID Web SDK ID на странице настроек приложения.
Данные для каждого события
Сформируйте тело JSON для каждого сопоставленного события со следующими полями:
{
"user_id": {
"customer_user_id": "<ваш внутренний идентификатор пользователя>",
"appsflyer_id": "<значение cookie afUserId, если доступно>"
},
"event_name": "signup",
"event_url": "<URL-адрес страницы, на которой произошло событие>",
"ip": "<IP-адрес конечного пользователя>",
"user_agent": "<user_agent конечного пользователя>",
"af_customer_event_id": "<messageId в Segment>"
}
Два правила, которые обеспечивают работу атрибуции
- Web SDK должен работать на маркетинговом сайте: он фиксирует посещения, а Segment передаёт события. Как указано во введении к этому разделу, перед событием у пользователя должно быть посещение, иначе событие будет атрибутировано как органическое. Если вы хотите полностью серверную настройку без использования Web SDK, следуйте инструкциям в разделе Настройка полностью серверной интеграции.
- Для каждого запроса также нужны правильные идентификаторы: отправляйте ту же комбинацию
appsflyer_idиcustomer_user_id, которая описана в разделе Отправляйте правильные идентификаторы при каждом запросе.
Проверьте настройку
Когда назначение и данные готовы, выполните развертывание в три этапа:
- Сопоставьте одно или два события в Segment (для начала хорошо подойдет событие регистрации) и отправьте тестовое событие с помощью инструмента проверки сопоставления.
- Убедитесь, что они корректно отображаются в отчете с необработанными данными и сопоставляются с посещением маркетингового сайта.
- После подтверждения расширьте сопоставление на остальные события.
Рекомендуемый порядок развертывания
Когда назначение и данные готовы, выполните развертывание в три этапа:
- Сопоставьте одно или два события в Segment (для начала хорошо подойдет событие регистрации) и отправьте тестовое событие с помощью инструмента проверки сопоставления.
- Убедитесь, что они корректно отображаются в отчете с необработанными данными и сопоставляются с посещением маркетингового сайта.
- После подтверждения расширьте сопоставление на остальные события.