選項說明

簡介

零接觸註冊機制 API 可協助裝置經銷商自動進行整合作業。 貴機構的銷售工具可內建零接觸註冊機制, 使用者和顧客,進而提升工作效率。您可以透過這個 API 協助使用者:

  • 將購買的裝置指派至客戶的零接觸註冊機制帳戶。
  • 建立客戶的零接觸註冊機制帳戶。
  • 將貴機構的電話和訂單中繼資料附加至裝置。
  • 針對指派給客戶的裝置建立相關報表。

本文件將介紹 API 並說明這些模式。如果您想 親自探索 API,並嘗試 Java.NETPython

API 概念

「客戶」和「裝置」是指您在 API 中使用的核心資源。如要建立 請撥打 create。您可以建立裝置 使用 Claim API 方法 (參閱下文)。貴機構也可以 透過零接觸註冊機制入口網站建立客戶和裝置。

裝置和顧客資源關係

客戶
貴機構銷售裝置的公司。客戶擁有name 以及 ID。如果客戶想認領或尋找裝置,請直接採用客戶。目的地: 詳情請參閱 Customer
裝置
為貴機構支援零接觸註冊機制的 Android 或 ChromeOS 裝置 銷售給客戶裝置具備硬體 ID、中繼資料以及客戶 著作權聲明。裝置是 API 的核心,因此幾乎在所有裝置上都能使用 方法。詳情請參閱 Device
裝置識別碼
封裝 IMEI 或 MEID 等硬體 ID,以便識別製造業 裝置。使用 DeviceIdentifier 指定裝置 希望找到、更新或聲明擁有權詳情請參閱: ID
DeviceMetadata
儲存裝置的鍵/值組合。使用 DeviceMetadata 儲存貴機構的中繼資料。目的地: 詳情請參閱「裝置中繼資料」。

如要列出應用程式可使用的所有 API 方法和資源,請參閱 API 參考資料

建立客戶

如果是 Android 裝置,經銷商會負責建立客戶 帳戶。客戶會將這個帳戶用於 登入零接觸入口網站,調整其佈建設定 裝置。如果 ChromeOS 裝置已安裝 Google 要用來調整佈建設定的 Workspace 帳戶。

您可以呼叫 create API 方法來建立 的客戶帳戶採用零接觸註冊機制因為 請確認網址正確無誤建立客戶名稱後,即無法編輯 用來追蹤協助客戶的客服專員姓名

您至少必須輸入一個與 Google 帳戶,才能成為擁有者。無法將個人 Gmail 帳戶用於 也能使用 Google Cloud CLI 或 Compute Engine API如果客戶需要協助連結帳戶,請傳送 相關指示 與 Google 帳戶建立關聯

透過呼叫 API 建立客戶後,他們會管理員工的 入口網站存取權 - 無法編輯客戶的以及如何使用 API程式碼片段 以下說明如何建立客戶:

Java

// Provide the customer data as a Company type.
// The API requires a name and owners.
Company customer = new Company();
customer.setCompanyName("XYZ Corp");
customer.setOwnerEmails(Arrays.asList("liz@example.com", "darcy@example.com"));
customer.setAdminEmails(Collections.singletonList("jane@example.com"));

// Use our reseller ID for the parent resource name.
String parentResource = String.format("partners/%d", PARTNER_ID);

// Call the API to create the customer using the values in the company object.
CreateCustomerRequest body = new CreateCustomerRequest();
body.setCustomer(customer);
Company response = service.partners().customers().create(parentResource, body).execute();

.NET

// Provide the customer data as a Company type.
// The API requires a name and owners.
var customer = new Company
{
    CompanyName = "XYZ Corp",
    OwnerEmails = new String[] { "liz@example.com", "darcy@example.com" },
    AdminEmails = new String[] { "jane@example.com" }
};

// Use our reseller ID for the parent resource name.
var parentResource = String.Format("partners/{0}", PartnerId);

// Call the API to create the customer using the values in the company object.
var body = new CreateCustomerRequest
{
    Customer = customer
};
var request = service.Partners.Customers.Create(body, parentResource);
var response = request.Execute();

Python

# Provide the customer data as a Company type. The API requires
# a name and at least one owner.
company = {'companyName':'XYZ Corp', \
  'ownerEmails':['liz@example.com', 'darcy@example.com'], \
  'adminEmails':['jane@example.com']}

