Skip to navigation

Enrichment API

Look up Media Ratings Terminal data for a mobile app, CTV app or website, one at a time or in batches.

The Enrichment API returns Pixalate’s Media Ratings Terminal (MRT) data for an app or domain: risk ratings, invalid traffic (IVT), brand safety, viewability, inventory, sellers, COPPA and made-for-advertising (MFA) signals, and more. Use it to vet supply before you buy or sell it, or to add Pixalate’s ratings to your own records.

There is one API per supply type. They share the same request pattern, authentication and quota mechanics, but each returns its own set of fields.

Supply typeSingle lookupBatch lookupMetadata and quotaFields
Mobile appsGET /mrt/apps/{appId}POST /mrt/appsGET /mrt/appsMobile app fields
CTV appsGET /mrt/ctv/{appId}POST /mrt/ctvGET /mrt/ctvCTV app fields
DomainsGET /mrt/domains/{adDomain}POST /mrt/domainsGET /mrt/domainsDomain fields

Before you start

  • API key. Every request needs your Pixalate API key in the x-api-key header. Sign up and get a key at the Pixalate developer portal, or ask your Pixalate account manager. See Authentication and API keys.
  • Base URL. https://api.pixalate.com/api/v2
  • Batch access. Batch lookups require an Enterprise subscription. Contact support@pixalate.com to enable them for your account.

The examples on this page read the key from an environment variable:

export PIXALATE_API_KEY="your-api-key"

Make your first request

Look up one mobile app’s risk overview, aggregated across all regions and devices:

curl -H "x-api-key: $PIXALATE_API_KEY" \
"https://api.pixalate.com/api/v2/mrt/apps/com.example.app?widget=riskOverview&region=GLOBAL&device=GLOBAL&pretty=true"

The response looks like this (values are illustrative):

{
"status": "OK",
"numFound": 1,
"docs": [
{
"appId": "com.example.app",
"region": "GLOBAL",
"device": "GLOBAL",
"appStore": "android",
"riskOverview": {
"ivt": 10.12,
"ivtRisk": "medium",
"viewability": 66.05,
"viewabilityRisk": "medium",
"descriptionBrandSafetyRisk": "low",
"contentBrandSafetyRisk": "low",
"overallIvtPermissionRisk": "low",
"risk": [
{
"region": "GLOBAL",
"device": "GLOBAL",
"pixalateRisk": "medium",
"pixalateRiskReasons": ["Significantly Elevated IVT Percentage"]
}
]
}
}
]
}

Add pretty=true to any request for indented JSON. It’s off by default.

Reading the response

A lookup returns three top-level fields:

FieldDescription
statusOK or ERR.
numFoundThe number of matching apps or domains.
docsThe data records.

Each record in docs is one slice of the app’s or domain’s data. The keys at the top of the record tell you which slice it is:

  • Mobile apps: appId, appStore (ios or android), region and device. A record is one app in one store, for one region and one device type.
  • CTV apps: appId, region and device, where device is the CTV platform. A record is one app on one platform, for one region.
  • Domains: AdDomain, region and device. A record is one domain, for one region and one device type.

The rest of the record holds one object (or array) per widget you asked for. Risk ratings are low, medium or high. The field pages list every field: mobile apps, CTV apps and domains.

Choose the data you need with widgets

A widget is a named group of fields, such as riskOverview, brandSafety, invalidTraffic or mfa. Pass one or more in the widget parameter, comma-separated, to get only those groups:

?widget=riskOverview,invalidTraffic,mfa

If you leave widget out, every widget is returned. The widget changes which fields come back in each record. It doesn’t change how many records come back; region and device do that (see Filter by region and device).

Each supply type has its own widgets:

Supply typeWidgets
Mobile appsappOverview, appDetails, pixalateAdvisories, appAdvisories, riskOverview, developerOverview, trafficOverview, brandSafety, appPermissions, trafficOverlap, authorizedSellers, invalidTraffic, viewability, inventory, ctr, availableCountries, rankings, rankingsByCountry, coppa, mfa
CTV appsappOverview, riskOverview, pixalateAdvisories, appSpoofing, appDetails, developerOverview, channels, brandSafety, trafficOverlap, authorizedSellers, invalidTraffic, inventory, availableCountries, rankings, rankingsByCountry, coppa, mfa
DomainsdomainOverview, riskOverview, domainDetails, trafficQualityRisk, siteRisk, siteInfo, brandSafetyRisk, socialMediaRisk, invalidTraffic, inventory, authorizedSellers, viewability, ctr, trafficSources, subDomains, deviceDistribution, mfa

A widget with the same name can hold different fields in different supply types. For example, the domain mfa widget has three fields the app mfa widgets don’t. Check the field page for the supply type you’re querying.

Filter by region and device

By default a lookup returns a record for every region and device combination. Use region and device to narrow it down. Each takes one value.

Region takes the same values for all three supply types:

ValueMeaning
GLOBALAggregated traffic from all regions
NANorth America
EMEAEurope, the Middle East and Africa
LATAMLatin America
APACAsia-Pacific

Device differs by supply type:

Supply typedevice valuesNotes
Mobile appsGLOBAL, smartphone, tabletGLOBAL aggregates all devices. Records are also split by store.
CTV appsroku, firetvThe CTV platform. There is no GLOBAL value: each platform’s record stands alone and carries that platform’s own app ID.
DomainsGLOBAL, desktop, mobileGLOBAL aggregates all devices.

