GraphQL Reporting API Overview

The GraphQL Reporting API is the place to retrieve all of your reporting data. Instead of making multiple API calls, you can retrieve everything you need in a single request. Want to query multiple Advertisables at once? That’s possible with the GraphQL Reporting API.

The GraphQL Reporting API replaces the following API methods:

What is GraphQL?

GraphQL is a query language for APIs. The benefits of GraphQL include:

  • Retrieve only the data you need

  • Access multiple resources at once

  • Evolve without API versions

If you’d like to learn the basics of GraphQL, we recommend reading the official Introduction to GraphQL.

Authentication

For details on how to authenticate, refer to Get Started with the NextRoll API.

Getting Started

To make an API call, you’ll need to write a GraphQL query. Once you’ve written the query, you’ll package that query inside a JSON object. Then you’ll then send that JSON to POST /reporting/api/v1/query. GraphQL uses a single endpoint for all requests.

Alternatively, you could use a GraphQL client library. When using a client library, make sure you configure it to use either Personal Access Tokens or OAuth.

Your First Query

The following is GraphQL query retrieves the name and EID of every Advertisable you have access to:

query MyFirstQuery {
  advertisable {
    forUser {
      eid
      name
      campaigns {
        eid
        name
        metrics(start: "2017-06-01", end: "2017-06-30") {
          summary {
            impressions
            clicks
            cpc
            cpa
          }
        }
      }
    }
  }
}

This becomes the following JSON payload

{
   "query": "query MyFirstQuery { advertisable { forUser { eid name campaigns { eid name metrics(start: \"2017-06-01\", end: \"2017-06-30\") { summary { impressions clicks cpc cpa } } } } } }"
}

Which can then be sent using:

curl -H 'Authorization: Token YOUR_TOKEN' \
    -H 'Content-Type: application/json' \
    -d '{
       "query": "query MyFirstQuery { advertisable { forUser { eid name campaigns { eid name metrics(start: \"2017-06-01\", end: \"2017-06-30\") { summary { impressions clicks cpc cpa } } } } } }"
    }' \
    'https://services.adroll.com/reporting/api/v1/query?apikey=MYAPIKEY'

Which gives us our Advertisables:

{
  "(~˘▾˘)~": "2017.05.24-1/req4561",
  "request": "req4561",
  "version": "2017.05.24-1",
  "data": {
    "organization": {
      "current": {
        "advertisables": [
          {
            "eid": "B0167F8263EE64DEEEC533",
            "name": "Test advertisable",
            "metrics": {
              "summary": {
                "clicks": 100,
                "cpa": 1,
                "cpc": 1,
                "impressions": 200
              }
            }
          }
        ]
      }
    }
  }
}

Note

You can experiment with building queries using GraphiQL

Error Handling

The GraphQL Reporting API uses a custom error structure that differs from standard GraphQL error handling. Understanding this structure is essential for building robust integrations.

Error Response Structure

When errors occur, the API response includes error information at multiple levels:

  • Top-level: has_errors flag and errors array with detailed error messages

  • Object-level: has_errors flag and errors array containing error IDs

  • Parent objects: Propagate has_errors: true up the object hierarchy

Error IDs in object-level errors arrays reference detailed error messages in the top-level errors array. These IDs are unique per request, and multiple objects can reference the same error ID.

Basic Error Handling

The simplest way to handle errors is to check for has_errors: true in the top-level response:

response = make_graphql_request(query)

if response.get('has_errors'):
    # Log errors and retry later
    print(f"Request {response['request']} failed with errors:")
    for error in response.get('errors', []):
        print(f"  {error['id']}: {error['msg']}")
else:
    # Process successful response
    process_data(response['data'])

This approach prevents displaying a mix of correct and incomplete data in your application.

Example Error Response

Here’s an example response with an error:

{
  "(˘▾˘)": "2018.09.11-1/req46209 (production)",
  "data": {
    "advertisable": {
      "byEID": {
        "campaigns": [],
        "eid": "",
        "name": ""
      },
      "errors": [
        "E001"
      ],
      "has_errors": true
    },
    "has_errors": true
  },
  "errors": [
    {
      "id": "E001",
      "msg": "HTTP request failed"
    }
  ],
  "has_errors": true,
  "request": "req46209",
  "version": "2018.09.11-1"
}

In this example:

  1. The top-level has_errors is true

  2. The advertisable object has has_errors: true and references error E001

  3. The top-level errors array contains the detailed message for E001

  4. The request field (req46209) can be used for support investigations

Error Propagation

When any nested object encounters an error:

  1. The object sets has_errors: true and includes error IDs in its errors array

  2. All parent objects up to the root also set has_errors: true

  3. The root errors array contains the detailed error messages

This allows you to:

  • Quickly check the top level to see if any errors occurred

  • Drill down to specific objects to identify which ones failed

  • Access detailed error messages from the top-level errors array

Troubleshooting

If you encounter errors and need assistance:

  1. Save the full response: Include both the query and the complete response

  2. Note the request ID: The request field (e.g., req46209) helps investigate issues

  3. Check error messages: The msg field in the errors array provides details

  4. Contact support: Provide the request ID and error details for investigation

Best Practices

  • Always check has_errors before processing data

  • Log error details including the request ID for debugging

  • Implement retry logic for transient errors

  • Handle partial data carefully: When has_errors is true, either handle the error appropriately or discard the results entirely to avoid displaying incomplete data