POST /v1/reports/path_to_conversion?project_id={project_id} {
"ResponseType": "JSON",
"Fields": [
"InteractionTime",
"InteractionType",
"MediaCampaignName",
"TargetEventName"
],
"InteractionFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31"
},
"TargetFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31",
"EventType": ["Purchase"]
}
}
curl -X POST "https://api.targetads.io/v1/reports/path_to_conversion?project_id=12486" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ResponseType": "JSON",
"Fields": [
"PathDeviceID",
"PathPosition",
"PathLength",
"InteractionTime",
"InteractionType",
"InteractionMediaCampaignName",
"TargetEventName",
"TargetEcomAmount",
"Weight_MLI",
"Weight_FL"
],
"TargetFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31",
"EventType": ["Purchase"]
},
"Limit": 10000
}' curl -X POST "https://api.targetads.io/v1/reports/path_to_conversion?project_id=12486" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ResponseType": "JSON",
"Fields": [
"PathDeviceID",
"PathPosition",
"InteractionTime",
"InteractionType",
"InteractionMediaCampaignName",
"InteractionUtmSource",
"TargetEventName",
"Weight_MLI",
"Weight_MFI",
"Weight_ML"
],
"InteractionFilter": {
"MediaCampaignId": [12345, 12346]
},
"TargetFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31",
"EventType": ["Purchase"]
}
}' curl -X POST "https://api.targetads.io/v1/reports/path_to_conversion?project_id=12486" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ResponseType": "JSON",
"Fields": [
"PathDeviceID",
"PathPosition",
"PathLength",
"InteractionTime",
"InteractionType",
"InteractionMediaCampaignName",
"TargetEcomId",
"TargetEcomAmount",
"TargetEcomItemsName",
"TargetEcomItemsCategory1",
"Weight_FTDM_30"
],
"TargetFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31",
"EventType": ["Purchase"],
"EcomItemCategory1": ["Electronics", "Books"]
}
}' curl -X POST "https://api.targetads.io/v1/reports/path_to_conversion?project_id=12486" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ResponseType": "JSON",
"Fields": [
"PathPosition",
"InteractionTime",
"InteractionType",
"InteractionUtmSource",
"InteractionUtmMedium",
"InteractionUtmCampaign",
"TargetEventName",
"Weight_FL"
],
"InteractionFilter": {
"UtmSource": ["google", "facebook"]
},
"TargetFilter": {
"DateFrom": "2024-01-01",
"DateTo": "2024-01-31"
}
}' {
"data": [
{
"PathDeviceID": "abc123",
"PathPosition": "1",
"PathLength": "4",
"InteractionTime": "2024-01-10 10:00:00",
"InteractionType": "Impression",
"InteractionMediaCampaignName": "Campaign A",
"TargetEventName": "Purchase",
"TargetEcomAmount": "1500.00",
"Weight_MLI": "0",
"Weight_FL": "0.25"
},
{
"PathDeviceID": "abc123",
"PathPosition": "2",
"PathLength": "4",
"InteractionTime": "2024-01-12 14:30:00",
"InteractionType": "Click",
"InteractionMediaCampaignName": "Campaign B",
"TargetEventName": "Purchase",
"TargetEcomAmount": "1500.00",
"Weight_MLI": "0",
"Weight_FL": "0.25"
},
{
"PathDeviceID": "abc123",
"PathPosition": "3",
"PathLength": "4",
"InteractionTime": "2024-01-14 16:00:00",
"InteractionType": "PageView",
"InteractionMediaCampaignName": "",
"TargetEventName": "Purchase",
"TargetEcomAmount": "1500.00",
"Weight_MLI": "0",
"Weight_FL": "0.25"
},
{
"PathDeviceID": "abc123",
"PathPosition": "4",
"PathLength": "4",
"InteractionTime": "2024-01-15 18:20:00",
"InteractionType": "Click",
"InteractionMediaCampaignName": "Campaign C",
"TargetEventName": "Purchase",
"TargetEcomAmount": "1500.00",
"Weight_MLI": "1",
"Weight_FL": "0.25"
}
],
"count": 4
} # Группировка по путям
paths = {}
for row in data:
device_id = row['PathDeviceID']
if device_id not in paths:
paths[device_id] = []
paths[device_id].append(row)
# Анализ каждого пути
for device_id, touchpoints in paths.items():
path_length = touchpoints[0]['PathLength']
conversion_value = touchpoints[0]['TargetEcomAmount']
print(f"Device {device_id}: {path_length} touchpoints, value {conversion_value}") def calculate_campaign_contribution(data, weight_field='Weight_MLI'):
"""Расчет вклада каждой кампании в конверсии"""
campaign_stats = {}
for row in data:
campaign = row['InteractionMediaCampaignName']
if not campaign:
continue
if campaign not in campaign_stats:
campaign_stats[campaign] = {
'conversions': 0,
'revenue': 0
}
weight = float(row[weight_field])
revenue = float(row['TargetEcomAmount'])
campaign_stats[campaign]['conversions'] += weight
campaign_stats[campaign]['revenue'] += weight * revenue
return campaign_stats def analyze_path_lengths(data):
"""Анализ распределения длины путей"""
path_lengths = {}
for row in data:
if row['PathPosition'] == '1': # Только первое касание
length = int(row['PathLength'])
path_lengths[length] = path_lengths.get(length, 0) + 1
return path_lengths
# Результат: {1: 150, 2: 340, 3: 280, 4: 190, 5: 40}
# 150 конверсий с одним касанием, 340 с двумя и т.д. def analyze_campaign_positions(data):
"""Где в пути чаще встречаются кампании"""
campaign_positions = {}
for row in data:
campaign = row['InteractionMediaCampaignName']
if not campaign:
continue
position = int(row['PathPosition'])
if campaign not in campaign_positions:
campaign_positions[campaign] = {}
campaign_positions[campaign][position] = \
campaign_positions[campaign].get(position, 0) + 1
return campaign_positions Лимиты и ограничения
API имеет технические ограничения, которые следует
учитывать при построении интеграции:
Таймаут: 300 секунд
def get_all_paths(project_id, date_from, date_to):
offset = 0
limit = 100000
all_paths = []
while True:
response = get_path_to_conversion(
project_id=project_id,
date_from=date_from,
date_to=date_to,
offset=offset,
limit=limit
)
all_paths.extend(response['data'])
if len(response['data']) < limit:
break
offset += limit
return all_paths # Отдельно для разных типов конверсий
for event_type in ['Lead', 'Purchase', 'Registration']:
paths = get_path_to_conversion(
target_filter={'EventType': [event_type]}
)
analyze_paths(paths, event_type) # Минимальный набор для анализа атрибуции
fields = [
'PathDeviceID',
'PathPosition',
'InteractionTime',
'InteractionMediaCampaignName',
'TargetEcomAmount',
'Weight_MLI'
] # Запросить данные со всеми весами
fields = [
'PathDeviceID',
'InteractionMediaCampaignName',
'TargetEcomAmount',
'Weight_MFI',
'Weight_MLI',
'Weight_ML',
'Weight_FL'
]
# Рассчитать вклад по каждой модели
for model in ['Weight_MFI', 'Weight_MLI', 'Weight_ML', 'Weight_FL']:
contribution = calculate_campaign_contribution(data, model)
print(f"{model}: {contribution}") def analyze_journey_patterns(data):
"""Найти популярные последовательности касаний"""
patterns = {}
paths = group_by_device(data)
for device_id, touchpoints in paths.items():
pattern = ' -> '.join([
f"{t['InteractionType']}({t['InteractionMediaCampaignName']})"
for t in touchpoints
])
patterns[pattern] = patterns.get(pattern, 0) + 1
return sorted(patterns.items(), key=lambda x: x[1], reverse=True) from datetime import datetime
def calculate_conversion_time(data):
"""Время от первого касания до конверсии"""
paths = group_by_device(data)
conversion_times = []
for device_id, touchpoints in paths.items():
first = datetime.strptime(touchpoints[0]['InteractionTime'], '%Y-%m-%d %H:%M:%S')
last = datetime.strptime(touchpoints[-1]['InteractionTime'], '%Y-%m-%d %H:%M:%S')
hours = (last - first).total_seconds() / 3600
conversion_times.append(hours)
return {
'avg_hours': sum(conversion_times) / len(conversion_times),
'median_hours': sorted(conversion_times)[len(conversion_times) // 2]
}