Documentation

Reporting API best practices

Understand the Tapjoy Offerwall Reporting API endpoint, request structure, and error handling to effectively access accurate user acquisition data.
Read time 7 minutesLast updated a month ago

The Reporting API enables advertisers and publishers to access reporting data from the Tapjoy platform and manage their Offerwall content, using the GraphQL query language. For more information on GraphQL, refer to GraphQL's official website.
Use the API Explorer to help build your queries. Select the book icon in the top left corner to expand the Documentation Explorer and find information on the fields and metrics you can use in your queries.
The documentation explorer panel in the Reporting API Explorer after clicking the book icon.

API endpoint

The Reporting API has a single endpoint:
https://api.tapjoy.com/graphql
The endpoint remains the same for every operation.

Communicating with the API

When you have an access token, you can make requests to the API. To form a request, send a JSON-encoded body in an HTTP POST, whether you're executing a query or a mutation.
Refer to the following example request:
POST /graphqlHost: api.tapjoy.comAuthorization: Bearer <OAuth Token>{ "query": "query { user { firstName } }"}

Set time increments and ranges

Use the
timeIncrement
argument to bucket insights:

Value

Result

ALLA single aggregated value for the whole range. Applies when you omit the argument.
DAILYOne value per day.
HOURLYOne value per hour. Valid only for ranges shorter than 1 week.
MONTHLYOne value per month.
NONE
isn't a valid value and returns an
argumentLiteralsIncompatible
error. Use
ALL
for a single aggregate.
The requested range must be at least 1 hour and at most 3 months, and
from
can be no earlier than 2 years ago. Timestamps must be ISO 8601 with a timezone (
2024-03-01T00:00:00Z
). The API rejects bare dates.

Working with errors

You can encounter the following categories of errors when you use the API:
To integrate your system properly, consider how it handles each of these categories of errors.
Note
The Reporting API is atomic. If you perform multiple actions in a single query and any step fails, the entire query fails.
Each of the following error categories uses this query for context:
query { user { firstName lastName }}

Server and network errors

Occasionally you might encounter unrecoverable server or network errors with the API. In these cases, the API returns the HTTP status code for the scenario you encounter. For example, if a problem with the API prevents queries from executing, you receive an HTTP response with a 500 status code.
To handle this scenario, retry the request with exponential back-off.

Limitations

The Reporting API has certain protections in place to prevent excessive or abusive API calls. If your integration exceeds these limits, contact your Tapjoy account manager or support to understand how to optimize your integration or how to increase your limits.
The following examples apply to both advertiser and publisher integrations.

Data retention

The Reporting API can access the last two years of data.

Pagination

When you query a paginated type, you must follow these rules:
  • Supply a
    first
    or
    last
    argument.
  • Request no more than 100 nodes in a single page.
Omitting the pagination argument returns a 422 error. For example, traversing the
campaigns
connection requires
campaigns(first: N)
;
advertiser { campaigns { ... } }
without
first
or
last
fails. The same requirement applies to other paginated connections, such as
adSets
.
If you exceed the maximum value, the API truncates the results and ignores your
first
or
last
argument.
For example:
{ advertiser { adSets(first: 50) { edges { node { id name ads(first: 50) { edges { node { id name } } } } } } }}
The previous query returns a maximum of 50 ad sets, each with a maximum of 50 ads.
To paginate through collections, you must provide an
after
or
before
argument to control where to start the page. For example:
{ advertiser { adSets(first: 50, after: "Mg==") { edges { node { id name } } pageInfo { endCursor hasNextPage } } }}
The previous query returns a maximum of 50 ad sets, starting at the cursor position
Mg==
. The
endCursor
value that an earlier query returns determines that position. Pagination is complete when
hasNextPage
is
false
.
For more information about pagination, refer to the GraphQL documentation.

Call complexity

To pass schema validation, a Marketing API call must not exceed 10,000 calls, where a call is a request for a resource. Because GraphQL lets you combine multiple calls into a single query, the API calculates the total number of calls for a query before it executes that query.
The number of calls is roughly equivalent to the number of resources you select from the result, such as campaigns, ad sets, ads, apps, and insights.
Consider the same example:
{ advertiser { adSets(first: 50) { # <= 50 calls edges { node { id name ads(first: 50) { # <= 50 calls edges { node { id name } } } } } } }}
In this example, you request up to 50 ad sets at a time, and up to 50 ads for each ad set.
To calculate the total number of calls:
50 = 50 ad sets+50 x 50 = 2500 ads = 2550 calls
There's no rate limit for the number of calls per hour.

Insights complexity

Reporting insights that you query at any level incur an additional complexity cost that the previous calculation doesn't reflect. The API adds 1 call to the calculation for each day you query.
Consider the following example:
{ advertiser { # 50 calls adSets(first: 50) { edges { node { id name # 7 calls insights(timeRange: {from: "2024-03-01T00:00:00Z", until: "2024-03-08T00:00:00Z"}) { timestamps reports { country impressions conversions spend } } } } } }}
In this example, you request up to 50 ad sets at a time, and 7 days' worth of reporting data across 3 metrics and 1 segment for each ad set.
To calculate the total number of calls:
50 = 50 ad sets+50 x 7 = 350 insights = 400 calls