# Use our reseller ID for the parent resource name.
parent_resource = 'partners/{0}'.format(PARTNER_ID)

# Call the API to create the customer using the values in the company object.
response = service.partners().customers().create(parent=parent_resource,
    body={'customer':company}).execute()

如要進一步瞭解客戶員工的擁有者和管理員角色, 請參閱「入口網站使用者」一文。

為客戶認領裝置

客戶購買裝置後,會想設定佈建作業 設定。聲明裝置擁有權後,會新增這部裝置 導入零接觸註冊機制,讓客戶能夠 帳戶管理設定。

裝置的佈建記錄中會有零接觸註冊機制專區。個人中心 以指派裝置的方式, 用來追蹤協助客戶的客服專員姓名呼叫 partners.devices.claimpartners.devices.claimAsync 方法,搭配 做為論點一律提供 SECTION_TYPE_ZERO_TOUCH 做為 sectionType

您必須先撤銷客戶的裝置擁有權 (詳見下文),才能 為不同的客戶申請同一部裝置。著作權聲明方法 驗證 DeviceIdentifier 欄位, 包括 IMEI、MEID 或序號, 製造商名稱和型號,以及 ChromeOS 裝置的認證裝置 ID (在建立新裝置時)。

以下程式碼片段說明如何聲明裝置擁有權:

Java

// Identify the device to claim.
DeviceIdentifier identifier = new DeviceIdentifier();
// The manufacturer value is optional but recommended for cellular devices
identifier.setManufacturer("Google");
identifier.setImei("098765432109875");

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest();
body.setDeviceIdentifier(identifier);
body.setCustomerId(customerId);
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");

// Claim the device.
ClaimDeviceResponse response = service.partners().devices().claim(PARTNER_ID, body).execute();

.NET

// Identify the device to claim.
var deviceIdentifier = new DeviceIdentifier
{
    // The manufacturer value is optional but recommended for cellular devices
    Manufacturer = "Google",
    Imei = "098765432109875"
};

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest
{
    DeviceIdentifier = deviceIdentifier,
    CustomerId = CustomerId,
    SectionType = "SECTION_TYPE_ZERO_TOUCH"
};

// Claim the device.
var response = service.Partners.Devices.Claim(body, PartnerId).Execute();

Python

# Identify the device to claim.
# The manufacturer value is optional but recommended for cellular devices
device_identifier = {'manufacturer':'Google', 'imei':'098765432109875'}

