Standard Yahoo Conversion API

Prev Next

The standard integration to the Yahoo Conversion API (CAPI) can be used to send data directly or via integrated partners for campaign measurement, attribution and optimization.

This CAPI integration is a direct replacement for Yahoo Dot pixels and uses the same rules engines and attribution configured in a Yahoo DSP seat.

Important

CAPI supports identifiers that do not rely on cookies, leverages secure privacy protocols and enables advertisers to have full control over the data sent to the platform.

The end-to-end process for activating against CAPI works as follows:

  1. Create authentication credentials via an OAuth 2.0 connection.

  2. Yahoo creates a new set of encrypted credentials.

  3. Yahoo generates an allow-list with a unique Pixel ID for the API POST call.

  4. Work with Yahoo to create new rules in the Yahoo DSP that describe the targeting and/or conversion audience.

  5. POST events to CAPI.

Create a Pixel ID (yp ID) in the Yahoo DSP

Important

When using Yahoo Dot pixels, this firing can be viewed through the .yp parameter. Do not use the same pixel ID that is currently in use on a site in order to maintain clean tracking and avoid conversion count duplication.

  1. Under your Advertiser in the DSP, navigate to the Tracking tab.

  2. Click Create New and Pixel.

    The unique pixel ID is generated.

  3. Copy the pixel ID from this newly created pixel to use in the POST endpoint.

    Do not use this pixel code for website tracking.

Endpoints

Batch Conversions Endpoint

This is the default endpoint for all integrations. When using the batch conversion endpoint, data is processed once a day.

POST https://batch.datax.yahoo.com/v1/events/<pixelId>

Streaming Conversions Endpoint

When using the streaming conversion endpoint, data is processed multiple times a day.

POST https://streaming.datax.yahoo.com/v1/events/<pixelId>

Headers

Content-Type: application/json

Accept: application/json

Authorization: Bearer <access_token>

POST body - JSON keys

Required and Supported Fields

The required fields for a successful JSON body POST are described in the table below. Normalize all values to lowercase.

Note

CAPI supports multiple identity keys, the “userData” fields listed in the table below, to match the event. Multiple keys can be sent to improve match rates. One or more device IDs, email addresses, phone numbers or Partner Match IDs (pxid) are required.

While not a user ID, the “clickData” identifier is a click ID. This may be used to match events when user IDs are not available or permitted.

Field

Type

Required/Optional

Description

eventTs

Integer

Required

The timestamp of the event in either seconds or milliseconds. For example,1746558464

actionSource

Enum

Required

The digital or physical source of the event. For example, web, app, phone, email, online, physical_store.

actionSourceUrl

String

Optional

The URL of the website where the conversion occurred. Null in case of some actionSources. For example, phone or physical_store.

country

String

Optional

Two characters. For example, US.

region

String

Optional

For example, APAC, NA, EMEA, LATAM or ROW.

userData

Object

Required.

The wrapper object for all user data. At least one ID must be provided or clickData must be included.

userData.email

List<string>

Optional

SHA256 hashed email addresses.

userData.phone

List<string>

Optional

SHA256 hashed phone numbers.

userData.gpsaid

List<string>

Optional

The Android advertising ID.

userData.idfa

List<string>

Optional

The Apple advertising ID.

userData.pxid

List<string>

Optional

3rd party external identifier. Format: pxIdSrcId + ‘:’ + pxIdValue. Provider source ID will be provided by Yahoo to the advertiser.

privacy

Object

Optional

The wrapper object for all privacy data.

privacy.privacy_type

Enum/String

Required

Determines the applicable privacy regulation or mode. Must be set to one of:

  • GPP: Global Privacy Platform

  • GDPR: EU General Data protection regulation (TCF)

  • OPTOUT: attribution-only mode. Excludes user for optimization and does not include consent strings.

privacy.consent_string

String

Required if privacy_type= GPP or GDPR

Forbidden if privacy_type=OPTOUT

The consent string representing the user’s privacy preferences.

  • For GPP, send a valid GPP string

  • For GDPR, send a valid TCF string

privacy.gpp_sid

List<integer>

Required if privacy_type=GPP

List of GPP section IDs that are active in the consent string. Each number corresponds to a privacy section as defined by the IAB Tech Lab.

eventName

String

Optional

