Want to boost your ROAS?

Take our on-demand video course on native advertising brought to you by top experts. Enroll now with our limited 30% discount.

Add Native Advertising To Your Marketing Mix After Taking This Course>> Preview
E40000_INVALID_INPUT API error solution for Yahoo Gemini API

Yahoo Gemini Reporting API - Advertiser id not available

The flow to getting data from the Yahoo Gemini reporting API is cumbersome and consists of multiple steps. Here’s a guide how to do it and avoid the common error E40000_INVALID_INPUT - Entity (publisher or advertiser id) not available.

We have previously produced an article on how to go through the Yahoo Gemini API Oauth authentication. And while it is a good resource to get started working with the API, it is easy to get stuck at the next steps as we were made aware by a recent conversation.

Specifically the E40000_INVALID_INPUT - Entity (publisher or advertiser id) not available error code seems to be a recurring issue. Although not necessarily intuitive, it’s luckily easy to get around this easy.

Assuming that you have gone through the Authentication steps from the previous article, you have everything you need for this guide. Let’s start the process of collecting performance reporting data from the API of Yahoo Gemini (Verizon Media Native).

Reminder, a fresh Access Token and the advertiser id

Now depending on how long ago you went throuhg the Authentication process, your Access Token might have expired. This should happen 60 minutes after receiving it. If this is the case, below is how to use your Refresh Token to get a new Access Token.

data = {
    'grant_type': 'refresh_token',
    'redirect_uri': 'oob',
    'code': code,
    'refresh_token': refresh_token
response = post(base_url + 'oauth2/get_token', headers=headers, data=data)
if response.ok:
  access_token = response.json()['access_token']

And let’s test that it’s working and also collect out Advertiser id which will be needed for the next steps.

headers = {
    'Authorization': f'Bearer {access_token}',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
response = get('https://api.gemini.yahoo.com/v3/rest/advertiser/', headers=headers)

The Advertiser id should now be in the response. Use the code below to save it. Keep in mind that this is assuming that you only have one Advertiser or you want the data for your first Advertiser. If that is not the case, you need to explore the other advertisers that are returned in the response.

if response.ok:
    adv_id = response.json()['response'][0]['id']

It could be idea to print it out to make sure you have it before moving on. Overall it should look something like the screenshot below.

Yahoo API Advertiser id

Request a report and get around E40000_INVALID_INPUT

Now we will need to use some additional libraries that will be needed in the following steps. These come with Python so no need to install anything else.

import datetime
import pandas as pd

Next up is deciding the time range that we want performance data for. For this, we use the datetime library to give us today’s date and whichever date we want. For the sake of this guide only data from yesterday will be collected.

report_date_from = (datetime.date.today() - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
report_date_to = (datetime.date.today() - datetime.timedelta(days=1)).strftime("%Y-%m-%d")

In order to do more dates, just change the date in report_date_from. For example days=30 there will give you the data for the last 30 days. The strftime makes sure that the date is formatted in the way that the Yahoo Gemini API reads it.

It is now time to define our cube for the report request. A cube is Yahoo terminology for a json dictionary that contains all information related to creating a performance report. You can read more about cubes on the API documentation. The cube for our example looks like this:

payload = {"cube": "performance_stats",
                   "fields": [
                       {"field": "Day"},
                       {"field": "Campaign Name"},
                       {"field": "Campaign ID"},
                       {"field": "Ad ID"},
                       {"field": "Ad Title"},
                       {"field": "Impressions"},
                       {"field": "Clicks"},
                       {"field": "Spend"},
                   "filters": [
                       {"field": "Advertiser ID", "operator": "=", "value": adv_id},
                       {"field": "Day", "operator": "between", "from": report_date_from, "to": report_date_to}

As you can see, we are including the previously defined Advertiser id and report dates in the cube. The fields and filters can be changed to include other data. For filters the Advertiser id and Day are required, but you can also filter for specific campaigns or hours. The available metrics and filters can be found here in the Yahoo Gemini API documentation.

So far so good. Now let’s actually request the API to create a report for us

E40000_INVALID_INPUT - Entity (publisher or advertiser id) not available

Getting close to the issue here. First defining the url we are making the request to and the headers.

url = 'https://api.gemini.yahoo.com/v2/rest/reports/custom'
headers = {
    'Authorization': f'Bearer {access_token}',
    'Accept': 'application/json',
    'Content-Type': 'application/json'

Then the request

response = post(url + "?reportFormat=json", data=payload, headers=headers)

And the response we are getting:

E40000_INVALID_INPUT - Entity (publisher or advertiser id) not available

E40000_INVALID_INPUT - Solution

All that is actually needed to avoid this issue is to make sure that the cube is really formatted in the json format. In Python this is done by using json.dumps().

So let’s retry

json_payload = json.dumps(payload, separators=(',', ':'))
response = post(url + "?reportFormat=json", data=json_payload, headers=headers)

Looks a lot better:

E40000_INVALID_INPUT - Entity (publisher or advertiser id) not available

How to get the reporting data from the API

You have now successfully requested the report, but more is needed for you to actually get the data. As you might recall from the last the text is the last response, it had a jobId and the status was submitted. This means that the API has started working on generating the report. In order to actually download the report data, you need to make additional requests to see if the report is ready, and when it is then download it. Generally it doesn’t take long for the report to be prepared, but expect to wait a few minutus if you are requesting a lot of data.

Use the following code to check if the report is ready

jobId = response.json()['response']['jobId']
headers = {'Authorization': f'Bearer {access_token}'}
response = get(url + '/{}?advertiserId={}'.format(jobId, adv_id), headers=headers)

If the status is now completed there is a url in the jobResponse which is what you’ll use to collect the actual report. If it’s not yet completed give it a little longer and then try again.

jobResponse = response.json()['response']['jobResponse']
report = get(jobResponse)
if response.ok:
    report = report.json()

This returns a json formatted response with the headers and data fields seperated. There are several ways of cleaning it up. If you are used to working with Pandas, this would directly turn it into a dataframe

pd.DataFrame(report['rows'], columns = [i['fieldName'] for i in report['fields']])

And all of it should look something like this

Performance data from the Yahoo Gemini API

Start adapting the data collection

If you made it to this point you should have successfully got performance data from the Yahoo Gemini API. Now feel free to go back and start making changes to make sure you get all the data you want. Expand the time ranges to collect more historic data and include other relevant fields.

You find the official documentation for the Verizon Media Native API. Information about using the API for reporting here and documentation for campaign management here.

For a better way of collecting Native Advertising performance data, preparing reports and getting insights, check out our Native Ads Reporting and Optimization tool. We are currently offering a free 30 day trial, get in touch for more information.