[БЕТА] Переход с PBA на Web Performance Measurement

Краткий обзор: Атрибуция People-Based (PBA) заменяется Web Performance Measurement — усовершенствованным решением AppsFlyer для веб-измерений. В этой статье описываются предстоящие изменения, шаги миграции и полное сопоставление полей для ваших отчётов и серверных интеграций.

Почему мы обновляем вашу систему веб- измерений

Веб-измерения важны как никогда. На сайте происходит конверсия многих ваших пользователей, и именно там начинается путь к вашему мобильному приложению. Это не просто целевая страница — это полноценная воронка привлечения с квиз-сценариями, персонализированным онбордингом, пейволлами и веб-магазинами, которые часто приводят пользователей с более высоким намерением по более низкой цене привлечения.

AppsFlyer выводит измерение веб-данных на тот же уровень, что и мобильных. Устаревший веб-продукт АтрибуцияPeople-Based (PBA) заменяется системой Web Performance Measurement, построенной на базовом атрибуционном движке AppsFlyer и единой модели данных. Web Performance Measurement включает всё, что уже умеет PBA, и дополнительно предлагает:

  • Единый источник истины: измерения веб- и мобильных приложений в одном месте, с агрегацией затрат, постбэками оптимизации и оптимизацией креативов.
  • Более эффективные решения по бюджету: гибкая система атрибуции, соответствующая вашей бизнес-логике, позволяет вам сосредоточиться на действительно работающих кампаниях.
  • Улучшенный ROAS: расширенные запросы на оптимизацию в ваши рекламные сети и полноценная серверная настройка, позволяющая фиксировать больше конверсий, чтобы сети могли оптимизировать кампании на основании более качественных сигналов.
  • Реальная кроссплатформенная ROI : измерение каждого пользовательского пути в вебе, в приложении и на любой платформе.
  • Простая, унифицированная отчетность : один дэшборд и один набор отчетов для каждой платформы, которые обновляются каждый час.

Примечание

Для переключения вам потребуется приложить минимальные усилия. Вы сохраняете тот же Web SDK, без каких-либо изменений в коде вашего веб-сайта.

Важно!

Ожидайте некоторых расхождений в цифрах. Логика атрибуции в Web Performance Measurement более продвинутая и гибкая, поэтому показатели PBA не будут совпадать в точности.

Web Performance Measurement против PBA

Функциональность Описание PBA Web Performance Measurement
Данные
Актуальность данных Насколько быстро доступны данные для отчетности? ✗ Ежедневно ✓ Отчеты каждый час, актуальность данных примерно 2 часа
Модель данных Согласование схемы с данными мобильной атрибуции ✗ Отличается от мобильного устройства ✓ Адаптировано для мобильных устройств, легко подключаться и анализировать.
Отчётность
Дэшборд активности Дэшборд по времени события ✓ Поддерживается ✓ Поддерживается
Когортный дэшборд Анализируйте эффективность по когортам привлечения с течением времени. ✗ Не поддерживается ✓ Поддерживается
Сырые данные Data Locker Доступ к необработанным данным атрибуции через экспорт в Data Locker . ✓ Поддерживается ✓ Поддерживается
Детализация на уровне отдельных объявлений Детализация отчета от кампании до уровня отдельных объявлений ✗ Только дэшборд, без сырых данных ✓ Полная детализация кампании как на дэшборде, так и в сырых данных
Кроссплатформенный LTV Объедините веб- и мобильные пользовательские путешествия в единую метрику LTV ✗ Не поддерживается ✓ Поддерживается
Стоимость и сигналы
Стоимость веб-трафика Собирайте и отчитывайтесь о рекламных расходах веб-кампаний. ✗ Не поддерживается ✓ Поддерживается
Постбэки оптимизации Отправляйте сигналы оптимизации обратно в рекламные сети. ✗ Не поддерживается ✓ Поддерживается
Реализация
Web SDK (Pixel) Клиентский SDK для измерения визитов и событий на сайте ✓ Поддерживается ✓ Тот же SDK, никаких изменений в коде не требуется
Поддержка S2S Полноценное измерение посещений и событий на стороне сервера ✗ Только мероприятия ✓ События и посещения. Поддерживает полноценную серверную реализацию.
Атрибуционный движок
Окна атрибуции Настраиваемые окна лукбэка, атрибуции, повторного вовлечения и неактивности ✗ Нажмите только на окно лукбэка ✓ 5 настраиваемых окон (полный контроль)
Пользовательское событие UA Определите, какое событие считается привлечением пользователей после первого посещения. ✗ Только при первом посещении ✓ Любое событие пользователя (например, регистрация, покупка)
Привлечение пользователей против ретаргетинга Раздельный учёт новых привлечений и повторных вовлечений ✗ Нет концепции UA, события привязаны к последнему касанию ✓ Целевые показы для привлечения пользователей и ретаргетинг с двойной атрибуцией