The type of event action that triggers the event. For example, addToCart, Purchase

  • Use eventName to create a rule for Event Type Action.

eventData

Object

Optional

The wrapper object for commerce event data.

eventData.price

Number

Optional

The numerical value of any given conversion.

  • By default, the value is assumed to be USD.

  • This will be reported as Dynamic Conversion Value in the DSP.

eventData.products

Array

Optional

  • Use category to create a rule for Event Type Category in the DSP UI.

  • Use subCategory to create a rule for Event Type Label in the DSP UI.

    For example,

    products : {

    category : string,

    subCategory : string

    }

eventData.customKeyValues

Map<string,string>

Optional

Custom key value pairs.

clickData

Object

Optional

Accepts Yahoo Click ID, vmcid, and Taboola Click ID, tblci.

Note

Yahoo DSP supports customKeyValues via CAPI. These values represent custom named keys for use in the DSP. Not all 3rd party integrations to CAPI support customKeyValues. Please check with your integrated vendor to confirm.

Sample Event

The following sample CAPI payload ties to an audience-building rule for a specific pixel ID built out in the Yahoo DSP.

Add a Conversion Rule to a line in the DSP coupled with sending a CAPI Payload.

In UI Conversion Rule

When creating rules in the DSP UI, ensure values are lowercase to match the API payload.

CAPI Payload

Sample Payload

{
    "eventTs": 1733508168,
    "actionSource": "web",
    "actionSourceUrl": "http://store.com",
    "country": "USA",
    "region": "NA",
    "userData": {
      "email" : [ "536a09742acb5b4ec7c7d6c0e20a5d3f4318817817353b69f8ee15f27d3fc9fa",
        "7ebd20af4a7ff32eb6331c108cb1aa2176c195f7f1b472fc7ebfd2051f89f8a1" ],
      "gpsaid" : ["c2f11fe5-3600-4ade-901e-5cf84f2d71a5"],
      "phone" : ["1036636844eea8b0c54623eee63eb5d83ad5b86c02cfa7a8da29a3c140c9b100",
        "f4ef23f72996f81f2bbc90929eb7d1e6397cba597cbbd70b5afa717ad41e500f"],
      "pxid" : ["999:XY50038zETeXJBOYNTRn7Z3T6VSkxDF5ZpRz3wvPEVmt1ZXHo"]
     },
     "eventName": "test_action",
     "eventData": {
        "price": 12.99,
        "products": [
          {
          "category": "test_category",
          "subCategory": "test_label"
          }
         ]
     },
     "clickData": {
        "vmcid": "vmcid123456"
     },
}

Sample Payload With Privacy Object

{
   "eventTs":1733508168,
   "actionSource":"web",
   "actionSourceUrl":"http://store.com",
   "country":"USA",
   "region":"NA",
   "userData":{
      "email":[
         "536a09742acb5b4ec7c7d6c0e20a5d3f4318817817353b69f8ee15f27d3fc9fa",
         "7ebd20af4a7ff32eb6331c108cb1aa2176c195f7f1b472fc7ebfd2051f89f8a1"
      ],
      "gpsaid":[
         "c2f11fe5-3600-4ade-901e-5cf84f2d71a5"
      ],
      "phone":[
         "1036636844eea8b0c54623eee63eb5d83ad5b86c02cfa7a8da29a3c140c9b100",
         "f4ef23f72996f81f2bbc90929eb7d1e6397cba597cbbd70b5afa717ad41e500f"
      ],
      "pxid":[
         "999:XY50038zETeXJBOYNTRn7Z3T6VSkxDF5ZpRz3wvPEVmt1ZXHo"
      ]
   },
   "privacy":{
      "privacy_type":"OPTOUT"
   },
   "eventName":"test_action",
   "eventData":{
      "price":12.99,
      "products":[
         {
            "category":"test_category",
            "subCategory":"test_label"
         }
      ]
   },
   "clickData":{
      "vmcid":"vmcid123456"
   }
}

Output

{
"success": true
}

OAuth 2.0 Authentication

CAPI is a server-to-server implementation that requires OAuth 2.0 authentication before any data can be posted to Yahoo Ad Tech servers.

OAuth 2.0 is a mechanism that relies on continuously generating authentication tokens and then providing those tokens during the posting of data.

Important

