Introduction
App Conversions allows mobile app developers to track and measure user interactions and conversions within their mobile apps. It enables developers to send app events directly from their apps to advertising platforms' servers, providing valuable data for ad optimization and tracking the effectiveness of their app marketing campaigns.
With App Conversions, developers can track various app events, such as app installs, app opens, in-app purchases, and other user interactions. These events are sent to advertising platforms, where advertisers can use them to target specific audiences and optimize their ad campaigns for better performance.
Get Started
The following sample packages can be installed for App Conversions in Swift.
Note
Async/await is a modern concurrency feature introduced in Swift 5.5 and above — versions earlier than 5.5 cannot use it!
import Foundation
import Alamofire
import SwiftyJSONExtended Device Information
Send device information, such as screen width and height, in your app event call using /{app-id}/activities?extinfo. Values are separated by commas and must be in the order indexed in the /application/activities reference guide. When using extinfo, all values are required.
versionmust bea2for Androidversionmust bei2for iOS
Get Mobile Cookies for iOS
We encourage you to associate app events with an advertiser_id. However, for Android devices and iOS devices earlier than iOS 6, you can also use the attribution parameter set to the mobile cookie of the device.
Note
Mobile cookies are not derived from any user or device attributes. These cookies are not persistent and are designed to be refreshed frequently. Do not use mobile cookies for re-targeting ads.
The mobile cookie is created by Facebook iOS apps using CFUUIDCreateString and is a 128-bit UUID string representation. Get both the cookie ID and the IDFA and send them to Facebook as an identifier:
ASIdentifierManager *manager = [ASIdentifierManager sharedManager];
NSString *advertiserID = [[manager advertisingIdentifier] UUIDString];
if (advertiserID) {
// do stuff
}Set Up Deduplication
The deduplication mechanism is required to remove duplicate event traffic between the Conversions API integration and all other existing integrations you have with app events, including the SDK and App Events API.
For app events, we apply the same deduplication functionality that exists for web events. The logic leverages event_id and event_name based deduplication (Conversions API and SDK / App Events API events that carry the same event_id). The event_id parameter is an identifier that can uniquely distinguish between similar events. Inaccurate event IDs may cause your conversion to be wrongly deduplicated, further impacting conversion reporting and campaign performance.
Here is an example of how to log a custom event. To do so, pass the name of the event as an AppEvents.Name in the iOS SDK:
import FBSDKCoreKit
// Generate a unique event ID
let eventId = UUID().uuidString
// Define the custom event_id parameter
let eventIDParameter = AppEvents.ParameterName("event_id")
// Prepare event parameters with AppEvents.ParameterName keys
let parameters: [AppEvents.ParameterName: Any] = [
eventIDParameter: eventId,
.currency: "USD",
.value: 9.99
]
// Log the event with parameters
AppEvents.logEvent(.purchased, parameters: parameters)
// Send the same event_id via Meta Event SDK for server-side tracking
let capiEvent = Event(
eventName: .purchased,
eventTime: Date(),
eventId: eventId, // Use the same eventId
// Include other necessary properties
)
MetaEventSDK.sendEvent(capiEvent)Install events
For app install events, there is already a deduplication mechanism that makes sure only one install is attributed in the last 90-day window. We keep the first event and drop the later ones no matter the action source. No extra deduplication is required for install-related events.
Events
Please implement the following events in your app:
1. Purchase Event
class ApiClient {
// The base URL for the API endpoint
private let BASE_URL = "https://cpi.ssevt.com/push"
private let token = "YOUR_BEARER_TOKEN"
// Function to send a POST request to the API
func sendPostRequest() async {
// Define the media type for the request body (application/json)
let mediaType = "application/json"
// Create the JSON body
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Order ID or Transaction ID For Purchase Event
"et": "Purchase", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"currency": "USD",
"value": 142.54,
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London",
// Add other optional properties here
// ...
// Required
"contents": [
["id": "ABC123", "quantity": 1],
["id": "DEF456", "quantity": 1]
],
// Required
"content_type": "product"
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]
// Convert the JSON body to Data
guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonBody, options: []) else {
print("Error: Unable to create JSON data")
return
}
// Perform the POST request asynchronously using Alamofire with await
do {
var urlRequest = URLRequest(url: URL(string: BASE_URL)!)
urlRequest.httpMethod = HTTPMethod.post.rawValue
urlRequest.setValue(mediaType, forHTTPHeaderField: "Content-Type")
urlRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") // Adding Bearer Token
urlRequest.httpBody = jsonData // Adding JSON data
let response = try await AF.request(urlRequest).responseJSON()
let json = JSON(response.value ?? "")
print("Response: \(json)")
} catch {
print("Error: \(error.localizedDescription)")
}
}
}The other events reuse this client
Only the jsonBody changes between events. The sections below show the body for each event — the Alamofire request code stays exactly the same as in the Purchase example.
Parameter List
| User information | Parameter | Format | Example |
|---|---|---|---|
| Anonymous ID* | anon_id | Unique ID — do not hash | 123456abc |
| Advertising ID (IDFA / GAID)* | madid | Unique ID — do not hash | 7497f910905fb413fe27a64a557778063 |
| em | Lowercase + SHA256 hash | [email protected] | |
| First name | fn | Lowercase + SHA256 hash | john |
| Last name | ln | Lowercase + SHA256 hash | doe |
| Telephone | ph | Only numbers, incl. country and area code + SHA256 hash | 12125357525 |
| Gender | ge | A single lowercase letter, f or m + SHA256 hash | f |
| Birthday | db | Only numbers: year, month, day + SHA256 hash | 19910526 for May 26, 1991 |
| City | ct | Lowercase, no spaces + SHA256 hash | newyork |
| Postal / zip code | zp | Only numbers + SHA256 hash | 34000 |
| Country | cn | Two-letter country code, lowercase + SHA256 hash | tr |
PII Hashing
Every personal identifier except anon_id and madid must be normalized and SHA256-hashed before sending. Use our PII Hashing guide and live tool to verify your hashes.
2. View Content Event
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Any Unique Identifier
"et": "ViewContent", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"currency": "USD",
"value": 142.54,
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London",
// Add other optional properties here
// ...
// Required
"contents": [
["id": "ABC123", "quantity": 1],
["id": "DEF456", "quantity": 1]
],
// Required
"content_type": "product"
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]3. Add To Cart Event
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Any Unique Identifier
"et": "AddToCart", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"currency": "USD",
"value": 142.54,
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London",
// Add other optional properties here
// ...
// Required
"contents": [
["id": "ABC123", "quantity": 1],
["id": "DEF456", "quantity": 1]
],
// Required
"content_type": "product"
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]4. Lead Event
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Any Unique Identifier
"et": "Lead", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London"
// Add other optional properties here
// ...
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]5. Complete Registration Event
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Any Unique Identifier
"et": "CompleteRegistration", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London"
// Add other optional properties here
// ...
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]6. Contact Event
let jsonBody: [String: Any] = [
// Required
"eid": "d290f1ee-6c54-4b01-90e6-d701748f0851", // Any Unique Identifier
"et": "Contact", // Event Name
"ua": "App", // App Static Value
"p": [
// Required
"event_time": 1644778428,
"platform": "ios",
"os_version": "16.5.1", // iOS version
"att": 1, // Advertiser Tracking Enabled
"ate": 1, // Application Tracking Enabled
"device_model": "Iphone 5,1",
"app_id": "id123456789",
// Optional
"screen_width": 762,
"screen_height": 1278,
"device_timezone": "Europe/London"
// Add other optional properties here
// ...
],
// Advanced Matching Parameters
"amp": [
// Required
"anon_id": "123456abc", // The ID of a person who has installed the app anonymously
"madid": "7497f910905fb413fe27a64a557778063", // Apple's Advertising Identifier (IDFA)
// or Google Android's advertising ID
// Optional
"ph": "8a187a62e69697497f910905fb413fe27a64a5577780636db7b18305e57cacaf", // Phone
"em": "55e79200c1635b37ad31a378c39feb12f120f116625093a19bc32fff15041149", // Email
"ge": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111", // Gender
"db": "d5234ccb6fb4dd59cbe76a3e5e1f396c27d2862246c7dbd7bc9e8fd72d664aaf", // Date Of Birth
"ct": "350c754ba4d38897693aa077ef43072a859d23f613443133fecbbd90a3512ca5", // City
"zp": "3ebb904517b0c6cf6b2d387f1e5f0ba715258125efc4012d88c4053d0da62233", // Zip Code
"cn": "79adb2a2fce5c6ba215fe5f27f532d4e7edbac4b6a5e09e1ef3a08084a904621" // Country
]
]