Этапы миграции

В таблице ниже процесс миграции разбит на пять этапов Создание веб-приложения необходимо для всех, а остальные шаги зависят от того, какими возможностями PBA вы пользуетесь сейчас — например, S2S API или отчётами Data Locker.

Действие Актуально для Что включено
Создайте веб-приложение Каждый При создании нового веб-приложения выберите существующий ключ разработчика веб-приложения в поле Web SDK ID . Это позволяет сохранить работоспособность текущего кода вашего веб-сайта без каких-либо изменений. Затем настройте параметры атрибуции в новом приложении.
Перейдите на новый S2S API Использование PBA S2S API Настройте новый S2S API . Он поддерживает как посещения, так и события, что позволяет полностью действовать на стороне сервера. См. приложение о миграции S2S API ниже.
Перейдите к новым отчетам Data Locker Использование отчетов PBA Data Locker Включите новый веб-отчет в пользовательском интерфейсе и настройте вашу бизнес-аналитику/ETL на использование обновленных данных. Новые отчеты построены по единой схеме, используемой на всех платформах, в мобильных приложениях, на веб-сайте, CTV и ПК. См. приложение с сопоставлением полей сырых данных ниже.
Проверить параметры атрибуции Рекомендовано PBA применила собственные правила атрибуции медиаисточника . Web Performance Measuremen использует улучшенное определение источника трафика для повышения точности аналитики. Проанализируйте различия, чтобы понять, какие значения можно ожидать увидеть в отчетах. См. приложение со сравнением определения источника трафика ниже.
Объедините приложения в линейку продуктов Необязательно Создайте продуктовую линейку и сгруппируйте веб-приложение с мобильными приложениями, чтобы разблокировать кроссплатформенную отчетность по LTV клиента (аналогично PBA Brand Bundle).

Примечание

Ожидайте некоторых расхождений в цифрах. Логика атрибуции в Web Performance Measurement более продвинутая и гибкая, поэтому показатели PBA не будут совпадать в точности. Сама логика записи сессиq не изменилась; сессия по-прежнему длится 30 минут активности -- это отраслевой стандарт.

Функции, выводимые из эксплуатации

Функциональность Что меняется Подробности
Путь конверсии Уже устарело.
Веб-ассоциированные установки (заслуга веб-кампании, которая впоследствии привела к установке на мобильном устройстве) Отсутствует отдельный раздел "Установка с помощью веб-браузера".

Переходы «web → app» измеряются с помощью Smart Script и Smart Banner. В кроссплатформенном отчете представлен аналогичный, хотя и не идентичный, анализ. Как и PBA, он основан на CUID:

  • Веб-кампании, которые ранее способствовали установкам, учтённым как органические, теперь отображаются как неорганическое привлечение пользователей. Это не ассисты; веб-кампания является источником привлечения.
  • Веб-кампании, которые способствовали неорганической установке: веб-кампания становится источником привлечения, а мобильная установка — кроссплатформенным ретаргетингом.
Обратный перерасчет Обратный перерасчет не производится после истечения стандартной 30-минутной задержки. Атрибуция завершается с 30-минутной задержкой, что дает пользователям время идентифицировать себя в течение этого окна.
Поля отчетов по необработанным данным Поля, связанные с мобильными приложениями, признаны устаревшими для веб-использования. Некоторые поля переименованы, а некоторые значения изменены. См. приложение с сопоставлением полей сырых данных ниже.
Поздние события S2S События, поступившие позднее, чем через 30 минут после окончания дня по UTC, в течение которого они произошли, по-прежнему принимаются, но время их события заменяется временем получения их AppsFlyer . Отправляйте события в реальном времени, предпочтительно в течение 30 минут после возникновения события, а не объединяйте их в одну ежедневную загрузку. Точность атрибуции зависит от того, насколько быстро после фактического события мы получаем его данные. Точность атрибуции зависит от того, насколько быстро после фактического события мы получаем его данные.

Приложение: изменения в отчетах о сырых данных

Единое сопоставление каждого поля в сыром отчёте PBA (Посещения веб-сайта и События веб-сайта) с новым отчётом События конечного пользователя. Источник: сырые отчёты PBA.

Область охвата: отчет о посещениях веб-сайта PBA и событиях на веб-сайте.

  • Без изменений , то же название поля и те же данные.
  • Переименовано , данные те же, новое название столбца.
  • Переопределено , с тем же или похожим именем, но с изменением формата данных или значения (требуется осторожность перед повторным использованием).
  • Устарело, в новом отчете нет эквивалента.
