Migrate from the Ad Manager SOAP API

The Ad Manager SOAP API is a legacy API for reading and writing your Ad Manager data and running reports. If you can migrate, we recommend using the Ad Manager API (Beta). However, Ad Manager SOAP API versions are supported for their typical lifecycle. For more information, see the Ad Manager SOAP API Deprecation Schedule.

The following guide outlines differences between the Ad Manager SOAP API and the Ad Manager API (Beta).

Learn

The standard Ad Manager SOAP API service methods have equivalent concepts in the Ad Manager API. The Ad Manager API also has methods for reading single entities. The following table shows an example mapping for Order methods:

SOAP method REST methods
getOrdersByStatement networks.orders.get
networks.orders.list

Authenticate

To authenticate with the Ad Manager API (Beta), you can use your existing Ad Manager SOAP API credentials or create new ones. With either option, you must first enable the Ad Manager API in your Google Cloud project. For more details, see Authentication.

If you are using a client library, set up application default credentials by setting the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path of your service account key file. For more details, see How Application Default Credentials works.

If you are using Installed Application credentials, create a JSON file in the following format and set the environment variable to its path instead:

{
  "client_id": "CLIENT_ID",
  "client_secret": "CLIENT_SECRET",
  "refresh_token": "REFRESH_TOKEN",
  "type": "authorized_user"
}

Replace the following values:

  • CLIENT_ID: Your new or existing client ID.
  • CLIENT_SECRET: Your new or existing client secret.
  • REFRESH_TOKEN: Your new or existing refresh token.

Linux or macOS

export GOOGLE_APPLICATION_CREDENTIALS=KEY_FILE_PATH

Windows

set GOOGLE_APPLICATION_CREDENTIALS=KEY_FILE_PATH

Understand filter differences

The Ad Manager API (Beta) query language supports all Publisher Query Language (PQL) features, but significant syntax differences exist.

This example for listing Order objects illustrates the major changes such as the removal of bind variables, case sensitive operators, and the replacement of ORDER BY and LIMIT clauses with separate fields:

Ad Manager SOAP API

<filterStatement>
  <query>WHERE name like "PG_%" and lastModifiedDateTime &gt;= :lastModifiedDateTime ORDER BY id ASC LIMIT 500</query>
  <values>
    <key>lastModifiedDateTime</key>
    <value xmlns:ns2="https://www.google.com/apis/ads/publisher/v202502" xsi:type="ns2:DateTimeValue">
      <value>
        <date>
          <year>2024</year>
          <month>1</month>
          <day>1</day>
        </date>
        <hour>0</hour>
        <minute>0</minute>
        <second>0</second>
        <timeZoneId>America/New_York</timeZoneId>
      </value>
    </value>
  </values>
</filterStatement>

Ad Manager API (Beta)

JSON format

{
  "filter": "displayName = \"PG_*\" AND updateTime > \"2024-01-01T00:00:00-5:00\"",
  "pageSize": 500,
  "orderBy":  "name"
}

URL encoded

GET https://admanager.googleapis.com/v1/networks/123/orders?filter=displayName+%3D+\"PG_*\"+AND+updateTime+%3E+\"2024-01-01T00%3A00%3A00-5%3A00\"

The Ad Manager API (Beta) supports all PQL capabilities, with the following syntax differences from the Ad Manager SOAP API:

  • The operators AND and OR are case sensitive in the Ad Manager API (Beta). Lowercase and and or are treated as bare literal search strings, a feature in the Ad Manager API (Beta) to search across fields.

    Use uppercase operators

    // Matches unarchived Orders where order.notes has the value 'lorem ipsum'.
    notes = "lorem ipsum" AND archived = false
    

    Lowercase treated as literal

    // Matches unarchived Orders where order.notes has the value 'lorem ipsum'
    // and any field in the order has the literal value 'and'.
    notes = "lorem ipsum" and archived = false
    
  • The character * is a wildcard for string matching. The Ad Manager API (Beta) doesn't support the like operator.

    Ad Manager SOAP API PQL

    // Matches orders where displayName starts with the string 'PG_'
    displayName like "PG_%"
    

    Ad Manager API (Beta)

    // Matches orders where displayName starts with the string 'PG_'
    displayName = "PG_*"
    
  • Field names must appear on the left-hand side of a comparison operator:

    Valid filter

    updateTime > "2024-01-01T00:00:00Z"
    

    Invalid filter

    "2024-01-01T00:00:00Z" < updateTime
    
  • The Ad Manager API (Beta) does not support bind variables. All values must be inlined.

  • String literals containing spaces must be wrapped in double quotes, for example, "Foo bar". You can't use single quotes to wrap string literals.

Remove order by clauses

Specifying a sorting order is optional in the Ad Manager API (Beta). If you want to specify a sorting order for your result set, remove the PQL ORDER BY clause and set the orderBy field instead:

GET networks/${NETWORK_CODE}/orders?orderBy=updateTime+desc

Migrate from offsets to pagination tokens

The Ad Manager API (Beta) uses pagination tokens instead of LIMIT and OFFSET clauses for paging through large result sets.

The Ad Manager API (Beta) uses a pageSize parameter to control the page size. Unlike the LIMIT clause in the Ad Manager SOAP API, omitting a page size does not return the entire result set. Instead, the list method uses a default page size of 50. The following example sets pageSize and pageToken as URL parameters:

# Initial request
GET networks/${NETWORK_CODE}/orders?pageSize=50

# Next page
GET networks/${NETWORK_CODE}/orders?pageSize=50&pageToken=${TOKEN_FROM_INITIAL_REQUEST}

Unlike the Ad Manager SOAP API, the Ad Manager API (Beta) may return fewer results than the requested page size even if there are additional pages. Use the nextPageToken field to determine if there are additional results.

Although an offset is not required for pagination, you may use the skip field for multithreading. When multithreading, use the pagination token from the first page to ensure you are reading from the same result set:

# First thread
GET networks/${NETWORK_CODE}/orders?pageSize=50&pageToken=${TOKEN_FROM_INITIAL_REQUEST}

# Second thread
GET networks/${NETWORK_CODE}/orders?pageSize=50&pageToken=${TOKEN_FROM_INITIAL_REQUEST}&skip=50