Publisher API Overview

1. Getting Started

Tapjoy’s Publisher API is designed to help you quickly create and manage your monetization strategy across a portfolio of apps. It is written in GraphQL and requires token-based authorization. For details, please follow these instructions.

You may want to use this API if you plan to launch many apps in a short time frame, or prefer to manage your Tapjoy monetization setups via a custom dashboard.

To test your authentication, you can run this simple query that will list some brief information about your first 3 apps:

query apps {
  publisher {
    apps(first: 3) {
      nodes {
        id
        name
        sdkApiKey
        realWorldCurrency
        timezone        
      }
    }
  }
}

2. Creating an App

If you haven’t already set up your app using the dashboard, then your first step with the API is to create the app you’ll be monetizing.

If your app isn’t live in the App Store or Google Play store yet, no worries. The storeUrl parameter, along with a few other parameters such as orientation, is optional.

mutation createPublisherAppWithStoreUrl {
  createPublisherApp(input: {
    name: "App Created With Store URL",
    platform: ANDROID,
    storeUrl: "https://play.google.com/store/apps/details?id=com.tapjoy.tapout&gl=us",
    orientation: PORTRAIT
  }) {
    app {
      id
      name
      timezone
      realWorldCurrency
    }
  }
}

mutation createPublisherAppWithoutStoreUrl {
  createPublisherApp(input: {
    name: "App Created WithOUT Store URL",
    platform: ANDROID,
    orientation: PORTRAIT,
    currency: KRW,
    timezone: TOKYO_SEOUL
  }) {
    app {
      id
      name
	  timezone
      realWorldCurrency
    }
  }
}

3. Creating a Currency

To monetize with Tapjoy you must create a virtual currency, even if your app itself does not expose one to users. There can be a one-to-many relationship between apps and currencies; but there must be at least one.

Currencies define a very important aspect of advertising - the maturity content of the ads that are appropriate to be shown within your app. Your account manager can answer in-depth questions about maturity, but in general, choosing a currency maturity that is similar to your app’s platform maturity rating will drive the highest possible eCPM while displaying content appropriate for your users.

If your app does not expose a currency to users, then you only need to provide the app ID, a currency name, an exchange rate, and a maturity. If you do not care about exchange rate, then simply provide 100, the default. (More: Virtual Currencies)

mutation createCurrency {
  createCurrency(input: {
    appId: "<PASTE_YOUR_APP_ID_HERE>",
    name: "New Virtual Currency",
    exchangeRate: 100,
    maturity: MEDIUM
  }) {
    currency {
      id
      name
      exchangeRate
      initialBalance
      maturity
    }
  }
}

You can also easily edit existing currencies:

mutation updateCurrency {
  updateCurrency(input: {
    id: "<CURRENCY_ID>",
    maturity: HIGH,
    name: "Shell Bells",
    initialBalance: 100
  }) {
    currency {
      id
      name
      exchangeRate
      initialBalance
      maturity
      callbackUrl
    }
  }
}

4. Creating Placements and Content Cards

Next, you’ll need to create one or more Placements. A Placement is a specific area in your application where you might want to display Tapjoy content your users. When created via the API, you’ll be creating a Content Card contents along with every Placement.

A Content Card defines the types of ads to show, along with powerful settings such as eCPM floors. For example, we can specify a contentType of REWARDED_VIDEO so that the video is not skippable, along with a few per-country eCPM floors. (Currently, the API only supports HARD floors).

Content types

Name Skippable? Rewarded? Programmatic?
PROGRAMMATIC_REWARDED_VIDEO No Yes Yes
PROGRAMMATIC_INTERSTITIAL_VIDEO Yes No Yes
REWARDED_VIDEO No Yes No
INTERSTITIAL_VIDEO Yes No No

CPM floors are in USD, so 5.5 = $5.50.

Please note that eCPM floors cannot be applied to programmatic content cards.

The non-country code XX is reserved for use as “Rest of World”. If XX is the only eCPM floor, this works as a global floor. If other country codes are specified, then XX is a catch-all for all countries that do not match other floors.

mutation createPlacementAndContent {
  createPlacementsAndContents(input: {entries: [
    {
      appId: "<PASTE_YOUR_APP_ID_HERE>",
      placementName: "Placement from API",
      contentType: REWARDED_VIDEO,
      ecpmSettingsToAdd: [
        { price: 5.5, country: "US" },
        { price: 6.5, country: "KR", cpmFloorType: HARD },
        { price: 7.5, country: "JP", cpmFloorType: HARD },
        { price: 7.5, country: "CA", cpmFloorType: HARD }
      ]
    }
  ]}) {
    placements {
      id
      name
      description
      contents {
        id
        name
        type
        isSkippable
        ecpmSettings {
          price
          country
          cpmFloorType
        }
      }
    }
  }
}

You’ll be using the placement.id and content.id to manage them later.

5. Managing eCPM Floors

You can easily update many aspects of Content Cards, including eCPM floors.

For example, let’s remove our eCPM floor for Italy, and raise our Japan floor to $14.

mutation updatePlacementAndContent {
  updatePlacementsAndContents(input: { entries: [
    {
      placementId: "<PLACEMENT ID>",
      contentId: "<CONTENT CARD ID>",
      ecpmSettingsToUpdate: [
        {country: "JP", price: 14.0}
      ],
      ecpmSettingsToDelete: [
        {country: "IT"}
      ]
    }
  ]}) {
    placements {
      id
      contents {
        id
        ecpmSettings {
          price
          country
        }
      }
    }
  }
}

It’s also easy to add a new eCPM floor:

mutation updatePlacementAndContent {
  updatePlacementsAndContents(input: { entries: [
    {
      placementId: "<PLACEMENT ID>",
      contentId: "<CONTENT CARD ID>",
      ecpmSettingsToAdd: [
        {country: "ES", price: 7.0}
      ]
    }
  ]}) {
    placements {
      id
      contents {
        id
        ecpmSettings {
          price
          country
        }
      }
    }
  }
}

6. Error Handling and Atomicity

The API will return errors if provided invalid input, if validation fails, or for a variety of other reasons.

Tapjoy’s Publisher API is atomic. This means that if you perform multiple actions in a single query, the entire query will fail if any constituent step fails. For example, if you attempt to update the eCPM Floors on 4 content cards, and there is a typo in one of the IDs, the entire query will fail and no changes will be made.

7. App Status

If you’d like to see an app’s current setup, simply query its list of placements along with the attributes you’re interested in:

query placements {
  publisher {
    placements(appId: "<APP_ID>") {
      id
      name
      contents {
        id
        name
        type
        currencyId
        isSkippable
        ecpmSettings {
          price
          country
          cpmFloorType
        }
      }
    }
  }
}