# Create the body to connect the customer with the device.
request_body = {'deviceIdentifier':device_identifier, \
    'customerId':customer_id, \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

# Claim the device.
response = service.partners().devices().claim(partnerId=PARTNER_ID,
    body=request_body).execute()

取消認領裝置

貴機構可取消客戶裝置擁有權。取消認領裝置 就會從零接觸註冊機制中移除。經銷商可能會取消認領以下裝置: 他們想要遷移至其他帳戶、退回或收到了錯誤的聲明。 呼叫 partners.devices.unclaim 方法或 :partners.devices.unclaimAsync:撤銷 客戶的裝置。

供應商

您可以透過供應商,在經銷商網路 (本地) 中代表經銷商合作夥伴 營運商或全球經銷商網路中的營運商 管理裝置供應商可協助您區隔使用者、客戶和 裝置:

  • 您建立的供應商無法查看您的零接觸註冊機制帳戶或每個供應商 和他人的帳戶。
  • 您可以查看供應商的客戶和裝置,也可以取消註冊 供應商的裝置。不過,您無法將裝置指派給供應商 以更全面、準確的方式回答顧客問題 並與顧客自然流暢地對話
,瞭解如何調查及移除這項存取權。

使用入口網站為以下項目建立供應商: 因此無法使用 API。帳戶角色必須 擁有者:建立新的供應商。如果貴機構有供應商 您可以呼叫 partners.vendors.list 列出 供應商和 partners.vendors.customers.list 吸引供應商的客戶以下範例同時使用這兩種方法 即可列印一份報表,其中列出供應商的《服務條款》狀態 客戶:

Java

// First, get the organization's vendors.
String parentResource = String.format("partners/%d", PARTNER_ID);
ListVendorsResponse results = service.partners().vendors().list(parentResource).execute();
if (results.getVendors() == null) {
  return;
}

// For each vendor, report the company name and a maximum 5 customers.
for (Company vendor: results.getVendors()) {
  System.out.format("\n%s customers\n", vendor.getCompanyName());
  System.out.println("---");
  // Use the vendor's API resource name as the parent resource.
  AndroidProvisioningPartner.Partners.Vendors.Customers.List customerRequest =
      service.partners().vendors().customers().list(vendor.getName());
  customerRequest.setPageSize(5);
  ListVendorCustomersResponse customerResponse = customerRequest.execute();

  List<Company> customers = customerResponse.getCustomers();
  if (customers == null) {
    System.out.println("No customers");
    break;
  } else {
    for (Company customer: customers) {
      System.out.format("%s: %s\n",
          customer.getCompanyName(),
          customer.getTermsStatus());
    }
  }
}

.NET

// First, get the organization's vendors.
var parentResource = String.Format("partners/{0}", PartnerId);
var results = service.Partners.Vendors.List(parentResource).Execute();
if (results.Vendors == null)
{
    return;
}

// For each vendor, report the company name and a maximum 5 customers.
foreach (Company vendor in results.Vendors)
{
    Console.WriteLine("\n{0} customers", vendor);
    Console.WriteLine("---");
    // Use the vendor's API resource name as the parent resource.
    PartnersResource.VendorsResource.CustomersResource.ListRequest customerRequest =
        service.Partners.Vendors.Customers.List(vendor.Name);
    customerRequest.PageSize = 5;
    var customerResponse = customerRequest.Execute();

    IList<Company> customers = customerResponse.Customers;
    if (customers == null)
    {
        Console.WriteLine("No customers");
        break;
    }
    else
    {
        foreach (Company customer in customers)
        {
            Console.WriteLine("{0}: {1}", customer.Name, customer.TermsStatus);
        }
    }
}

Python

# First, get the organization's vendors.
parent_resource = 'partners/{0}'.format(PARTNER_ID)
vendor_response = service.partners().vendors().list(
    parent=parent_resource).execute()
if 'vendors' not in vendor_response:
  return

# For each vendor, report the company name and a maximum 5 customers.
for vendor in vendor_response['vendors']:
  print '\n{0} customers'.format(vendor['companyName'])
  print '---'
  # Use the vendor's API resource name as the parent resource.
  customer_response = service.partners().vendors().customers().list(
      parent=vendor['name'], pageSize=5).execute()
  if 'customers' not in customer_response:
    print 'No customers'
    break
  for customer in customer_response['customers']:
    print '  {0}: {1}'.format(customer['name'], customer['termsStatus'])

如果您販售一系列裝置,可能需要知道哪家經銷商或 供應商已領取裝置。如要取得經銷商 ID (數值) 的數字,請檢查 裝置聲明記錄中的 resellerId 欄位。

貴機構可以取消認領供應商已認領的裝置。對於 修改裝置,請檢查貴機構是否已認領該裝置 再呼叫 API 方法以下範例說明如何執行這項作業:

Java

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
body.setCustomerId(Arrays.asList(resellerCustomerId, vendorCustomerId));
body.setLimit(MAX_PAGE_SIZE);
FindDevicesByOwnerResponse response =
    service.partners().devices().findByOwner(PARTNER_ID, body).execute();
if (response.getDevices() == null) {
  return;
}

for (Device device: response.getDevices()) {
  // Confirm the device was claimed by our reseller and not a vendor before
  // updating metadata in another method.
  for (DeviceClaim claim: device.getClaims()) {
    if (claim.getResellerId() == PARTNER_ID) {
      updateDeviceMetadata(device.getDeviceId());
      break;
    }
  }
}

.NET

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
{
    Limit = MaxPageSize,
    SectionType = "SECTION_TYPE_ZERO_TOUCH",
    CustomerId = new List<long?>
    {
        resellerCustomerId,
        vendorCustomerId
    }
};
var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
if (response.Devices == null)
{
    return;
}

foreach (Device device in response.Devices)
{
    // Confirm the device was claimed by our reseller and not a vendor before
    // updating metadata in another method.
    foreach (DeviceClaim claim in device.Claims)
    {
        if (claim.ResellerId == PartnerId)
        {
            UpdateDeviceMetadata(device.DeviceId);
            break;
        }
    }
}

Python

# Get the devices claimed for two customers: one of our organization's
# customers and one of our vendor's customers.
request_body = {'limit':MAX_PAGE_SIZE, \
  'pageToken':None, \
  'customerId':[reseller_customer_id, vendor_customer_id], \
  'sectionType':'SECTION_TYPE_ZERO_TOUCH'}
response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).execute()