Yahoo does not support OAuth 1.0, which depends on static tokens.

Step 1 Request Client Credentials

Step 2 Generate the JSON Web Token (JWT)

Step 3 Complete the Post-Credential OAuth 2.0 Workflow

Step 4 Use Access Token to Call CAPI Endpoint

Request Client Credentials

Note

Requesting client credentials includes an internal allowlist approval process that may require additional time for the setup to be completed.

  1. Generate a private key.

    >> openssl genpkey -aes256 -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem
  2. Generate a public key using the above private key.

    >> openssl rsa -in private_key.pem -out public_key.pem -outform PEM -pubout
  3. Send the public key to the Yahoo Account Team.

  4. Yahoo will then send a file containing credentials encrypted with the above public key to use.

  5. Decrypt the file with the private key.

    >> openssl rsautl -decrypt -inkey private_key.pem -in credential.enc -out my_credentials.txt

Generating JSON Web Token (JWT)

The JSON Web Token is composed of three main parts:

  • Header: normalized structure specifying how the token is signed (generally using the HMAC SHA-256 algorithm).

  • Free set of claims embedding whatever you want: client_id, aud, expiration date, etc.

  • Signature ensuring data integrity.

The signature mechanism is HMAC_SHA256 as defined by the JOSE specifications:

https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31
JWT Header
{
"alg": "HS256",
"typ": "JWT"
}
JWT Claims
{
"aud": "https://id.b2b.yahooinc.com/identity/oauth2/access_token?realm=dataxonline,
"iss": "{client_id}",
"sub": "{client_id}",
"exp": {expiry time in seconds},
"iat": {issued time in seconds},
"jti": "{UUID}"
}

Note the following:

  • “exp” and “iat” values should be numeric. Do not set them as strings.

  • “exp” value is currentTime + 3600 (i.e. 60 minutes).

  • Don’t use currentTime + (24 * 60 * 60). You may get a “JWT has expired or is not valid” error.

  • UUID - A Universally Unique IDentifier, https://www.ietf.org/rfc/rfc4122.txt

Walking through manual steps to build this JWT value

jwt_signing_string = base64url_encode(jwt_header) + '.' + base64url_encode(jwt_body)

jwt_signature = base64url_encode(hmac_sha256(jwt_signing_string, client_secret))

JWT = jwt_signing_string + '.' + jwt_signature

JWT libraries can be found at https://openid.net/developers/libraries/.

Post-Credential OAuth 2.0 Workflow

Start the workflow after the encrypted credentials are received from the Yahoo Account Team.

  1. Call the ID B2B server to get the access_token, which is valid for 60 minutes.

  2. Call the POST /identity/oauth2/access_token endpoint of ID B2B with the JWT token created out of the provided client_id and the client credential.

Sample Request

curl -X POST 'https://id.b2b.yahooinc.com/identity/oauth2/access_token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=<jwt_token>' \
--data-urlencode 'scope=conversion-event' \
--data-urlencode 'realm=dataxonline'

Sample Response

{
  "access_token": "wcf1011c-70fe-4740-b8a1-781d2b4dd3q3",
      "scope": "conversion-event",
      "token_type": "Bearer",
      "expires_in": 3599
 }

Use Access Token to Call CAPI Endpoint

Call the CAPI endpoint with the access_token in the Authorization header. The API will verify the client access_token and identify the client and determine whether it is authorized for the pixel ID.

Sample Request

curl -X POST \
    https://streaming.datax.yahoo.com/v1/events/10157549/events \
    -H 'authorization: Bearer 9f4c74cf-5bb9-45ce-987c-e5240e5710b8' \
    -H 'cache-control: no-cache' \
    -H 'content-type: application/json' \
    -d '[
{
    "eventTs": 1733508168,
    "actionSource": "web",
    "actionSourceUrl": "http://store.com",
    "country": "USA",
    "region": "NA",
    "userData": {
      "email" : [ "536a09742acb5b4ec7c7d6c0e20a5d3f4318817817353b69f8ee15f27d3fc9fa",
        "7ebd20af4a7ff32eb6331c108cb1aa2176c195f7f1b472fc7ebfd2051f89f8a1" ],
      "gpsaid" : ["c2f11fe5-3600-4ade-901e-5cf84f2d71a5"],
      "phone" : ["1036636844eea8b0c54623eee63eb5d83ad5b86c02cfa7a8da29a3c140c9b100",
        "f4ef23f72996f81f2bbc90929eb7d1e6397cba597cbbd70b5afa717ad41e500f"],
      "pxid" : ["999:XY50038zETeXJBOYNTRn7Z3T6VSkxDF5ZpRz3wvPEVmt1ZXHo"]
     },
     "eventName": "test_action",
     "eventData": {
        "price": 12.99,
        "products": [
          {
          "category": "test_category",
          "subCategory": "test_label"
          }
         ]
     },
     "clickData": {
        "vmcid": "vmcid123456"
     },
}
      ]