Название поля Описание Статус Новое поле/примечание
advertising_id Рекламный идентификатор (GAID) Устарело Рекламный идентификатор мобильного устройства, интегрируемый кроссплатформенно в PBA. Кроссплатформенные отчёты по LTV и путям пользователя основаны на CUID и не используют это поле.
af_web_id Идентификатор файла cookie, отправляемый из веб-SDK Переименовано appsflyer_id_value, тот же веб-cookie.
amazon_aid Рекламный идентификатор Amazon Fire TV Устарело Идентификатор мобильного устройства — не относится к вебу.
android_id Идентификатор устройства Android Устарело Идентификатор мобильного устройства — не относится к вебу.
app_id Идентификатор мобильного устройства не применяется к вебу. Устарело Кроссплатформенная мобильный среда. Идентификатор веб-приложения в новом отчёте имеет формат unified_app_id ("website-{domain}"), это другое понятие.
app_name Последнее название приложения Без изменений: app_name.
app_version Последняя версия приложения Устарело Кроссплатформенное мобильное поле, неприменимо к вебу.
appsflyer_id Идентификатор AppsFlyer (установка) Устарело Идентификатор мобильной установки Новыйappsflyer_id_value является веб-cookie (af_web_id ), уникальный идентификатор.
attributed_touch_time Метка времени (атрибутированного) веб-посещения Переименовано event_time__attribution, время атрибутированного контакта (взаимодействия)
attributed_touch_type Тип точки контакта — всегда «посещение веб-сайта». Устарело Постоянное значение в PBA. Функция Visit-vs-event теперь реализована вend_user_event_type (СЕССИЯ / В ПРИЛОЖЕНИИ).
bundle_id Идентификатор пакета PBA Устарело Заменено группировкой по продуктовым линейкам (веб + мобильные приложения) в кроссплатформенном отчете.
campaign Атрибутируется посещению сайта Переименовано campaign_name.
campaign_id Атрибутируется посещению сайта Без изменений: campaign_id.
city Определено по IP-адресу Без изменений: city.
country_code Определено по IP-адресу Без изменений: country_code.
customer_user_id Идентификатор клиента (CUID) Без изменений: customer_user_id.
device_type Тип устройства Переименовано device_categoryЗначения различаются («Настольный компьютер» против МОБИЛЬНЫЙ ТЕЛЕФОН/ТВ».
dma Определено по IP-адресу Без изменений: dma.
event_name Посещения: всегда "посещение веб-сайта". События: отправлено название событие Переопределено Данных по визитам нет (PBA указал «посещение сайта»). Без изменений для событий
event_revenue Сумма дохода от события в валюте покупки Переименовано revenue_value_original.
event_revenue_currency Трехзначный код валюты event_revenue Переименовано revenue_currency_original.
event_revenue_usd event_revenue конвертировано в доллары США Переименовано revenue_usd.
event_source Либо веб-SDK, либо сервер-к-серверу Без изменений: event_source.
event_time Посещения: время посещения. События: время события Без изменений: event_time.
event_type Стандартное событие / событие по конверсия / посещение веб-сайта Переопределено Пометка события конверсии больше не поддерживается. Визит против события находится вend_user_event_type (СЕССИЯ / В ПРИЛОЖЕНИИ).
event_url URL-адрес веб-страницы, на которой произошло событие (равнозначен исходному URL-адрес при посещениях). Без изменений: event_urlТеперь это также основное место для чтения параметров запроса URL (UTM и других)
event_value События: данные о событии в формате JSON. Посещения: null Без изменений: event_value.
idfa Рекламный идентификатор Устарело Идентификатор мобильного устройства — не относится к вебу.
idfv Рекламный идентификатор Устарело Идентификатор мобильного устройства — не относится к вебу.
imei Идентификатор устройства Устарело Идентификатор мобильного устройства — не относится к вебу.
install_time Время последней установки приложения Устарело Кроссплатформенная мобильный среда. Время привлечения веб-пользователя (конверсии) являетсяevent_time__conversion , отдельным понятием.
ip IP-адрес посетителя Переименовано ip_address_value, то же значение, плюсip_address_type для метода хеширования.
language Сообщается агентом пользователя (например, «английский»). Переопределено language Формат значения изменяется на ISO 639-1, добавляется код страны.
media_channel Атрибутируется посещению сайта ("Ad") Устарело Может быть закрыто sub_param_1-5 при необходимости.
media_source Атрибутируется посещению сайта Без изменений: media_source.
media_type Атрибутируется посещению сайта ("Paid") Устарело Пусто для веб-сайта. Показатель «органический против платный» теперь определяется is_organic булевым параметром.
oaid Рекламный идентификатор Устарело Идентификатор мобильного устройства — не относится к вебу.
original_url URL-адрес, который перенаправил пользователя при атрибутированном посещении. Переименовано Объединено вevent_url (во время визитов,event_url равно исходному URL-адресу). Отдельный столбец удалён.
platform Платформа ("macOS", "Windows") Переопределено Платформа всегда "ВЕБ-САЙТ". Операционная система переместилась вos_version /user_agent .
postal_code Определено по IP-адресу Без изменений: postal_code.
query_params Параметры запроса в перенаправляющем URL-адресе как в JSON Устарело Исходная строка запроса находится вevent_url столбец parsed-JSON удалён
referrer HTTP-реферер атрибутированного посещения веб-сайта Переименовано http_referrer.
region Определено по IP-адресу ("NA") Переименовано continentКод континента, например, "NA".
state Определено по IP-адресу Без изменений: state.

Готовый к использованию промпт для агента-кодировщика при миграции ETL в Data Locker

Чтобы упростить переход, мы подготовили готовый промпт для вашего ИИ-агента программирования (Claude Code, Cursor или аналогичного). Предоставьте агенту доступ к существующему ETL-коду и вставьте приведенный ниже промпт; он содержит полное сопоставление полей и все различия в поведении. Он поможет агенту изучить ваш текущий конвейер и перестроить его для нового отчёта.

You are migrating an ETL pipeline from AppsFlyer's legacy PBA Data Locker raw-data reports (Website visits + Website events) to AppsFlyer's Web Performance Measurement Data Locker report (End User Events). Everything you need is in this prompt: the structural changes, the complete field-by-field mapping, and the validation steps. Do not guess anything beyond what is written here; if something is ambiguous, ask me.

## Step 1: Learn the current pipeline

Before writing any code, explore the existing codebase and produce an inventory:
1. Which PBA reports we consume (Website visits, Website events, or both) and where they are ingested.
2. Every PBA field we read, and where each is used downstream (transforms, joins, dashboards, alerts, exports).
3. The load cadence and scheduling assumptions (PBA delivered daily).
4. Any logic that separates or joins visit rows and event rows.
5. Any filters, groupings, or hardcoded values keyed on PBA field values (e.g. media_source names, channel labels, event_type, platform values).

Present this inventory to me and wait for my confirmation before proceeding.

## Step 2: Ask me these questions

1. Is the new End User Events report already enabled in Data Locker (enabled from the AppsFlyer UI)? If not, I need to enable it first.
2. What is our new web app's Unified App ID? Format: "website-{domain}" (e.g. website-www.example.com). If I don't know it, I'll get it from the AppsFlyer dashboard before we continue.
3. Do we want a parallel-run period (old and new pipelines side by side, comparing outputs) or a direct cutover? Recommend parallel-run.
4. Should the new pipeline also consume the Conversions report (unique attribution instances, no duplicate rows) or the cross-platform End User Events report (CUID-deduplicated, web+mobile user-level)? Default scope is the platform-level End User Events report, the direct successor of the PBA reports.

## Structural changes to design around

1. **One report instead of two.** PBA split visits and events into two reports. The new End User Events report holds both: visits are rows with end_user_event_type = 'SESSION', events are rows with end_user_event_type = 'IN_APP'. Only IN_APP rows carry a valid event_name; on SESSION rows event_name is empty (PBA wrote "website visit" there).
2. **One schema across platforms.** The report is shared by website, mobile, CTV, and PC. Always filter platform = 'WEBSITE' to isolate web data.
3. **Dual attribution credit, deduplicate.** The same action can appear twice: a primary-credit row and a secondary-credit row (original UA source, for UA-view LTV). Filter is_primary_attribution = true by default to avoid double-counting. Drop the filter only for dedicated UA-view vs retargeting-view analysis using conversion_type.
4. **Hourly instead of daily.** The new report delivers hourly with approximately 2 hours of data freshness. Redesign incremental loads around hourly batches instead of a daily drop.
5. **Organic vs paid.** PBA's media_type ("Paid") is gone. Use the is_organic boolean; never infer organic/paid from media_source.
6. **User counting.** Count and join users with COALESCE(customer_user_id, appsflyer_id_value), the stable customer user ID first, the cookie-based ID as fallback.
7. **Empty values.** STRING fields are '', NUMERIC fields are NULL.

## Field-by-field mapping (PBA → End User Events)

Status legend: Unchanged = same name and data. Renamed = same data, new column. Redefined = data or value format changes (handle with care). Deprecated = no equivalent.

| PBA field | Status | New field / handling |
|---|---|---|
| advertising_id | Deprecated | Mobile/device ID. Cross-platform reports are CUID-based; drop it. |
| af_web_id | Renamed | appsflyer_id_value, same web cookie. |
| amazon_aid | Deprecated | Mobile/device ID, not relevant for web. |
| android_id | Deprecated | Mobile/device ID, not relevant for web. |
| app_id | Deprecated | Mobile cross-platform field. The new web app identifier is unified_app_id ("website-{domain}"), a different concept, not a rename. |
| app_name | Unchanged | app_name. |
| app_version | Deprecated | Mobile cross-platform field. |
| appsflyer_id | Deprecated | Mobile install ID. Note: the new appsflyer_id_value is the web cookie (PBA's af_web_id), NOT this field. |
| attributed_touch_time | Renamed | event_time__attribution. |
| attributed_touch_type | Deprecated | Was a constant. Visit-vs-event now lives in end_user_event_type. |
| bundle_id | Deprecated | Replaced by the Product Line grouping in the cross-platform report. |
| campaign | Renamed | campaign_name. |
| campaign_id | Unchanged | campaign_id. |
| city | Unchanged | city. |
| country_code | Unchanged | country_code. |
| customer_user_id | Unchanged | customer_user_id. |
| device_type | Renamed + values change | device_category, values differ (e.g. "Desktop" → "MOBILE_PHONE" / "TV" style values). Update any value-keyed logic. |
| dma | Unchanged | dma. |
| event_name | Redefined | Events: unchanged. Visits: now empty (PBA wrote "website visit"). Use end_user_event_type = 'SESSION' to identify visits. |
| event_revenue | Renamed | revenue_value_original. |
| event_revenue_currency | Renamed | revenue_currency_original. |
| event_revenue_usd | Renamed | revenue_usd. |
| event_source | Unchanged | event_source. |
| event_time | Unchanged | event_time. |
| event_type | Redefined | "Conversion event" marking no longer exists. Visit-vs-event lives in end_user_event_type (SESSION / IN_APP). |
| event_url | Unchanged | event_url, now also the primary place URL query params (UTMs, etc.) are read from. |
| event_value | Unchanged | event_value. |
| idfa / idfv / imei / oaid | Deprecated | Mobile/device IDs, not relevant for web. |
| install_time | Deprecated | Mobile field. The web user-acquisition time is event_time__conversion, a separate concept. |
| ip | Renamed | ip_address_value (plus ip_address_type for the hashing method). |
| language | Redefined | language, format changes to ISO 639-1 + country code (was e.g. "English"). |
| media_channel | Deprecated | Can be covered by sub_param_1-5 if needed. |
| media_source | Unchanged | media_source (but see value renames below). |
| media_type | Deprecated | Use the is_organic boolean instead. |
| original_url | Renamed | Consolidated into event_url (on visits, event_url equals the original URL). Standalone column gone. |
| platform | Redefined | platform is always "WEBSITE". The OS moved to os_version / user_agent. |
| postal_code | Unchanged | postal_code. |
| query_params | Deprecated | The raw query string lives in event_url; the parsed-JSON column is gone. Re-implement parsing from event_url if needed. |
| referrer | Renamed | http_referrer. |
| region | Renamed | continent, continent code (e.g. "NA"). |
| state | Unchanged | state. |

## Attributed-value changes (update filters and groupings)

The attribution engine resolves traffic sources differently, so some VALUES change even where field names don't:
- media_source renames: doubleclick_int → dv360_int (Google display/video via UTM); "X Ads" → "Twitter" (Twitter via UTM). More PID values now remap to display names (e.g. iossearchads_int → Apple Search Ads, metweb_int → Facebook Ads, tiktokweb_int → tiktokglobal_int, snapweb_int → snapchat_int).
- Channel labels change format: Direct / Organic search / Social media / Email / Ad / Referral / Other become DIRECT / ORGANIC_SEARCH / SOCIAL_MEDIA / EMAIL / AD / REFERRAL / OTHER.
- Click-ID coverage expanded (more networks resolve from click IDs); dclid alone no longer resolves; fbclid is not used.

Scan the codebase for any filter, CASE, join key, or dashboard grouping keyed on these old values and update them.

## Step 3: Build

1. Propose the new ETL design (ingestion, schema, incremental hourly logic, the mandatory filters from "Structural changes").
2. After my approval, implement it, reusing our existing conventions and infrastructure.
3. For every Deprecated field the inventory found in downstream use, list the consumer and propose a resolution (drop, replace with the suggested alternative, or flag to the business owner).

## Step 4: Validate

1. Run both pipelines on the same day range and compare: visits (SESSION rows) vs PBA website visits, events (IN_APP rows) vs PBA website events, and revenue totals.
2. Expect differences, not equality: the new attribution logic is more advanced, so attributed dimensions (media_source, campaign) will not match PBA exactly. Session counting logic is unchanged (30 minutes of activity), so visit volumes should be in the same ballpark.
3. Verify the is_primary_attribution filter is applied everywhere; its absence shows up as inflated event counts.
4. Produce a short migration report: what was mapped, what was dropped, what changed in values, and any open items for the business owner.

Приложение: Миграция с PBA Web-S2S на новый S2S API

Если вы отправляете события в PBA через API событий Web Server-to-Server (Web-S2S) , перейдите на новый S2S API . Новый API поддерживает и визиты, и события, поэтому ваш сайт может работать полностью на стороне сервера; сервер-к-серверу API PBA принимал только события.

Конечные точки и аутентификация

PBA Web-S2S Новый S2S API
Базовый URL https://webs2s.appsflyer.com https://events.appsflyer.com
Вызов события POST /v1/{bundleId}/event POST /v2.0/s2s/inapps/app/web/{appId}
Вызов посещения Недоступно (посещения осуществлялись только через Web SDK ) POST /v2.0/s2s/visits/app/web/{appId}
Идентификационный вызов POST /v1/{bundleId}/setcuid (отдельный вызов для сопоставления CUID с веб-пользователем) Идентификатор не указан, идентификатор передаётся непосредственно user_id в объекте для каждого события/визита
Идентификатор приложения bundleId (идентификатор пакета бренда) в пути appId = вебunified_app_id ("website-{domain}") в пути
Аутентификация  webDevKey внутри тела JSON при каждом вызове Заголовок авторизации, содержащий ключ S2S API.
Тип контента application/json application/json
Успешный ответ 200 OK 202 приняты

Сопоставление полей полезной нагрузки

Поле PBA Web-S2S Новое поле S2S Примечание
customerUserId user_id.customer_user_id Теперь размещен вuser_id объект.
afUserId user_id.appsflyer_id Теперь размещен вuser_id объект. Отправьте хотя бы один изcustomer_user_id илиappsflyer_id; отправляйте оба, когда пользователь идентифицируется.
webDevKey Удалено из тела. Аутентификация перенесена в заголовок Authorization; приложение идентифицируется по следующим параметрам:appId на пути.
eventType (всегда СОБЫТИЕ) Удаленный Тип определяется конечной точкой (/inapps или /visits).
eventName event_name 1-64 символа; не может содержать@ = + - .
timestamp (Unix мс, 13 цифр) timestamp (Unix ms) Тот же формат. Рекомендуется при каждом вызове; если этот параметр пропущен, AppsFlyer использует время получения.
eventValue event_value Свободная форма; поддерживаетcustom_parameters подобъект.
eventRevenue event_revenue Теперь это необязательно (в PBA это было обязательным для дэшбордов).
eventRevenueCurrency event_revenue_currency Теперь это необязательно (в PBA это было обязательным для дэшбордов).
referrer http_referrer Переименовано.
userAgent user_agent Переименовано.
ip ip Без изменений.
event_url Новый. Обязательно при посещении; необязательно в событиях.
customer_dedup_id Новый. Удаляет дубликаты одного и того же события, поступающего из другого источника (например, из Web SDK).
email_hashed, phone_number_hashed, phone_number_e164_hashed, first_name_hashed, last_name_hashed Новый. SHA-256 (64-символьное шестнадцатеричное число в нижнем регистре) нормализованных значений для обогащения идентификации.

Примечания к S2S API

  • Теперь обработка посещений осуществляется на стороне сервера. Сервис S2S от PBA принимал только события; посещения должны были осуществляться через Web SDK. Новая конечная точка посещений /visits позволяет сайту работать полностью на сервере.
  • Больше нет вызовов setcuid. Для работы PBA требовался Web SDK, поэтому для привязки CUID к веб-пользователю был необходим отдельный вызов. Новый API передает идентификационные данные непосредственно в каждый запрос, поэтому этот шаг отпадает.
  • Окно запаздывающих данных. Отправляйте информацию о событиях и посещениях в реальном времени, предпочтительно в течение 30 минут после возникновения события, а не объединяйте все данные в одну ежедневную загрузку. Данные, поступившие позднее, чем через 30 минут после окончания дня по UTC, в котором произошло событие , все еще принимаются, но время события заменяется временем получения данных AppsFlyer .

Миграция сервисов S2S: готовое к использованию приложение для генерации кода.

Если вы отправляете отчет о событиях через API PBA Server-to-server, мы подготовили готовый к использованию промпт для вашего агента ИИ-программирования (Claude Code, Cursor или аналогичный). Предоставьте агенту доступ к сервису, который отправляет события в AppsFlyer, и вставьте промпт ниже; в нём содержатся полный endpoint и сопоставление полей payload. Это поможет агенту изучить ваше текущее внедрение и создать обновленное.

You are migrating a server-side integration from AppsFlyer's legacy PBA Web S2S events API (webs2s.appsflyer.com) to AppsFlyer's new S2S API for Web Performance Measurement (events.appsflyer.com). Everything you need is in this prompt: endpoints, authentication, the complete payload mapping, and the behavior changes. Do not guess anything beyond what is written here; if something is ambiguous, ask me.

## Step 0: Ask me these questions before touching code

1. Should we modify the existing service in place, or create a new service/module alongside it (allowing a parallel-run and clean cutover)? Recommend a new module alongside.
2. Do I know our new web app's Unified App ID? Format: "website-{domain}" (e.g. website-www.example.com). It replaces PBA's bundle ID in the URL path. If I don't know it, I'll get it from the AppsFlyer dashboard before we continue.
3. Do I have the new S2S API key? Authentication moved from the webDevKey in the request body to an Authorization header carrying this key. If I don't have it, I'll retrieve it from the AppsFlyer dashboard.
4. Do we want to send events only (like PBA), or adopt the new visits endpoint too? The new API supports server-side visits, so the website can run fully server-side; PBA accepted events only.
5. Is the AppsFlyer Web SDK still running on our site? (Determines whether visits come from the SDK and whether we need event deduplication between SDK and S2S.)

## Step 1: Learn the current service

Explore the codebase and produce an inventory:
1. Every call site to webs2s.appsflyer.com, the /event calls and any /setcuid calls.
2. The fields populated on each call (customerUserId, afUserId, eventName, eventValue, eventRevenue, timestamp, referrer, userAgent, ip, etc.) and where their values come from.
3. Error handling and monitoring keyed on the 200 OK response.
4. Retry, batching, and queueing behavior.

Present this inventory to me and wait for my confirmation before proceeding.

## What changed: endpoints and authentication

|  | PBA Web-S2S (old) | New S2S API |
|---|---|---|
| Base URL | https://webs2s.appsflyer.com | https://events.appsflyer.com |
| Event call | POST /v1/{bundleId}/event | POST /v2.0/s2s/inapps/app/web/{appId} |
| Visit call | Not available | POST /v2.0/s2s/visits/app/web/{appId} |
| Identity call | POST /v1/{bundleId}/setcuid | None, identity is inline in the user_id object on every call |
| App identifier in path | bundleId (brand bundle ID) | appId = the web Unified App ID ("website-{domain}") |
| Authentication | webDevKey in the JSON body | Authorization header with the S2S API key |
| Content type | application/json | application/json (415 if missing) |
| Success response | 200 OK | 202 Accepted |

## Payload field mapping

| PBA field | New field | Note |
|---|---|---|
| customerUserId | user_id.customer_user_id | Nested in the user_id object. |
| afUserId | user_id.appsflyer_id | Nested in the user_id object. Send at least one of customer_user_id or appsflyer_id; send both whenever the user is identified. |
| webDevKey | (removed) | Auth moved to the Authorization header; the app is identified by appId in the path. |
| eventType (always "EVENT") | (removed) | The endpoint (/inapps vs /visits) determines the type. |
| eventName | event_name | 1-64 chars; cannot contain @ = + - characters. |
| timestamp (Unix ms) | timestamp (Unix ms) | Same format. Recommended on every call; if omitted, AppsFlyer uses receive time. |
| eventValue | event_value | Free-form; supports a custom_parameters sub-object. |
| eventRevenue | event_revenue | Now optional (PBA required it for dashboards). |
| eventRevenueCurrency | event_revenue_currency | Now optional (PBA required it for dashboards). |
| referrer | http_referrer | Renamed. |
| userAgent | user_agent | Renamed. |
| ip | ip | Unchanged. |
| (new) | event_url | Required on visits; optional on events. |
| (new) | customer_dedup_id | Deduplicates against the same event arriving from another source (e.g. the Web SDK). |
| (new) | email_hashed, phone_number_hashed, phone_number_e164_hashed, first_name_hashed, last_name_hashed | SHA256 (64-char lowercase hex) of normalized values, for identity enrichment. |

## Behavior changes and gotchas

1. **appId is the Unified App ID, not the "Web SDK ID".** The AppsFlyer app settings page shows a "Web SDK ID" UUID (the former Web Dev Key, kept for SDK continuity). The S2S path must carry the Unified App ID ("website-{domain}"), never that UUID. A 401 "app not found" usually means a wrong appId in the path or a missing/invalid Authorization header.
2. **Success is 202, not 200.** Update health checks, retries, and alerting accordingly.
3. **Don't validate against the old endpoint.** The legacy endpoint may still return 200, but that response is not proof that data reached Web Performance Measurement. Always verify events actually appear in the new web app's data.
4. **Drop the setcuid flow entirely.** Identity travels inline in the user_id object on every event and visit.
5. **Visits before events.** The system expects a visit before any event from a user; events for a user with no prior visit are classified as organic. Visits come from the Web SDK, or, new, from the /visits endpoint.
6. **Send in real time; don't batch.** Send every event and visit as it happens, preferably within 30 minutes of the event occurring. Data that arrives later than 30 minutes after the end of the UTC day in which the event occurred is still accepted, but its event time is replaced with the receive time, which distorts attribution. Always send a timestamp. Note that the approximately 30-minute attribution delay you may read about is a separate, server-side hold on AppsFlyer's side, nothing for us to implement.
7. **Full server-side option (if we adopt visits).** With no Web SDK, our server owns the web user identifier: generate a stable ID for first-time visitors, persist it as a server-set first-party HTTP cookie (Set-Cookie header, not JavaScript; JS cookies are capped at approximately 7 days on Safari), reuse it on every request, and send it as user_id.appsflyer_id. The visit payload must include event_url (and should include ip, user_agent, http_referrer for attribution quality).
8. **SDK + S2S together.** If both send the same event, populate customer_dedup_id so AppsFlyer keeps one copy.

## Step 2: Build

1. Propose the design: new client/module, config (base URL, appId, API key storage in our secrets manager, never hardcoded), payload builders for events (and visits, if in scope), and the response/retry handling for 202.
2. After my approval, implement it following our existing conventions.
3. Map every field from the inventory through the payload mapping above; flag any field we currently send that has no new equivalent.

## Step 3: Validate

1. Send a test event (and visit, if in scope) and confirm a 202 response.
2. Verify the test data appears in the new web app in AppsFlyer (dashboard or Data Locker); this is the real success signal, not the HTTP response.
3. Confirm event names comply with the new constraints (1-64 chars, no @ = + -).
4. If running in parallel with the old service, compare event volumes between old and new for a few days before cutover, then decommission the old calls including setcuid.

Приложение: определение источников трафика, PBA против Web Performance Measurement

Если значения источника трафика, канала или кампании отличаются от данных PBA, ниже объясняем, почему. Оба используют одинаковый базовый подход: источник трафика определяется на основе параметров URL и реферера визита путём последовательного обхода списка приоритетов до первого совпадения. Однако несколько правил изменились, и эти изменения смещают показатели, которые вы видите в отчётности. Источники: Правила атрибуции медиаисточника PBA и информация об определении источника трафика .

Значения медиаисточника переименованы.

Триггер Значение PBA Новое значение
Google display/video (utm_source= Google + utm_medium= cpm / display/banner/video/listing) doubleclick_int dv360_int
Twitter через UTM (twitter + cpc) X Ads Twitter

Web Performance Measurement также переназначает больше значений PID на имена отображаемых элементов, например:iossearchads_int в Apple Search Ads,metweb_int к Facebook Ads,twitterweb_int в Twitter,tiktokweb_int кtiktokglobal_int ,snapweb_int кsnapchat_int . Отчеты, основанные на старых сырых значениях, должны учитывать новые значения.

Покрытие Click ID расширилось, а параметр dclid больше не используется.

PBA обработал три идентификатора клика:gclid кgoogleadwords_int ,dclid кdoubleclick_int , иmsclkid кbingsearch_int .

Web Performance Measurement определяет гораздо больше,gclid /wbraid /gbraid кgoogleadwords_int ,msclkid кbingsearch_int ,twclid в Twitter,vmcid кyahoogemini_int ,sccid кsnapchat_int ,li_fat_id кlinkedin_int ,ttclid кtiktokglobal_int ,tbclid кtaboola_int ,ob_click_id /dicbo кoutbrain_int ,yclid кyandex_int ,rdt_cid кreddit_int .

Предупреждение

Два изменения в поведении:dclid больше не используется для определения самостоятельно (PBA определил его какdoubleclick_int ), иfbclid явно не используется.

Расширены пользовательские правила UTM.

Пользовательскоеutm_source +utm_medium сопоставление + в Web Performance Measurement более широкое: оно включает больше синонимов значения medium (paid, paid_search, paid-search и т. д.) и добавляет поддержку TikTok, Snapchat и Pinterest, выходя за рамки узких односредовых правил PBA. Если ни одно пользовательское правило не подходит, оба варианта возвращаются к исходным utm_source значениям.

Канал

Значения канала ттакже изменили формат: вместо Direct / Organic search / Social media / Email / Ad / Referral / Other в PBA теперь используются DIRECT / ORGANIC_SEARCH / SOCIAL_MEDIA / EMAIL / AD / REFERRAL / OTHER Фильтры и группировки, основанные на старых метках, нуждаются в обновлении.