There're  three types of google api client_id:
 1. Web Application
 2. Service Account
 3. Installed application  
I have used 3. Installed application successfullly base on oauth2client, but failed on 2. Service Account. I wanna access my own gmail inbox with oauth2.0 Credentials.
import imaplib
import json
import urllib2
from oauth2client.client import SignedJwtAssertionCredentials
from httplib2 import Http
from apiclient.discovery import build
import os
reldir = os.path.dirname(os.path.relpath(__file__))
CLIENT_SECRET_FILE = os.path.join(reldir, 'gmail_service.json')
OAUTH_SCOPE = "https://mail.google.com"
GMAIL_ADDRESS = 'my_gmail_address@gmail.com'
def jwt_oauth2():
    '''
    https://developers.google.com/identity/protocols/OAuth2ServiceAccount
    '''
    with open(CLIENT_SECRET_FILE) as f:
        data = json.loads(f.read())
    private_key = data['private_key']
    client_email = data['client_email']
    credentials = SignedJwtAssertionCredentials(
        client_email,   private_key, scope=OAUTH_SCOPE)
    http_auth = credentials.authorize(Http())
    try:
        gmail_service = build('gmail', 'v1', http=http_auth)
        threads = gmail_service.users().messages().list(userId='me').execute()
    except Exception as e:
        return e
I got an exception same as the question. I encounter another exception while trying to add sub=GMAIL_ADDRESS into credentials:
AccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.
I'm trying to figure out the problem, with credentials without sub:
>>> credentials = SignedJwtAssertionCredentials(
    client_email,   private_key, scope=OAUTH_SCOPE)
>>> http = credentials.authorize(Http())
>>> credentials.access_token
>>> credentials.refresh(http)
>>> credentials.access_token
u'ya29.pAGJjddCXjwsiHFN6hKU1yAkdWN7xMJbks5O76Pmrpe1hW1BbgwfZifjp81aDE55ALMVgjv-yBYiyQ'
>>> gmail_service = build('gmail', 'v1', http=http)
>>> request = gmail_service.users().messages().list(userId='me')
>>> response = request.execute()
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "failedPrecondition",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}
Try to use credentials with sub:  
>>> credentials = SignedJwtAssertionCredentials(
    client_email,   private_key, scope=OAUTH_SCOPE, sub=GMAIL_ADDRESS)
>>> http = credentials.authorize(Http())
>>> credentials.access_token
>>> credentials.refresh(http)
AccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.
I found a similar question Google OAuth2 Service Account HTTP/REST Authentication, but I don't know much about node.js. Any help would be appreciated.