Sample Response

{ success: "COMPLETE" }

Rate Limitation

A rate limit is the number of events that are allowed within an API call an advertiser can make within a given period.

For the batch endpoint, the 2 rate limits are:

  1. 200 events per second

  2. 10MB of data per second

For the streaming endpoint, 2 rate limits apply:

  1. An advertiser can send up to two hundred (200) events per second.

  2. An advertiser can send up to 1MB of data per second.

Error Responses

The following return codes can come back in response:

Code

Message

Reason

200

JSON: { success: "COMPLETE" }

Valid request.

200

JSON: { success: "PARTIAL", message: "{ <ERROR_TYPE>=<count> }" }

Submission included invalid events and so partially ingested. The returned success field is marked as partial and the message field contains the breakdown of error types and their respective counts.

400

Error. Unsupported Content-Type.

Invalid Content-Type provided.

400

Error. Missing body and no query parameters provided.

Missing query params and body.

400

{ "message" : "Missing Conversion Event metadata eventTs in request",  "error_code" : "DXOL400_MISSING_EVENT_TS_IN_REQUEST"}

Missing eventTs field in request

400

{ "message" : "Missing Conversion Event metadata eventName in request",  "error_code" : "DXOL400_MISSING_EVENT_METADATA_IN_REQUEST"}

eventName field is missing or empty

400

{ "message" : "Encountered unexpected eventTs value.",  "error_code" : "DXOL400_INVALID_EVENT_TS_FIELD"}

Invalid eventTs, either a future timestamp or older than 30 days

400

{ "message" : "Pxid must have pxIdSrcId + ‘:’ + pxIdValue format",  "error_code" : "DXOL400_BAD_PXID_FORMAT_IN_REQUEST"}

PXID should be passed as <pxIdSrcId>:<pxIdValue> format

400

{ "message" : "Encountered unexpected clickData field in the event data unable to apply.",  "error_code" : "DXOL400_UNEXPECTED_EVENT_CLICKDATA_FIELD"}

clickData is not expected for product events

400

{ "message" : "Setting multiple type of click data per event is not valid.",  "error_code" : "DXOL400_MULITPLE_EVENT_CLICKDATA_FIELD"}

clickData fields tblci and vmcid are mutually exclusive, both cannot be set

400

Error. Request body/params formatting error.

Unable to parse request body/params. Failed to decode KVs in request body. Failed to decode KVs in query params.

400

GPP_STRING_MISSING_SECTION

Returned if privacy_type is GPP but provided gpp_sid section id is not found in the consent_string.

400

INCORRECT_NUMBER_SECTION_IDS

Returned if privacy_type is GPP but provided gpp_sid contains more than 2 section ids.

400

INVALID_GDPR_CONSENT_STRING

Returned if privacy_type is GDPR but consent_string cannot be decoded.

400

INVALID_GPP_CONSENT_STRING

Returned if privacy_type is GPP but consent_string cannot be decoded.

400

INVALID_GPP_SECTION_IDS

Returned if privacy_type is GPP but provided gpp_sid is not supported.

400

INVALID_PRIVACY_TYPE

Returned if privacy_type is missing when consent_string is provided, or if privacy_type is not GPP or GDPR.

400

MISSING_CONSENT_STRING

Returned if privacy_type is present but consent_string is missing.

400

MISSING_GPP_SIDS

Returned if privacy_type is GPP but gpp_sid is missing.

401

Error. Invalid ‘Authorization’ HTTP Header. Request a new token. (Not enforced in initial release)

Invalid Authorization token.

429

Request is rate limited.

500

Internal Server Error

502

External Server Error

An external call failed during serving the query.