API Troubleshooting Tips
Introduction
In this article, we'll cover how to perform basic checks for determining the source of an error, common issue types, and data latency. We'll also describe the kind of information the Criteo team needs to investigate an error.
This article doesn't only refer to errors that the API can produce, but also provides information about its expected behavior.
Is it the error coming from my app or the Criteo server?
These simple checks will help you to separate client-side issues from server bugs.
Connectivity
Requests failing at the origin or blocked by the firewall configurations are surprisingly common. Check your connection by attempting to open a page in your web browser or run the curl command in the terminal. Make sure your personal or organizational firewall is set up to allow connection to Criteo services.
Here are the Criteo sub-networks to be whitelisted by region:
EMEA | APAC | Americas |
---|---|---|
178.250.0.0/21 185.235.84.0/22 91.212.98.0/24 91.199.242.0/24 2a02:2638::/32 | 74.119.116.0/22 199.204.168.0/22 177.73.128.0/21 2620: 100:a000::/44 | 116.213.20.0/22 182.161.72.0/22 2406:2600::/32 |
Tip
For best results, our recommendation is to whitelist the ranges for all DCs even if your server is located only in one of the regions.
In some cases connectivity issues can arise when persistent HTTP/2 connections' termination command is either not issued properly by the server or not correctly processed by the client. Typically, this results in a time-out from the endpoint. In such cases, turning off the keep-alive
property of a connection may help.
Here is an example for Python:
s=requests.session(),
s.keep_alive = False;
....
/// add a parameter into requests:
headers={'Connection':'close'}, req=requests(url, headers)
...
Incorrect request URLs
If you are using variables or path parameters with your request, make sure that the final address is structured correctly. Uninitialized variables can result in the response code 404.
Transient Issues
Transient issues can be resolved by properly implemented retry mechanisms, such as the exponential backoff technique.
Consent issues
Usually if advertiser hasn't given a consent to your app you will get an error in 4xx range. Part 1 of the tutorial covers 4xx error series in more detail here: How to handle API errors.
In order to perform a quick check whether an advertiser has given consent to the app you can query /advertisers/me endpoint and see if it returns advertiser ID that you expect.
Implementation errors
If the request is not formed according to the [specification] (ref:apiv1oauth2tokenpost) or an invalid request header is provided, the server will respond with an error in the 400 code series.
Part 1 of the tutorial covers 4xx error series in more detail here: How to handle API errors.
As mentioned earlier, If you are using variables or path parameters with your request, this would require making sure that the raw request is in expected format.
To get more details on the next steps you can turn on verbose output of your application. Here is how to turn the debug mode on for the Python3 requests library:
import requests
import logging
# Enabling debugging at http.client level (requests->urllib3->http.client)
# you will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# the only thing missing will be the response.body which is not logged.
try: # for Python 3
from http.client import HTTPConnection
except ImportError:
from httplib import HTTPConnection
HTTPConnection.debuglevel = 1
logging.basicConfig() # you need to initialize logging, otherwise you will not see anything from requests
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
requests.get('https://httpbin.org/headers')
If you are using Criteo SDK Libraries you can invoke debug mode in similar fashion. For example, for Java Criteo SDK library calling setDebugging(true) on the instance of com.criteo.marketing.Configuration will enable the output of all request details. Here is how the full code could look like
package com.criteo.marketing.examples;
import com.criteo.marketing.ApiClient;
import com.criteo.marketing.ApiException;
import com.criteo.marketing.ApiResponse;
import com.criteo.marketing.Configuration;
import com.criteo.marketing.api.AnalyticsApi;
import com.criteo.marketing.model.StatisticsReportQueryMessage;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.List;
public class StatisticsApplication {
public static void main(String[] args) {
ApiClient client = Configuration.getDefaultApiClient();
client.setUsername("client_key");
client.setPassword("client_secret");
// Uncomment the following line to enable debugging logs.
client.setDebugging(true);
AnalyticsApi myApi = new AnalyticsApi(client);
...
//Populate statisticsReportQueryMessage
// for more details see "API Client Libraries" section
...
try {
ApiResponse<byte[]> response = myApi.getAdsetReportWithHttpInfo (statisticsReportQueryMessage);
} catch (ApiException e) {
System.out.println(e.getCode());
System.out.println(e.getResponseBody());
}
}
}
Other languages (PHP, Ruby) have similar mechanisms of invoking debug mode in basic HTTP clients.
This will help you to inspect what information is actually being sent to Criteo server.
If you are still not sure whether the issue is with your implementation or something else then feel free to extract the output of debug mode and create a support request. Make sure to eliminate all sensitive information from the logs (e.g credentials, tokens). See the next section to understand on which additional information is helpful when submitting an investigation request to Criteo.
Server bugs
If you are getting an error in the 500 series consistently, this could indicate an issue on the Criteo server-side. You can always check the latest service availability status by visiting https://status.criteo.com/.
If the status page does not explain your issue, get in touch with your Criteo contact.
In your post, please share the following information:
- RequestId or TraceId, if available
- Endpoint and its version
- App name or app ID
- Payload without any identifiers or sensitive information
- Response message without any identifiers or sensitive information
If your query contains private or sensitive information, we will strive to get back to you in a timely fashion via email. In this case, we will also need the advertiser ID, the full payload, and the full response message.
Is the issue that my data is late?
Starting from How to handle API errors - Part 1 to now, we have focused on common issues that can arise with the API.
Let's talk about data and metrics. Data latency can also be mistaken for causing issues. Some metrics may have several hours of latency, while others may seem to have longer delays. The following table provides the maximum and median data delays for different metric groups.
Metric group | Maximum delay* | Median delay* |
---|---|---|
Revenue and basic metrics, including: - Displays, clicks, advertiser cost Revenue metrics - Revenue-based ROI: ECoS and related metrics - Sales and derivative metrics: - Sales data - Conversion data - Conversion-based ROI: CPO, CPI, and related metrics | 12 hours | 5 hours |
Audience metrics: Potential users Exposed users Displays | 19 hours | 7 hours |
Omnichannel metrics | 207 hours | 197 hours |
Retention for most of the data, including sales data is 2 years unless requested by hourly dimension. The Placement Category report, as well as sales report with hourly dimension, have 3 months of retention.
Info
Data freshness guidelines on this page are not official SLAs and therefore maximum delay values are not guaranteed. They reflect the 95th and 50th percentile latency based on the last two weeks of import data. It is your responsibility to assess the precision-error trade-off of your application based on the snapshot of historical data provided above. Official SLAs will be shared at a later date.
Is the issue caused by a data discrepancy?
Whether you are building an aggregator service with Criteo as one of the sources or simply trying to compare the numbers in the Commerce Growth Analytics UI and the API, you may have encountered a situation where the reported numbers in the UI and API are not the same.
As a first step, we need to make sure we have an apples-to-apples comparison by making sure our views are closely aligned.
Dates
Aligning the timezones and the date ranges in the API request body and the platform UI (whether Criteo Commerce Growth or a third-party platform) will resolve the issue most of the time. Check this document for the list of supported timezones.
Attribution scope
Please view this document for the list of supported metrics in the Criteo API.
The naming pattern provided on the metrics page will help you understand how you're comparing the data in different systems. Ask yourself:
- [Devices]: Am I comparing cross-device sales or same-device sales?
- [AttributionModel]: Am I comparing custom attribution sales or default attribution sales?
- [LookbackWindow]: Am I selecting the same attribution lookback period?
In general, the Criteo API allows you to retrieve all possible metrics while Commerce Growth' Analytics module is more focused on the metrics that are deemed relevant to a specific account and its settings.
Technical
Due to the specifics of the billing mechanism, the cost data for the day immediately preceding the current day may be adjusted within a 5% threshold soon after midnight. Please take this into account when determining the refresh window of your connector.
Compliance
In some cases, the metrics could be updated several days after a click occurs. For example, this can happen after removing IVT (invalid traffic).
If you still have questions or suspect you've found a bug, please get in touch with your Criteo contact.
Updated about 1 month ago