Guide To The Google Tag Manager API

In October 2014, Google Tag Manager V2 was officially released. In the wake of this major UI and functional overhaul, the developer team also published an API service that allows anyone to create value-adding components on top of Google Tag Manager (GTM).

The API really opens a whole new world of interaction with your GTM accounts and containers. Tired of waiting for some feature to be developed by Google in GTM? Well, build it yourself!

In this article, I’ll walk you through how the API works, what you can do with it, and I’ll wrap things off with a simple example, where I use Python to list the GTM accounts and containers your Google ID has access to. Fasten your seat belts!

Available API Services

The API gives you a number of services you can invoke with an authenticated user. Most of the services support typical CRUD (create, read, update and delete) operations, and communications with the API are performed using the HTTP protocol.

Google provides a number of useful client libraries which make it very easy for you to build the service calls.

The services you can access through the GTM API are:

google tag manager api services

  • Accounts: Lets you access GTM accounts the user has access to.
  • Permissions: Allows you to modify permissions for GTM accounts and containers. Also lets you view and modify permissions for a given user.
  • Containers: Gives you full control over container resources in a given GTM account. You can, for example, create a new container, delete a container, or list all containers under an account (that the user has access to).
  • Container Versions: Perform versioning operations on a container, such as restore, publish and delete. Also gives you access to the entire version resource, together with all tags, triggers, and variables within the version.
  • Tags / Triggers / Variables: Gives you full control over the assets in a given container. Also lets you create new assets, delete assets, update them, etc.

In short, you can do everything that’s available through the UI, but as an added bonus you can create your own solutions that facilitate things that are not available in the UI, such as mass operations, cloning assets from one container to another, and so on.

