The Offline Conversions API will be discontinued in May 2025. It was previously due to be deprecated in the third quarter of 2024. Starting with Graph API v17.0, the Offline Conversions API no longer supports offline events. Graph API v16.0 is the last version that supports offline events. The Offline Conversions API will be discontinued when v16.0 expires in May 2025. Between now and May 2025, we will be deprecating the remaining Offline Conversions API endpoints on Marketing API v20.0. See the changelog for more details.
In February 2023, we announced that the Conversions API now fully supports offline events. We recommend that advertisers use the Conversions API for new integrations. We also recommend that advertisers with existing Offline Conversions API integrations convert their integration into a Conversions API integration before May 2025 and not update their Offline Conversions API until they have successfully done so. Learn more about the Conversions API.
Use the Offline Conversions API to send offline conversion events and to see how many customers viewed or clicked Meta ads before converting.
To use this API, you need:
If you don't have one, create one.
For access to Marketing API. To create a Meta app:
Rules around app review and permissions depend on how you are implementing our API:
Type Of Implementation | App Review And Permissions |
---|---|
Direct Implementation | In this case, you are an advertiser looking to use offline conversions directly. In this case:
|
Partners Implementing As A Platform | In this case, you are a third-party partner offering offline conversions functionalities for advertisers that use your services. In this case:
|
With system user access, your app can send data to Meta using the API. To create it:
An access token provides access to Meta data. To create system user access tokens:
You need an ad account to run ad campaigns on Meta. To create one, see Marketing API or Business Help Center: About your business settings in Meta Business Manager.
Grant your system user access to your ad account.
These are uploaded files with offline conversion data. When you create an ad, set tracking_spec
to the offline event set ID to correctly attribute events. You can then create event sets, view stats on your imports, delete, and modify this data in Business Manager.
With older implementations, you could do offline event set CRUD operations at the Business Manager level to share event sets with other objects and entities.
You need specific access to create offline event sets, upload, or view data for an event set. You also need this access to assign these permissions to an ad account. You must be one of the following:
ad_account
connected to the offline event setSee Offline Conversion Event Set, Reference.
curl
-F 'access_token=<SYSTEM_USER_ACCESS_TOKEN>'
-F 'name=offline_event_set',
-F 'description=conversion data used for superbowl campaign',
https://graph.facebook.com/<API_VERSION>/<BUSINESS_MANAGER_ID>/offline_conversion_data_sets
Make a HTTP POST
:
POST /<BUSINESS_MANAGER_ID>/offline_conversion_data_sets HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<BUSINESS_MANAGER_ID>/offline_conversion_data_sets
The response includes an event set id
:
{ "id": <OFFLINE_EVENT_SET_ID> }
Parameter | Description |
---|---|
type: string | Event set name. Example: |
type: string | Event set description. Example: |
To assign tracking and read permissions to an ad account:
POST /<OFFLINE_EVENT_SET_ID>/adaccounts HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/adaccounts
Parameter | Description |
---|---|
type: integer | Assign ad account to this business ID. |
type: integer | ID of ad account with offline tracking enabled. |
When you update tracking_spec
, we overwrite it. Make sure to do GET
first, then append the associated String
for the offline event set to the existing tracking_spec
. See Ads Management or use Ads Manager. For example, provide an appropriate tracking spec:
curl \ -F 'tracking_spec=[{action.type:"offline_conversion", dataset:["123"]}]' \ -F 'access_token=<SYSTEM_USER_ACCESS_TOKEN>' \ https://graph.facebook.com/<API_VERSION>/<AD_ID>
To update your ads's tracking spec:
POST /<AD_ID>/?tracking_specs=[{"action.type":"offline_conversion","dataset": <OFFLINE_EVENT_SET_ID>}] HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<AD_ID>/?tracking_specs=[{"action.type":"offline_conversion","dataset": <OFFLINE_EVENT_SET_ID>}]
Parameter | Description |
---|---|
type: string | Track this action for the ad group. Example: |
type: list<id> | ID for offline event set. Example: |
You should upload transaction within 62 days of the conversion. Upload the conversion data:
curl \ -F 'access_token=SYSTEM_USER_ACCESS_TOKEN' \ -F 'upload_tag=store_data' \ -F 'data=[ \ { match_keys: {"phone": ["HASH1","HASH2"], "email": ["HASH3","HASH4"]}, currency: "USD", value: 16, event_name: "Purchase", event_time: 1456870902, contents: [ {id: "A", quantity: 1}, {id: "B", quantity: 2}, {id: "C", quantity: 1} ] custom_data: { }, }, { match_keys: {"lead_id": "12345"}, event_name: "Lead", event_time: 1446336000, contents: [ {id: "A", quantity: 1}, {id: "B", quantity: 2}, {id: "C", quantity: 1} ] custom_data: { event_source: "email", action_type: "sent_open_click", email_type: "email_type_code", email_provider: "gmail_yahoo_hotmail", } }, ]' https://graph.facebook.com/VERSION/OFFLINE_EVENT_SET_ID/events
To send conversions, make a HTTP POST
:
POST /<OFFLINE_EVENT_SET_ID>/events HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/events
Parameter | Description |
---|---|
type: string | Required. Track your event uploads. Example: |
type: | Required. Includes number of events being uploaded. Upload a conversion event per Accounts Center account up to 2,000 events per API call. Example: see example above |
type: integer | Optional. Scope used to resolve Example: |
Use the same upload_tag
for all event upload API calls in the same batch to group them. This helps you debug event uploads, and you should use this for any event uploads made in more than one API call.
Parameters within data
include:
Parameter | Description |
---|---|
type: JSON dictionary | Required. The identifying information we use to match people on Meta. Example: |
type: integer | Required. The UNIX timestamp of the conversion event. Example: |
type: string | Required. Type of event. Example: |
type: string | Required. Three-letter ISO currency code for this conversion event. Required for Example: |
type: double | Required. Value of conversion event. Required for Example: |
type: string | Optional. Any valid Advantage+ catalog ads Example: |
type: JSON array | Optional. Required if you integrate your ads with catalog. Required: Recommended: Required: Recommended: |
type: JSON dictionary | Optional. Information about this conversion event. Example: |
type: string | Optional. Unique identifier for each transaction or order in an offline event set. For example, for retail this can be a receipt ID. Example: |
type: string | Optional. Unique identifier to distinguish events within the same order or transaction. Example: |
For example, you can upload information with the data
field:
{ match_keys: MATCH_KEYS, event_time: EVENT_TIME, event_name: "Purchase", value: 400, currency: "USD", contents: [ { id: "A", quantity: 1, brand: "brand_of_A", category: "Apparel & Accessories | Clothing", price: 100, }, { id: "B", quantity: 2, brand: "brand_of_B", category: "Apparel & Accessories | Shoes", price: 50, }, { id: "C", quantity: 1, brand: "brand_of_C", category: "Apparel & Accessories | Jewelry | Watches", price: 200, } ], }
Use the same upload_tag
for all event upload API calls in the same batch to group them. This helps you debug event uploads, and you should use this for any event uploads made in more than one API call.
match_keys
is a set of identifiers to match people for attribution. See Custom Audiences from CRM Data for normalizing and hashing your data. Only SHA256 is supported and we do not accept unhashed data.
for examples of properly normalized and hashed data for the parameters below.
Parameter names | Parameter | Hashing required |
---|---|---|
Email Address(es) |
| YES |
Phone Number(s) |
| YES |
Gender |
| YES |
Date of Birth |
| YES |
Last Name |
| YES |
First Name |
| YES |
City |
| YES |
US States |
| YES |
Zip codes |
| YES |
Country |
| YES |
Mobile Advertiser ID |
| Do not hash The advertising ID from an Android device or the Advertising Identifier (IDFA) from an Apple device. |
Third-party user id |
| Highly recommended |
The lead id from Lead Ads |
| Do not hash |
The response:
Name | Type | Description |
---|---|---|
| integer | Number of processed entries |
On errors you see an exception including invalid entries and the reason. Fix the errors or skip the data rows with errors and retry the API call.
A Business Manager admin or system user who created the offline event set can retrieve upload stats. Also any admin on the ad_account
which is connected to the offline event set can read this data.
To view stats about offline event sets such as valid entries and matched entries:
GET /<OFFLINE_EVENT_SET_ID>/uploads HTTP/1.1
Host: graph.facebook.com
curl -X GET -G \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/uploads
View daily breakdowns of offline events in Offline Events Manager
in Business Manager. For more precise breakdowns, make this call:
GET /<OFFLINE_EVENT_SET_ID>/stats HTTP/1.1
Host: graph.facebook.com
curl -X GET -G \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/stats
Parameter | Description |
---|---|
type: integer | Optional. The UNIX timestamp. Query events starting at this time. Example: |
type: integer | Optional. The UNIX timestamp. Excludes events that occur this time onward. Example: |
type: | Optional. List of strings. This endpoint provides all fields until v3.0, and after that it provides |
type: boolean | Optional. Returns the average upload delay time in seconds when aggregation time is set to |
type: string | Optional. Aggregate results based on this set time. Options are |
Offline Custom Conversions currently do not backfill. We do not attribute data from event uploads made before you created the custom conversion. You cannot use offline custom conversion data for ads delivery optimization. See Custom Conversion, Reference.
To create a custom conversion using your offline events, make a POST
:
POST /act_<ACCOUNT_ID>/customconversions HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/act_<ACCOUNT_ID>/customconversions
Parameters:
Parameter | Description |
---|---|
type: string | New custom conversion name. Example: |
type: integer | Offline event set ID to track. Example: |
type: string | One of nine Meta Pixel standard events. Example: |
type: JSON-encoded string | Operators and data for your conversion rule. See Custom Conversion, Reference. For example, purchases over USD 100. Example: |
The response, on success:
{ "id": <CUSTOM_CONVERSION_ID> }
You can use the custom_data
field to create rules that later determine if a conversion counts or not. This is similar to Offline Custom Audiences. The maximum number of custom conversions you can have per ad account is 40.
For example, include product category in uploads with custom_data
:
data=[ { match_keys: {"phone": ["<HASH>","<HASH>"], "email": ["<HASH>","<HASH>"]}, currency: "USD", value: 16, event_name: "Purchase", event_time: 1456870902, custom_data: { product_category: "ICECREAM", }, }, ]
Then use custom_data.{YOUR_CUSTOM_PARAM}
to create a Custom Conversion rule:
curl \ -F 'name=Ice Cream Purchasers' \ -F 'custom_event_type=Purchase' \ -F 'event_source_id=<OFFLINE_EVENT_SET_ID>' \ -F 'rule={"and": [{"event_name":{"eq":"Purchase"}},{"custom_data.product_category":{"i_contains":"ICECREAM"}}]}' \ -F 'access_token=<ACCESS_TOKEN>' \ "https://graph.facebook.com/<API_VERSION>/act_<ACCOUNT_ID>/customconversions"
To attribute offline conversion events to your client's ad, follow these steps. The API calls for most of these steps are same as when someone manages their own offline event set and campaign management.
These steps vary depending on how your partner or agency permissions are set up with client ad accounts:
To setup these permissions, see Business Manager Assets.
Share the event set your client's Business Manager. Your client can then use the event set for ads tracking.
GET /<OFFLINE_EVENT_SET_ID>/agencies HTTP/1.1
Host: graph.facebook.com
curl -X GET -G \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/agencies
Parameter | Description |
---|---|
type: integer | ID of your client business manager |
Share offline event sets created by a partner with their client. You need to be the Business Manager admin or admin system user who created the offline event set to enable tracking for ads under and ad account. If you are an admin on the ad account connected to the offline event set, you can also can do this. To make this API call, the business in the call has to have access to the offline event set.
You can assign offline event tracking and viewing permissions to an ad account with this call:
POST /<OFFLINE_EVENT_SET_ID>/adaccounts HTTP/1.1
Host: graph.facebook.com
curl -X POST \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<OFFLINE_EVENT_SET_ID>/adaccounts
Parameter | Description |
---|---|
type: integer | Assign ad account to this business ID. |
type: integer | Ad account ID with offline tracking enabled |
There may be scenarios where you provide your own external ID to represent a customer and match them to someone. To do this, use extern_id
following these guidelines.
Data partners who went through the match process can use partner ID as the namespace ID and extern_id
as your tpid
.
match_keys
We use match_keys
to try to determine if the conversion data you shared can be matched to a Meta user. If you provide match_keys
, you cannot also provide a namespace_id
parameter.
match_keys
and extern_id
We use match_keys
to try to find people on Meta and forward mappings from {dataset_id, extern_id}
to {facebook_user_id}
. If you provide match_keys
and extern_id
, you cannot also provide namespace_id
.
extern_id
If you already sent data with match_keys
and extern_id
, Meta uses {dataset_id, extern_id}
to retrieve a {facebook_user_id}
.
namespace_id
The namespace_id
parameter applies to the entire API call. You can use it to refer to another offline event set that is accessible or owned by a business or a partner profile ID.
If you already sent data with match_keys
and extern_id
, Meta uses {namespace_id, extern_id}
to retrieve a {facebook_user_id}
. You should only provide one extern_id
per row of data.
See offline events attributed to an ad someone viewed or clicked. We attribute offline conversions after more than 1 day. This means you need to set your attribution window to 28d_view
, or action_attribution_windows=['28d_view']'
, otherwise you will not see any conversions in reports. See Insights API and Insights Guide.
GET /act_<ADACCOUNT_ID>/insights HTTP/1.1
Host: graph.facebook.com
curl -X GET -G \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/act_<ADACCOUNT_ID>/insights
Parameter | Description |
---|---|
type: string[] | Break down of impression, click, or conversion data. Grouped by type of action: offline, online, and so on. Example: |
type: string[] | The basic ad metrics. Example: |
type: string | Aggregate or de-duplicate data at this level of reporting results. Example: |
type: string | Relative timeframes to query metrics. Example: |
Results look like this:
{ "data": [ { "date_start": "2015-12-01", "date_stop": "2015-12-01", "actions": [ { "action_type": "offline_conversion.purchase", "value": 1 }, { "action_type": "offsite_conversion.lead", "value": 3 }, ], ... } ] }
For example, to view attribution:
curl -G \ -d 'access_token=<SYSTEM_USER_ACCESS_TOKEN>' \ -d 'fields=unique_actions,action_values' \ https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/insights
The result looks like this:
{ "data": [ { "unique_actions": [ { "action_type": "link_click", "value": 94 }, { "action_type": "offline_conversion", "value": 1 }, { "action_type": "offline_conversion.purchase", "value": 1 }, { .... "value": 1 } ], "action_values": [ { "action_type": "offline_conversion.purchase", "value": 27.5 }, { "action_type": "offline_conversion", "value": 27.5 } ], "date_start": "2016-06-06", "date_stop": "2016-06-07" } ], "paging": { "cursors": { "before": "MAZDZD", "after": "MAZDZD" } } }
For these two APIs, implement data processing options by adding data_processing_options
, data_processing_options_country
, and data_processing_options_state
inside each event within the data parameter of your events.
Note: The App Events and Offline Conversions APIs are no longer recommended for new integrations. Instead, it is recommended that you use the Conversions API as it now supports web, app, and offline events. See Conversions API for App Events and Conversions API for Offline Events for more information.
To explicitly not enable Limited Data Use (LDU), specify an empty array for each event or simply remove the field in the payload:
{ "data": [ { "event_name": "Purchase", "event_time": <EVENT_TIME>, "user_data": { "em": "<EMAIL>" }, "custom_data": { "currency": "<CURRENCY>", "value": "<VALUE>" }, "data_processing_options": [] } ] }
To enable LDU and have Meta perform geolocation:
{ "data": [ { "event_name": "Purchase", "event_time": <EVENT_TIME>, "user_data": { "em": "<EMAIL>", "client_ip_address": "256.256.256.256" }, "custom_data": { "currency": "<CURRENCY>", "value": "<VALUE>" }, "data_processing_options": ["LDU"], "data_processing_options_country": 0, "data_processing_options_state": 0 } ] }
To enable LDU and manually specify the location, e.g., for California:
{ "data": [ { "event_name": "Purchase", "event_time": <EVENT_TIME>, "user_data": { "em": "<EMAIL>" }, "custom_data": { "currency": "<CURRENCY>", "value": "<VALUE>" }, "data_processing_options": ["LDU"], "data_processing_options_country": 1, "data_processing_options_state": 1000 } ] }
The Offline Conversions API offers the option to manually upload your events from a .csv
file. In this case, add Data Processing Options, Data Processing Country, and Data Processing State as columns inside your file. More information about this can be found in the upload user interface.
Learn more about Data Processing Options.