A service account is a type of Google Account that can be used by an application
to access Google APIs programmatically using OAuth 2.0. This does not require
human authorization but instead uses a key file that only your application can
access.

**Before reading more about service accounts** consider the simpler and more
highly recommended [OAuth 2.0 installed application flow](https://developers.google.com/accounts/docs/OAuth2InstalledApp). While
this flow requires manual user interaction to authorize your application, this
step must only be done once and need not be done in your production environment.
The refresh tokens generated by this flow never expire, can be cached and
deployed to different environments, and may be used to generate access tokens on
demand with no user interaction.

Still reading? OK, you can use a service account in either of the following
ways:

- Create a [Display \& Video 360 user](https://support.google.com/displayvideo/answer/2723011) associated with your service account. In this scenario, your service account behaves like a normal user account and lets you access all of the partners and advertisers to which the user has been provisioned. This is the preferred way to use service accounts with Display \& Video 360.
- Use [domain-wide delegation](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority) to make requests on behalf of one or more Display \& Video 360 users linked to accounts under a [G Suite](https://gsuite.google.com/) domain. In this case you must have administrator access to the target domain. For help with G Suite and domain configuration see the [G Suite support page](https://gsuite.google.com/support/).

## Prerequisites

To use a service account associated with a Display \& Video 360 user, select the
**DV360 user** tab. To use domain-wide delegation, select the
**Delegation** tab.

### DV360 user

You must have a Display \& Video 360 user linked to your service account.

### Delegation

1. You must have administrator access to a domain registered with [G Suite](https://gsuite.google.com/).
2. You must have one or more Display \& Video 360 users linked to accounts under your G Suite-registered domain. Users linked to accounts under other domains (for example, gmail.com) cannot be used.

## Configure and use a service account

### DV360 user

1. Generate a [service account key](https://support.google.com/cloud/answer/6158849#serviceaccounts) in the
   Google API Console.

   > [!CAUTION]
   > **Caution:** It's important to protect the key file that grants a service account access to Google services for which it has been authorized.

2. Associate the Display \& Video 360 user with the service account email
   obtained in the previous step as described in the
   [Manage users in Display \& Video 360](https://support.google.com/displayvideo/answer/2723011) help center article.

3. Implement the server-to-server OAuth 2.0 flow in your application, using
   your newly created service account. For more information, see the
   [examples](https://developers.google.com/display-video/api/guides/concepts/general/service-accounts#examples) section.

### Delegation

1. Generate a [service account key](https://support.google.com/cloud/answer/6158849#serviceaccounts) in the
   Google API Console.

   > [!CAUTION]
   > **Caution:** It's important to protect the key file that grants a service account access to Google services for which it has been authorized. This is especially true for the domain-wide delegation flow because of G Suite's domain-level control that gives the service account the ability to impersonate any user in the domain. It's also good practice to allow service accounts to only access one Google API each (using the "scope" field described in the next step). This is a preventative measure to mitigate the amount of data an attacker can access in the event that a service account's key file is compromised.

2. Delegate [domain-wide authority](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority) to this service account to
   allow it to impersonate users within your domain. When prompted, provide
   the following API scopes:

   <br />

   | Scope | Meaning |
   |---|---|
   | `https://www.googleapis.com/auth/display-video` | Read/write access. |
   | `https://www.googleapis.com/auth/display-video-user-management` | Read/write access for `users` service. Only available for service account users. |

   <br />

3. Implement the server-to-server OAuth 2.0 flow in your application, using
   your newly created service account. For more information, see the
   [examples](https://developers.google.com/display-video/api/guides/concepts/general/service-accounts#examples) section. Remember that you will need to provide an account
   to impersonate, and it must belong to the domain for which your service
   account was delegated domain-wide authority in the previous step.

For help with G Suite and / or domain configuration see the
[G Suite support page](https://gsuite.google.com/support/) page.

## Examples

### Java

```java
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.displayvideo.v4.DisplayVideo;
import com.google.api.services.displayvideo.v4.DisplayVideoScopes;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import java.io.FileInputStream;

/**
 * This example demonstrates how to authenticate using a service account.
 */
public class AuthenticateUsingServiceAccount {
  // Path to a JSON file containing service account credentials for this application. This file can
  // be downloaded from the Credentials tab on the https://console.cloud.google.com/.
  private static final String PATH_TO_JSON_FILE = "ENTER_PATH_TO_CLIENT_SECRETS_HERE";

  /**
   * An optional Google account email to impersonate. Only applicable to service accounts which have
   * enabled domain-wide delegation and wish to make API requests on behalf of an account within
   * their domain. Setting this field will not allow you to impersonate a user from a domain you
   * don't own (e.g., gmail.com).
   */
  private static final String EMAIL_TO_IMPERSONATE = "";

  // The OAuth 2.0 scopes to request.
  private static final ImmutableSet OAUTH_SCOPES =
      ImmutableSet.copyOf(DisplayVideoScopes.all());

  private static Credential getServiceAccountCredential(
      String pathToJsonFile, String emailToImpersonate) throws Exception {
    // Generate a credential object from the specified JSON file.
    GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(pathToJsonFile));

    // Update the credential object with appropriate scopes and impersonation info (if applicable).
    if (Strings.isNullOrEmpty(emailToImpersonate)) {
      credential = credential.createScoped(OAUTH_SCOPES);
    } else {
      credential =
          new GoogleCredential.Builder()
              .setTransport(credential.getTransport())
              .setJsonFactory(credential.getJsonFactory())
              .setServiceAccountId(credential.getServiceAccountId())
              .setServiceAccountPrivateKey(credential.getServiceAccountPrivateKey())
              .setServiceAccountScopes(OAUTH_SCOPES)
              // Set the email of the user you are impersonating (this can be yourself).
              .setServiceAccountUser(emailToImpersonate)
              .build();
    }

    return credential;
  }

  public static void main(String[] args) throws Exception {
    // Build service account credential.
    Credential credential = getServiceAccountCredential(PATH_TO_JSON_FILE, EMAIL_TO_IMPERSONATE);

    // Create a DisplayVideo service instance.
    //
    // Note: application name below should be replaced with a value that identifies your
    // application. Suggested format is "MyCompany-ProductName/Version.MinorVersion".
    DisplayVideo service =
        new DisplayVideo.Builder(credential.getTransport(), credential.getJsonFactory(), credential)
            .setApplicationName("displayvideo-java-service-acct-sample")
            .build();

    // Make API requests.
  }
}
```

### Python

```python
"""This example demonstrates how to authenticate using a service account.

An optional Google account email to impersonate may be specified as follows:
    authenticate_using_service_account.py <path_to_json_file> -i <email>

This optional flag only applies to service accounts which have domain-wide
delegation enabled and wish to make API requests on behalf of an account
within that domain. Using this flag will not allow you to impersonate a
user from a domain you don't own (e.g., gmail.com).
"""

import argparse
import sys

from googleapiclient import discovery
import httplib2
from oauth2client import client
from oauth2client import tools
from oauth2client.service_account import ServiceAccountCredentials

# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument(
    'path_to_service_account_json_file',
    help='Path to the service account JSON file to use for authenticating.')
argparser.add_argument(
    '-i',
    '--impersonation_email',
    help='Google account email to impersonate.')

API_NAME = 'displayvideo'
API_VERSION = 'v4'
API_SCOPES = ['https://www.googleapis.com/auth/display-video']


def main(argv):
  # Retrieve command line arguments.
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawDescriptionHelpFormatter,
      parents=[tools.argparser, argparser])
  flags = parser.parse_args(argv[1:])

  # Authenticate using the supplied service account credentials
  http = authenticate_using_service_account(
      flags.path_to_service_account_json_file,
      flags.impersonation_email)

  # Build a service object for interacting with the API.
  service = discovery.build(API_NAME, API_VERSION, http=http)

  # Make API requests.

def authenticate_using_service_account(path_to_service_account_json_file,
                                       impersonation_email):
  """Authorizes an httplib2.Http instance using service account credentials."""
  # Load the service account credentials from the specified JSON keyfile.
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      path_to_service_account_json_file,
      scopes=API_SCOPES)

  # Configure impersonation (if applicable).
  if impersonation_email:
    credentials = credentials.create_delegated(impersonation_email)

  # Use the credentials to authorize an httplib2.Http instance.
  http = credentials.authorize(httplib2.Http())

  return http


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

### PHP

```php
/**
 * This example demonstrates how to authenticate using a service account.
 *
 * The optional flag email parameter only applies to service accounts which have
 * domain-wide delegation enabled and wish to make API requests on behalf of an
 * account within that domain. Using this flag will not allow you to impersonate
 * a user from a domain that you don't own (e.g., gmail.com).
 */
class AuthenticateUsingServiceAccount
{
    // The OAuth 2.0 scopes to request.
    private static $OAUTH_SCOPES = [Google_Service_DisplayVideo::DISPLAY_VIDEO];

    public function run($pathToJsonFile, $email = null)
    {
        // Create an authenticated client object.
        $client = $this->createAuthenticatedClient($pathToJsonFile, $email);

        // Create a Dfareporting service object.
        $service = new Google_Service_DisplayVideo($client);

        // Make API requests.
    }

    private function createAuthenticatedClient($pathToJsonFile, $email)
    {
        // Create a Google_Client instance.
        //
        // Note: application name should be replaced with a value that identifies
        // your application. Suggested format is "MyCompany-ProductName".
        $client = new Google_Client();
        $client->setApplicationName('PHP service account sample');
        $client->setScopes(self::$OAUTH_SCOPES);

        // Load the service account credentials.
        $client->setAuthConfig($pathToJsonFile);

        // Configure impersonation (if applicable).
        if (!is_null($email)) {
            $client->setSubject($email);
        }

        return $client;
    }
}
```