Backstage Reporting API Users:

In order to be able to access the Backstage Reporting API service, add the following headers: Authorization: Bearer TOKEN and Authorizer: dsp (not case-sensitive) to each request. The client should be provisioned with both client_id and client_secret for the PROD environment.

To obtain these values, please contact pmp@yahooinc.com. Once the credentials are obtained, follow the below Backstage Reporting API Guide to generate the token and access the Reporting API.


Backstage Reporting API Migration Guide

Overview

This document provides step-by-step instructions for Backstage Reporting API clients to authenticate and execute reports on the Reporting API.

Prerequisites

Endpoints

Environment Reporting API ZTS Token Endpoint
Production https://api.reports.yahooinc.com/v4/ https://id.b2b.yahooincapis.com/zts/v1/oauth2/token

Step 1: Generate an Access Token

Create a JWT client assertion and exchange it for an access token using the OAuth2 client_credentials grant with a JWT bearer client assertion (RFC 7523).

Environment aud claim value
Production https://id.b2b.yahooincapis.com/zts/v1

Note: aud is the ZTS base path, not the full token endpoint URL.

JWT Header

{
  "alg": "HS256",
  "typ": "JWT"
}

JWT Assertion Claims

{
  "aud": "<ZTS audience from table above>",
  "iss": "idb2b.dsp.dspapi.<your_client_id>",
  "sub": "idb2b.dsp.dspapi.<your_client_id>",
  "iat": "<current_epoch_seconds>",
  "exp": "<current_epoch_seconds + 3600>",
  "jti": "<random_uuid>"
}

Build the JWT (Python one-liner)

JWT=$(python3 -c "
import time, uuid, base64, hmac, hashlib, json
def b64url(d): return base64.urlsafe_b64encode(d).decode().rstrip('=')
CLIENT_ID, CLIENT_SECRET, AUD = '<client_id>', '<client_secret>', '<zts_audience>'
header = {'alg':'HS256','typ':'JWT'}
iat = int(time.time())
payload = {'aud':AUD,'iss':f'idb2b.dsp.dspapi.{CLIENT_ID}','sub':f'idb2b.dsp.dspapi.{CLIENT_ID}','iat':iat,'exp':iat+3600,'jti':str(uuid.uuid4())}
hb = b64url(json.dumps(header,separators=(',',':')).encode())
pb = b64url(json.dumps(payload,separators=(',',':')).encode())
si = f'{hb}.{pb}'
sig = hmac.new(CLIENT_SECRET.encode(), si.encode(), hashlib.sha256).digest()
print(f'{si}.{b64url(sig)}')
")

Token Exchange Request

curl -X POST "<ZTS_TOKEN_ENDPOINT>" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Accept: application/json" \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "scope=api-client" \
  -d "realm=dsp" \
  --data-urlencode "client_assertion=$JWT"

Expected Response

{
  "access_token": "eyJ0eXAiOiJKV1Qi...",
  "token_type": "Bearer",
  "expires_in": 21600
}

Step 2: List Reports

Verify the token works by listing available reports. Use the optional platform query parameter to limit the response to report templates for a specific platform alias, such as 1M. Omit the parameter to return all report templates the authenticated user can access.

curl -s \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Authorizer: dsp" \
  "https://api.reports.yahooinc.com/v4/report-management/report?platform=1M"

Expected: HTTP 200 with a JSON array of report objects.


Step 3: Get Report Details

Fetch details for a specific report template.

curl -s \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Authorizer: dsp" \
  "https://api.reports.yahooinc.com/v4/report-management/report/<REPORT_ID>"

Expected: HTTP 200 with report template details including columns, filters, and parameters.


Step 4: Execute a Report

Submit a report generation task.

curl -s -X POST \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Authorizer: dsp" \
  -H "Content-Type: application/json" \
  -d '{
    "reportTemplateId": "12345678910",
    "reportParameters": {
      "sd": ["2026-04-24T00"],
      "ed": ["2026-04-30T23"],
      "ocOrgId1M": ["<ORG_ID>"]
    }
  }' \
  "https://api.reports.yahooinc.com/v4/report-management/reporttask"

Expected: HTTP 200 with a task ID.

Notes:


Step 5: Poll Task Status (and Fetch Data)

curl -s \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Authorizer: dsp" \
  "https://api.reports.yahooinc.com/v4/report-management/reporttask/<TASK_ID>"

Expected: HTTP 200. Poll until "status": "COMPLETED" (typically completes within a few seconds for small ranges).

Important: When status == COMPLETED, the report payload is returned inline in the same response under data.blocks[]. There is no separate /data endpoint on this API version — calling /reporttask/<TASK_ID>/data returns HTTP 404.

Response Shape

{
  "status": "COMPLETED",
  "data": {
    "blocks": [
      {
        "fields": [
          { "sqlAlias": "scaledDay1M",          "name": "Date",        "trending": false },
          { "sqlAlias": "adsDelivered1M",       "name": "Impressions", "trending": false },
          { "sqlAlias": "publisherRevenueRtb1M","name": "Net Revenue", "trending": false }
        ],
        "rows": [
          { "fields": { "scaledDay1M": 0000000000000, "adsDelivered1M": 00000, "publisherRevenueRtb1M": 99.99 }, "trendingFields": {} }
        ],
        "total": { "fields": { "adsDelivered1M": 9999999, "publisherRevenueRtb1M": 999.99 }, "trendingFields": {} }
      }
    ]
  }
}

Required Headers (All Requests)

Header Value Purpose
Authorization Bearer <access_token> Authentication
Authorizer dsp Routes to DSP authentication provider