for device in response['devices']:
  # Confirm the device was claimed by our reseller and not a vendor before
  # updating metadata in another method.
  for claim in device['claims']:
    if claim['resellerId'] == PARTNER_ID:
      update_device_metadata(device['deviceId'])
      break

長時間執行的批次作業

API 包含非同步版本的裝置方法。 這些方法允許批次處理許多裝置;而 方法則是針對每個 API 要求處理一部裝置非同步方法的名稱 含有「Async」後置字串,例如 claimAsync

非同步 API 方法會在處理程序完成之前傳回結果。 非同步方法也能幫助應用程式 (或工具) 持續回應您的 等待長時間執行的作業完成時。您的應用程式應 請定期檢查作業狀態。

作業

您可以使用 Operation 追蹤長時間執行的批次作業。A 罩杯 成功呼叫非同步方法時,會傳回作業的參照 回應。下列 JSON 程式碼片段顯示了呼叫後的一般回應 updateMetadataAsync:

{
  "name": "operations/apibatchoperation/1234567890123476789"
}

每項作業都包含個別工作清單。致電 operations.get: 作業所含工作的結果。下列程式碼片段說明如何 這種做法您必須在自己的應用程式中處理所有錯誤。

Java

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
UpdateMetadataArguments firstUpdate = new UpdateMetadataArguments();
firstUpdate.setDeviceMetadata(metadata);
firstUpdate.setDeviceId(firstTargetDeviceId);

UpdateMetadataArguments secondUpdate = new UpdateMetadataArguments();
secondUpdate.setDeviceMetadata(metadata);
secondUpdate.setDeviceId(firstTargetDeviceId);

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest();
body.setUpdates(Arrays.asList(firstUpdate, secondUpdate));
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.operations().get(response.getName()).execute();

.NET

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
var updates = new List<UpdateMetadataArguments>
{
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = firstTargetDeviceId
    },
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = secondTargetDeviceId
    }
};

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest
{
    Updates = updates
};
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.Operations.Get(response.Name).Execute();

Python

# Build out the request body to apply the same order number to a customer's
# purchase of 2 devices.
updates = [{'deviceMetadata':metadata,'deviceId':first_target_device_id},
    {'deviceMetadata':metadata,'deviceId':second_target_device_id}]

# Start the device metadata update.
response = service.partners().devices().updateMetadataAsync(
    partnerId=PARTNER_ID, body={'updates':updates}).execute()

# Assume the metadata update started, so get the Operation for the update.
operation = service.operations().get(name=response['name']).execute()

如要確認作業是否完成,請查看 done 欄位的作業 值為 true。如果缺少 donefalse,表示作業仍在執行 備用資源

回應

作業完成後,API 會更新作業結果並傳回結果,即使結果 。response 欄位是 DevicesLongRunningOperationResponse 物件,詳細說明作業中每部裝置的處理程序。

檢查 successCount 欄位,有效率地瞭解是否有任何工作失敗,並 避免反覆處理大型結果清單的 perDeviceStatus 欄位 DevicesLongRunningOperationResponseOperationPerDevice 執行個體,詳細說明每部裝置 作業。清單順序會與原始要求中的工作相符。

每項 OperationPerDevice 工作都包含 result 欄位和提醒摘要 要求數量。確認工作是否成功或失敗 使用 result 欄位。

下列 JSON 程式碼片段顯示了一般回應中,來自於 對 updateMetadataAsync 發出的呼叫:

"response": {
  "perDeviceStatus": [
    {
      "result": {
        "deviceId": "12345678901234567",
        "status": "SINGLE_DEVICE_STATUS_SUCCESS"
      },
      "updateMetadata": {
        "deviceId": "12345678901234567",
        "deviceMetadata": {
          "entries": {
            "phonenumber": "+1 (800) 555-0100"
          }
        }
      }
    }
  ],
  "successCount": 1
}

追蹤進度

