Google Ads API Client Library for Golang

This library provides a Golang client for the Google Ads API. It's fully generated from the googleapis repository. More information on the generation process can be found here.
Although this project isn't official, we deem it as low-risk due to its maturity and our many years of using it in production. However, always consult the sunset schedule of the Google Ads API.
Features
- Full support for Google Ads API.
- Support for gRPC and REST Interface.
- Source code generated from the official googleapis repository.
Version support
google-ads-pb |
Google Ads API |
Sunset date |
v1.19.0 |
v19 |
|
v1.18.0 |
v18 |
September 2025 |
v1.17.1 |
v17.1 |
June 4, 2025 |
v1.17.0 |
v17 |
June 4, 2025 |
v1.16.1 |
v16.1 |
Deprecated |
v1.7.0 |
v16 |
Deprecated |
Requirements
Installation
go get github.com/shenzhencenter/google-ads-pb
Getting started
- Prepare
ACCESS_TOKEN
, DEVELOPER_TOKEN
, and CUSTOMER_ID
.
Tips: For testing purposes, you can use google/oauth2l to obtain an access token.
- gRPC example.
var (
customerID = os.Getenv("CUSTOMER_ID")
developerToken = os.Getenv("DEVELOPER_TOKEN")
accessToken = os.Getenv("ACCESS_TOKEN")
)
cred := grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, ""))
conn, err := grpc.NewClient("googleads.googleapis.com:443", cred)
if err != nil {
panic(err)
}
defer conn.Close()
ctx := context.Background()
headers := metadata.Pairs(
"authorization", "Bearer "+accessToken,
"developer-token", developerToken,
"login-customer-id", customerID,
)
ctx = metadata.NewOutgoingContext(ctx, headers)
req := &services.SearchGoogleAdsRequest{
CustomerId: customerID,
Query: "SELECT user_list.name, user_list.resource_name FROM user_list",
}
svc := services.NewGoogleAdsServiceClient(conn)
var header metadata.MD
result, err := svc.Search(ctx, req, grpc.Header(&header))
requestId := header.Get("request-id")
log.Printf("request-id: %v, login-customer-id: %v", requestId[0], customerID)
if err != nil {
apiErr := status.Convert(err)
log.Fatalf("code: %s, message: %s, details: %v", apiErr.Code(), apiErr.Message(), apiErr.Details())
}
for _, row := range result.Results {
if row.UserList == nil {
continue
}
log.Print("resource_name: ", row.UserList.GetResourceName(), " name: ", row.UserList.GetName())
}
- HTTP example.
var (
customerID = os.Getenv("CUSTOMER_ID")
developerToken = os.Getenv("DEVELOPER_TOKEN")
accessToken = os.Getenv("ACCESS_TOKEN")
)
var endpoint = fmt.Sprintf("https://googleads.googleapis.com/v18/customers/%s/googleAds:search", customerID)
req := services.SearchGoogleAdsRequest{
Query: "SELECT user_list.name, user_list.resource_name FROM user_list",
}
reqBody, _ := protojson.Marshal(&req)
reqHttp, _ := http.NewRequest("POST", endpoint, bytes.NewReader(reqBody))
header := make(http.Header)
header.Set("content-type", "application/json")
header.Set("authorization", "Bearer "+accessToken)
header.Set("developer-token", developerToken)
header.Set("login-customer-id", customerID)
reqHttp.Header = header
httpResp, err := http.DefaultClient.Do(reqHttp)
if os.Getenv("DEBUG") != "" {
reqId := httpResp.Header.Get("request-id")
log.Print("request-id: ", reqId, " login-customer-id: ", reqHttp.Header.Get("login-customer-id"))
}
if err != nil {
log.Panic(err)
}
defer httpResp.Body.Close()
var httpRespBody []byte
if httpRespBody, err = io.ReadAll(httpResp.Body); err != nil {
log.Panic(err)
}
result := new(services.SearchGoogleAdsResponse)
if err := protojson.Unmarshal(httpRespBody, result); err != nil {
log.Fatal("failed to unmarshal response: ", err, "response: ", string(httpRespBody))
}
for _, row := range result.Results {
if row.UserList == nil {
continue
}
log.Print("resource_name: ", row.UserList.GetResourceName(), " name: ", row.UserList.GetName())
}
References
Contributing
As this project is fully protoc-generated, we aren't accepting pull requests. However, we value your feedback and suggestions, so feel free to open an issue.