For example, to clone a container from one account to another, you would need to write a solution that does the following:

  1. Get the container version you want to clone.
  2. Create a container in the target account, using the container version as the body of the request (so that the new container has the same settings).
  3. For each tag, trigger, and variable in the container version to be cloned, create a new tag, trigger, and variable in the target container, using the respective asset as the body of the request.
  4. Operations like these seem complex, but they are actually very trivial calculations for a client application communicating with a service endpoint.

    How The Google Tag Manager API Service Works

    Google Tag Manager API is very similar to all the other Google APIs out there. That is, it uses OAuth 2.0 for authentication, and it provides you with a client library that you can use to build the requests to the web service.

    If you’ve never worked with Google APIs before, you might want to follow this guide for the Google Analytics API. It has a very nice walkthrough of all the things you need to do to get started with using Google APIs. The steps you need to take, in a nutshell, are:

    1. Register a new project in the Google Developers Console, and make sure you’ve enabled access to the Google Tag Manager API.

    google developer console

    2. Create new credentials for the application. What type of credentials you want to create depends on whether or not you’re working with a web application, an installed application (e.g. command-line), or with a service account. If you want to try out the command-line example at the end of this article, make sure to create credentials for a native application.

    application credentials

    3. Download and install the right client library, depending on which programming language you want to use. The example at the end of this article will be using Python.

    4. In the application code, you will first need to create a service object, using authorization credentials the native application requires. Depending on the scopes you choose, the user will need to authorize the application to access their Google Tag Manager data.

    google tag manager data access

    5. Using this service object, you can then proceed to call all the services the Google Tag Manager API provides. The service object will be valid for as long as the user doesn’t revoke authorization to the application. Naturally, you might need to store the access credentials in some file to ensure that the user doesn’t need to provide authorization every time they run the command-line application.

    The most difficult thing to grasp in this process is that of authentication and authorization. The OAuth 2.0 protocol isn’t difficult to understand, but it has multiple layers and the process is ambiguous to many. But if you follow the steps outlined in the next chapter, you should have a better idea of how authentication works in the Google API universe.

    Simple Command-Line Application

    Command-Line ApplicationThe application we’ll create is a simple Python program, which defines the service object, and then proceeds to get the names of all GTM accounts your user has access to. For each account, it also gets the names of all containers you have access to. Everything is output into a text file, which will look like the image on the left.

    So, let’s get started.

    I’m assuming you’ve read the previous chapter. At this point, you should have a new project created, and you’ve also created credentials for a native application. You should also have the Python client libraries installed in your development environment.

    If you’re using Mac OS X, and you’ve installed the client library following the instructions, you won’t even need to setup a complicated development environment. All you’ll need is to edit the Python file (.py) directly in a text editor, and then run the application from the command line!

    First things first, download the client secret JSON from the Google Developers Console, and store the JSON file as client_secrets.json in the directory you’ve created for your application. This file will link your application with the project you created in the API console.

    JSON File

    To kick things off with the code, you will need to create a new text file that will become the Python application. I’ve used the imaginative name gtm2txt.py, but you can choose whatever name works for you.

    First things first, we’ll need to import a bunch of modules to help us work with the GTM API:


    import argparse
    import sys

    import httplib2

    from apiclient.discovery import build
    from oauth2client import client
    from oauth2client import file
    from oauth2client import tools

    These modules are required for the rest of the code to work. Next, as this is a Python command-line application, we’ll need to define the main method and invoke it with any command-line arguments:


    def main(argv):
    # Content coming soon

    if __name__ == '__main__':
    main(sys.argv)

    This is required stuff for any native Python application.

    All the rest of the code comes in the main method, so remove the line # Content coming soon, and let’s get on with the code!


    # Define variable constants for the application
    CLIENT_SECRETS = 'client_secrets.json'
    SCOPE = ['https://www.googleapis.com/auth/tagmanager.readonly']

    First, we’ll create some constants. If you followed my instructions, you downloaded the client secret JSON from the Google Developers Console, and you renamed it to client_secrets.json, saving it in the same directory as your Python application.

    Next, we’re defining a scope for the application. As this is a very simple app, all we’ll need is read-only rights to GTM accounts and containers. You can view all the available scopes behind this link.


    # Parse command-line arguments
    parser = argparse.ArgumentParser(parents=[tools.argparser])
    flags = parser.parse_args()

    # Set up a Flow object to be used if we need to authenticate
    flow = client.flow_from_clientsecrets(
    CLIENT_SECRETS,
    scope=SCOPE,
    message=tools.message_if_missing(CLIENT_SECRETS))

    These lines set up a Flow object. In the world of Google APIs, a flow is how the credentials are passed from the application to the web service and back, after a hopefully successful authentication. The Flow object is built using command-line flags, but since this is a very simple app, we won’t be actually using any flags. As you can see, the client_secrets.json file and the scope are passed as arguments to the Flow object.


    # Prepare credentials, and authorize the HTTP object with them.
    # If the credentials don't exist or are invalid, run through the native client
    # flow. The Storage object will ensure that if successful, the good
    # credentials will be written back to a file.
    storage = file.Storage('tagmanager.dat')
    credentials = storage.get()
    if credentials is None or credentials.invalid:
    credentials = tools.run_flow(flow, storage, flags)
    http = credentials.authorize(http=httplib2.Http())

    # Build the service object
    service = build('tagmanager', 'v1', http=http)

    These are very important lines. First, the application checks if a file called tagmanager.dat is located in the application directory. This is the file where we’ll save your credentials after a successful authorization. If the file isn’t found, or the credentials within are invalid, the run_flow() method is invoked, which opens a browser window and asks for your authorization to the scopes you’ve defined. A successful authorization returns a credentials object, which we then use to authorize all API requests.

    Finally, the service object is built, using the credentials we got back from the authorization flow.

    This is how OAuth 2.0 works. Authorization is requested, and if it’s provided, a service object can be built with the credentials.

    Now that we’ve built the service object, we can start calling the API and performing tasks.


    # Get all accounts the user has access to
    accounts = service.accounts().list().execute()

    # If the user has access to accounts, open accounts.txt and
    # write the account and container names the user can access
    if len(accounts):
    with open('accounts.txt', 'w') as f:
    for a in accounts['accounts']:
    f.write('Account: ' +
    unicode(a['name']).encode('utf-8') +
    '\n')
    # Get all the containers under each account
    containers = service.accounts().containers().list(
    accountId=a['accountId']).execute
    if len(containers):
    for c in containers['containers']:
    f.write('Container: ' +
    unicode(c['name']).encode('utf-8') +
    '\n')

    The very first command we’re executing shows exactly how Google APIs work. As you can see, we’re invoking a number of methods of the service object, which we built around the Google Tag Manager API.

    So, to get all the accounts the user has access to, you will have to run the accounts().list() query method against the service object. It takes no parameters. I know this, because I’ve consulted the instructions for invoking the list() method in the Google Tag Manager API Reference Guide. The execute() command in the end runs the actual service call.

    Because it’s a variable assignment, I’m actually storing whatever this API method returns in the object accounts. By looking at the reference guide again, I can see that the API returns a JSON list object, with all the accounts I have access to as objects within this list.

    As I know now what the response resource is like, I can confidently first check if there are any accounts, using Python’s built-in len() call to check the length of the list. Next, I can iterate over all the account resources in this list, storing the value of the name property in the text file. The reason I’m re-encoding the value in unicode is because I might have access to accounts that have been created with a character set not supported natively by the default encoding.

    Look at the call I’m doing on the service object next. I’m invoking the accounts().containers().list() method to get a list of containers the user has access to. This time, I will need to add a parameter to this call, namely the account ID I want to get the containers for. Luckily I’m in the process of looping through the accounts returned by the first API call, so all I have to do is send the accountId property of the account currently being looped through. Again, I can check the detail for the containers().list() method from the reference guide.

    And that’s the application right there. Short and sweet. Once you have the code in a Python file, you can run it with the command python gtm2txt.py.

    You can download this application code from my GitHub repository.

    It’s not difficult, if you have a modest understanding of Python, if you understand how authorization is passed to and from your application to the web service, and if you’re prepared to consult the reference guide for the API multiple times while debugging your application.

    What to do next?

    Well, the world is your oyster. The API opens up a lot of possibilities. I’ve created a set of tools for accounts created in the new Google Tag Manager interface. The tools are free to use, and can be found at v2.gtmtools.com. The toolset is built on a number of API methods similar to the ones we’ve explored today. Be sure to check out the user guide I’ve written as well.

    Feel free to use your imagination with the API. Here are a couple of ideas you might want to try:

    • A branch/merge publishing workflow for containers.
    • A diff for container versions, which shows what changed, what was removed, and what was added between two container versions.
    • A tool which lets you add a trigger condition to multiple tags at once.
    • An app which is similar to the one we just created, but which outputs the details into a .csv file, and includes also account IDs and container IDs.

Related Posts