如果您的應用程式需要追蹤進度,建議您定期重新擷取 作業。metadata 欄位包含一個 DevicesLongRunningOperationMetadata 執行個體,可協助您的應用程式查看執行中作業的最新進度。使用 包含下列資源中的「DevicesLongRunningOperationMetadata」欄位 資料表,追蹤作業進度:

欄位 常見用途
processingStatus 從「BATCH_PROCESS_PENDING」變更為 BATCH_PROCESS_IN_PROGRESS,之後是 BATCH_PROCESS_PROCESSED 表示作業進度。
progress 已處理的更新百分比。應用程式可使用 來估計完成時間因為progress 作業完成時,這個值可以是 100。 請查看作業的 done 欄位,瞭解是否存在 且有結果
devicesCount 顯示作業的更新次數。這個 可能會與 。

以下的簡化範例說明應用程式如何將進度中繼資料用於以下目的: 設定輪詢間隔在應用程式中,您可能需要更複雜的工作 執行輪詢作業此外,您也必須新增錯誤處理機制。

Java

// Milliseconds between polling the API.
private static long MIN_INTERVAL = 2000;
private static long MAX_INTERVAL = 10000;

// ...
// Start the device metadata update.
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();
String operationName = response.getName();

// Start polling for completion.
long startTime = new Date().getTime();
while (true) {

  // Get the latest update on the operation's progress using the API.
  Operation operation = service.operations().get(operationName).execute();

  if (operation.get("done") != null && operation.getDone()) {
    // The operation is finished. Print the status.
    System.out.format("Operation complete: %s of %s successful device updates\n",
        operation.getResponse().get("successCount"),
        operation.getMetadata().get("devicesCount"));
    break;

  } else {
    // Estimate how long the operation *should* take - within min and max value.
    BigDecimal opProgress = (BigDecimal) operation.getMetadata().get("progress");
    double progress = opProgress.longValue();
    long interval = MAX_INTERVAL;
    if (progress > 0) {
      interval = (long) ((new Date().getTime() - startTime) *
          ((100.0 - progress) / progress));
    }
    interval = Math.max(MIN_INTERVAL, Math.min(interval, MAX_INTERVAL));

    // Sleep until the operation should be complete.
    Thread.sleep(interval);
  }
}

.NET

// Milliseconds between polling the API.
private static double MinInterval = 2000;
private static double MaxInterval = 10000;

// ...
// Start the device metadata update.
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();
var operationName = response.Name;

// Start polling for completion.
var startTime = DateTime.Now;
while (true)
{

    // Get the latest update on the operation's progress using the API.
    Operation operation = service.Operations.Get(operationName).Execute();

    if (operation.Done == true)
    {
        // The operation is finished. Print the status.
        Console.WriteLine("Operation complete: {0} of {1} successful device updates",
                          operation.Response["successCount"],
                          operation.Metadata["devicesCount"]);
        break;
    }
    else
    {
        // Estimate how long the operation *should* take - within min and max value.
        double progress = (double)(long)operation.Metadata["progress"];
        double interval = MaxInterval;
        if (progress > 0)
        {
            interval = DateTime.Now.Subtract(startTime).TotalMilliseconds *
                                     ((100.0 - progress) / progress);
        }
        interval = Math.Max(MinInterval, Math.Min(interval, MaxInterval));

        // Sleep until the operation should be complete.
        System.Threading.Thread.Sleep((int)interval);
    }
}

Python

# Seconds between polling the API.
MIN_INTERVAL = 2;
MAX_INTERVAL = 10;

# ...
# Start the device metadata update
response = service.partners().devices().updateMetadataAsync(
  partnerId=PARTNER_ID, body={'updates':updates}).execute()

op_name = response['name']
start_time = time.time()

# Start polling for completion
while True:
  # Get the latest update on the operation's progress using the API
  op = service.operations().get(name=op_name).execute()

  if 'done' in op and op['done']:
    # The operation is finished. Print the status.
    print('Operation complete: {0} of {1} successful device updates'.format(
      op['response']['successCount'], op['metadata']['devicesCount']
    ))
    break
  else:
    # Estimate how long the operation *should* take - within min and max.
    progress = op['metadata']['progress']
    interval = MIN_INTERVAL
    if progress > 0:
      interval = (time.time() - start_time) * ((100.0 - progress) / progress)
    interval = max(MIN_INTERVAL, min(interval, MAX_INTERVAL))

    # Sleep until the operation should be complete.
    time.sleep(interval)