For most uses, region=GLOBAL&device=GLOBAL is enough: it returns one record per store for a mobile app and one record for a domain. On CTV, use region=GLOBAL for one record per platform, and add device if you need only one platform.

CTV lookups also accept includeSpoofing, which sets whether spoofed traffic counts in the invalid traffic figures. It’s on by default; set includeSpoofing=false to leave spoofed traffic out, like turning off the Include Spoofing toggle in the MRT.

Look up many items in a batch

Each supply type has a batch endpoint that takes up to 5,000 identifiers in one request and produces a downloadable report. Batch lookups require an Enterprise subscription.

1

Prepare the input file

Put one identifier per line in a plain-text file: bundle IDs or track IDs for mobile apps, app IDs for CTV, or domains for the Domains API.

apps.txt
com.example.app
com.example.otherapp
2

Submit the batch

POST the file with content type text/plain. The Mobile Apps batch endpoint accepts the same region and device filters as a single lookup.

curl -X POST \
-H "x-api-key: $PIXALATE_API_KEY" \
-H "Content-Type: text/plain" \
--data-binary @apps.txt \
"https://api.pixalate.com/api/v2/mrt/apps?region=GLOBAL&device=GLOBAL"

The response is a JSON string: the URL where your report will be.

3

Poll for the report

Request the report URL until it stops returning 404 Not Found. While the report is being built you get a 404; once it’s ready you get the report as newline-delimited JSON (NDJSON).

REPORT_URL="https://..." # the URL from the previous step
until [ "$(curl -sL -o report.ndjson -w '%{http_code}' "$REPORT_URL")" != "404" ]; do
sleep 30
done

Then check the final status code. Anything other than 200 means the batch failed:

StatusMeaning
400 Bad RequestProcessing failed because of an invalid query.
413 Request Entity Too LargeThe file contained more than 5,000 identifiers.
500 Internal Server ErrorAny other processing error.

Anyone with the report URL can download the report. The URL contains a randomly generated identifier, so the report stays private as long as you don’t share the URL.

Check database freshness and quota

Call the base path for a supply type, with no identifier, to get its metadata:

curl -H "x-api-key: $PIXALATE_API_KEY" \
"https://api.pixalate.com/api/v2/mrt/apps?pretty=true"

The response tells you when that supply type’s database was last updated and where your quota stands:

FieldDescription
database.lastUpdatedThe date the database was last updated, as YYYY-MM-DD.
quota.availableQuota available for use.
quota.usedQuota used so far.
quota.limitQuota made available each time the quota refreshes.
quota.expiryWhen the quota next refreshes back to the limit, as YYYY-MM-DDTHH:MM:SS.SSSZ.
quota.intervalThe number of time units used to calculate the refresh time.
quota.timeUnitThe time unit used to calculate the refresh time: minute, hour, day, week or month.

Use GET /mrt/ctv and GET /mrt/domains the same way for the other supply types.

How quota works

Enrichment API usage is metered against a quota. The mechanics:

  • One pool per supply type. Mobile apps, CTV apps and domains each have their own quota pool. The pools are independent: using one never draws down another.
  • Input items and output items. Each app or domain you submit (an input item) uses one unit when it’s submitted. Each result returned for it (an output item) uses one more unit. A result is one app or domain for one store, region and device combination (on CTV, one platform and region). So one input item can use several units.
  • Region and device control the count. The widgets you request decide what each result contains. The region and device filters decide how many results you get, so they’re how you control usage. region=GLOBAL&device=GLOBAL returns the fewest results.
  • Batches add up per identifier. Every identifier in a batch file is an input item, and each one’s results are output items, so filters matter even more there.
  • An exhausted pool blocks its whole supply type. When a pool runs out, requests for that supply type are refused, whatever widgets they ask for, until the pool refreshes at quota.expiry. The other supply types keep working.

Your quota limits and refresh period depend on your contract. Check them with the metadata call above, or ask your Pixalate account manager. See also Quotas, limits and errors.

Errors

StatusMeaningWhat to do
400 Bad RequestA parameter in the request is invalid.Check parameter names and values against the lists on this page.
401 UnauthorizedThe API key is invalid.Send a valid key in the x-api-key header.
403 ForbiddenYour subscription has expired or doesn’t cover this request.Contact your Pixalate account manager.
5XXThe API had an internal error.Check your request and retry. If it keeps failing, contact support@pixalate.com.

Batch reports have their own status codes; see Look up many items in a batch.

Worked examples

Check an app’s overall risk and MFA rating before you buy it, with one record per store:

curl -H "x-api-key: $PIXALATE_API_KEY" \
"https://api.pixalate.com/api/v2/mrt/apps/com.example.app?widget=riskOverview,mfa&region=GLOBAL&device=GLOBAL" \
| jq '.docs[] | {appStore, pixalateRisk: .riskOverview.risk[0].pixalateRisk, ivt: .riskOverview.ivt, mfaRisk: .mfa.mfaRisk}'
{
"appStore": "android",
"pixalateRisk": "medium",
"ivt": 10.12,
"mfaRisk": "low"
}

The identifier is the package name for a Google Play app, or the track ID for an App Store app. See Mobile app fields.