選擇對應用程式使用者有意義的輪詢做法。部分應用程式使用者 如果等待程序進行 完成。

分頁結果

partners.devices.findByOwner API 方法 可能會傳回非常龐大的裝置清單為了縮減回應大小 其他 API 方法 (例如 partners.devices.findByIdentifier) 支援分頁結果。分頁結果可讓您的應用程式 要求並處理大型清單 (一次一頁)。

呼叫 API 方法後,請檢查回應是否包含 nextPageToken。如果nextPageToken 不是 null,應用程式可以呼叫 再次呼叫此方法。您必須設定 limit 參數。如果 nextPageTokennull,您的應用程式要求 最後一頁。

以下範例方法展示應用程式如何輸出裝置清單 (一項 一次下載下列幾頁:

Java

private static long MAX_PAGE_SIZE = 10;

// ...
/**
 * Demonstrates how to loop through paginated lists of devices.
 * @param pageToken       The token specifying which result page to return.
 * @throws IOException    If the zero-touch API call fails.
 */
private void printDevices(String pageToken) throws IOException {

  // Create the request body to find the customer's devices.
  FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
  body.setLimit(MAX_PAGE_SIZE);
  body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
  body.setCustomerId(Collections.singletonList(targetCustomerId));

  // Call the API to get a page of Devices. Send a page token from the method
  // argument (might be None). If the page token is None, the API returns the first page.
  FindDevicesByOwnerResponse response =
      service.partners().devices().findByOwner(PARTNER_ID, body).execute();
  if (response.getDevices() == null) {
    return;
  }

  // Print the devices included in this page of results.
  for (Device device: response.getDevices()) {
    System.out.format("Device %s\n", device.getName());
  }
  System.out.println("---");

  // Check to see if another page of devices is available. If yes,
  // fetch and print the devices.
  if (response.getNextPageToken() != null) {
    this.printDevices(response.getNextPageToken());
  }
}

// ...
// Pass null to start printing the first page of devices.
printDevices(null);

.NET

private static int MaxPageSize = 10;

// ...
/// <summary>Demonstrates how to loop through paginated lists of devices.</summary>
/// <param name="pageToken">The token specifying which result page to return.</param>
private void PrintDevices(string pageToken)
{
    // Create the request body to find the customer's devices.
    FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
    {
        PageToken = pageToken,
        Limit = MaxPageSize,
        SectionType = "SECTION_TYPE_ZERO_TOUCH",
        CustomerId = new List<long?>
        {
            targetCustomerId
        }
    };

    // Call the API to get a page of Devices. Send a page token from the method
    // argument (might be None). If the page token is None, the API returns the first page.
    var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
    if (response.Devices == null)
    {
        return;
    }

    // Print the devices included in this page of results.
    foreach (Device device in response.Devices)
    {
        Console.WriteLine("Device: {0}", device.Name);
    }
    Console.WriteLine("---");

    // Check to see if another page of devices is available. If yes,
    // fetch and print the devices.
    if (response.NextPageToken != null)
    {
        this.PrintDevices(response.NextPageToken);
    }
}

// ...
// Pass null to start printing the first page of devices.
PrintDevices(null);

Python

MAX_PAGE_SIZE = 10;

# ...
def print_devices(page_token):
  """Demonstrates how to loop through paginated lists of devices.

  Args:
    page_token: The token specifying which result page to return.
  """

   # Create the body to find the customer's devices.
  request_body = {'limit':MAX_PAGE_SIZE, \
    'pageToken':page_token, \
    'customerId':[target_customer_id], \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

  # Call the API to get a page of Devices. Send a page token from the method
  # argument (might be None). If the page token is None,
  # the API returns the first page.
  response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).execute()

  # Print the devices included in this page of results.
  for device in response['devices']:
    print 'Device: {0}'.format(device['name'])
  print '---'

  # Check to see if another page of devices is available. If yes,
  # fetch and print the devices.
  if 'nextPageToken' in response:
    print_devices(response['nextPageToken'])

# ...
# Pass None to start printing the first page of devices.
print_devices(None);

後續步驟

現在您已瞭解 API 的運作方式,不妨參考下列的快速入門導覽課程: Java.NETPython