Clojure wrapper for the Google Cloud Channel API (v1).
Provides idiomatic Clojure functions for the reseller-side surface of Workspace + Cloud subscriptions: enumerating downstream customers, their entitlements, the catalog (products, SKUs, offers), and four tenant-migration writes (transferEntitlements, transferEntitlementsToGoogle, import-customer, provision-cloud-identity).
Auth: use csl/scoped-delegated-credentials with the appropriate scope and a reseller-admin impersonation target:
Cloud Channel API is reseller-only. The apps.order scope is granted by
Google only to authorized Workspace/Cloud resellers; non-reseller orgs
receive 403 on every call.
All list functions return {:data [...] :next-page-token "..."}. :next-page-token is absent when there are no further pages.
SCOPE NOTE
apps.order is the only meaningful scope for production reseller work;
Google did not carve out a .readonly variant (the unrelated
apps.reports.usage.readonly scope covers only the deprecated
reports/reportJobs resources, which this wrapper does NOT expose).
This wrapper exposes ~24 reads plus four tenant-migration writes.
Entitlement-lifecycle writes (activate / cancel / suspend / changeOffer /
etc.), CRUD on customers / channelPartnerLinks, and repricing configs are
intentionally NOT wrapped; a future consumer files its own FR.
ACCOUNT vs CUSTOMER (terminology) In Cloud Channel, an "account" is the reseller's own account (e.g. "accounts/A012345"); a "customer" is a downstream Workspace tenant the reseller manages (e.g. "accounts/A012345/customers/C987"). This is different from Directory's User/customer terminology.
All functions return {:data ...} on success or {:error ...} on failure.
Clojure wrapper for the Google Cloud Channel API (v1).
Provides idiomatic Clojure functions for the reseller-side surface of
Workspace + Cloud subscriptions: enumerating downstream customers, their
entitlements, the catalog (products, SKUs, offers), and four
tenant-migration writes (transferEntitlements, transferEntitlementsToGoogle,
import-customer, provision-cloud-identity).
Auth: use csl/scoped-delegated-credentials with the appropriate scope and
a reseller-admin impersonation target:
- CloudchannelScopes/APPS_ORDER (read + write — see SCOPE NOTE below)
Cloud Channel API is reseller-only. The `apps.order` scope is granted by
Google only to authorized Workspace/Cloud resellers; non-reseller orgs
receive 403 on every call.
All list functions return {:data [...] :next-page-token "..."}.
:next-page-token is absent when there are no further pages.
SCOPE NOTE
`apps.order` is the only meaningful scope for production reseller work;
Google did not carve out a `.readonly` variant (the unrelated
`apps.reports.usage.readonly` scope covers only the deprecated
reports/reportJobs resources, which this wrapper does NOT expose).
This wrapper exposes ~24 reads plus four tenant-migration writes.
Entitlement-lifecycle writes (activate / cancel / suspend / changeOffer /
etc.), CRUD on customers / channelPartnerLinks, and repricing configs are
intentionally NOT wrapped; a future consumer files its own FR.
ACCOUNT vs CUSTOMER (terminology)
In Cloud Channel, an "account" is the reseller's own account
(e.g. "accounts/A012345"); a "customer" is a downstream Workspace
tenant the reseller manages (e.g. "accounts/A012345/customers/C987").
This is different from Directory's User/customer terminology.
All functions return {:data ...} on success or {:error ...} on failure.(check-cloud-identity-accounts-exist client parent request & [opts])Check whether the given domain is already associated with one or more Cloud Identity accounts. Useful before attempting to import or provision a customer.
parent — the reseller account resource name. request — map with kebab-case keys: :domain — required; the customer's primary domain (e.g. "example.com")
opts:
Returns {:data [...]} of cloud-identity-customer-account maps under :cloud-identity-accounts.
Check whether the given domain is already associated with one or more
Cloud Identity accounts. Useful before attempting to import or provision
a customer.
parent — the reseller account resource name.
request — map with kebab-case keys:
:domain — required; the customer's primary domain (e.g. "example.com")
opts:
- :fields — partial response field mask string
Returns {:data [...]} of cloud-identity-customer-account maps under
:cloud-identity-accounts.(cloudchannel-client credentials)(cloudchannel-client credentials opts)Build an authenticated Cloud Channel client.
credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with a reseller-admin impersonation target. Must hold the CloudchannelScopes/APPS_ORDER scope; non-reseller credentials will fail at the API with 403.
opts (optional):
Per-request opts on individual call sites override the client-level defaults.
Build an authenticated Cloud Channel client. credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with a reseller-admin impersonation target. Must hold the CloudchannelScopes/APPS_ORDER scope; non-reseller credentials will fail at the API with 403. opts (optional): - :read-timeout-ms per-client default read timeout (default 120000 / 120s) - :connect-timeout-ms per-client default connect timeout (default 30000 / 30s) Per-request opts on individual call sites override the client-level defaults.
(get-channel-partner-link client name & [opts])Get one channel-partner link by resource name.
name — the channel-partner-link resource name (e.g. "accounts/A1/channelPartnerLinks/cpl1").
opts:
Get one channel-partner link by resource name. name — the channel-partner-link resource name (e.g. "accounts/A1/channelPartnerLinks/cpl1"). opts: - :view — "BASIC" or "FULL" - :fields — partial response field mask string
(get-channel-partner-link-customer client name & [opts])Get one customer under a channel-partner link.
name — the customer resource name under a channel-partner link (e.g. "accounts/A1/channelPartnerLinks/cpl1/customers/C1").
opts:
Get one customer under a channel-partner link. name — the customer resource name under a channel-partner link (e.g. "accounts/A1/channelPartnerLinks/cpl1/customers/C1"). opts: - :fields — partial response field mask string
(get-customer client name & [opts])Get one customer by resource name.
name — the customer resource name (e.g. "accounts/A012345/customers/C987").
opts:
Get one customer by resource name. name — the customer resource name (e.g. "accounts/A012345/customers/C987"). opts: - :fields — partial response field mask string
(get-entitlement client name & [opts])Get one entitlement by resource name.
name — the entitlement resource name (e.g. "accounts/A1/customers/C1/entitlements/E1").
opts:
Get one entitlement by resource name. name — the entitlement resource name (e.g. "accounts/A1/customers/C1/entitlements/E1"). opts: - :fields — partial response field mask string
(get-operation client operation-name & [opts])Get a long-running operation by name. Returned operation has :done (boolean), :metadata (operation-specific progress info), and either :response (when done successfully) or :error (when done with failure).
opts:
Get a long-running operation by name. Returned operation has :done (boolean), :metadata (operation-specific progress info), and either :response (when done successfully) or :error (when done with failure). opts: - :fields — partial response field mask string
(import-customer client parent request & [opts])Import a customer's Cloud Identity into the reseller account. SYNCHRONOUSLY returns the resulting Customer (NOT an Operation — this is not an LRO).
parent — the reseller account resource name (the import target). request — map with kebab-case keys: :domain or :cloud-identity-id — required; identifies the source customer :auth-token — optional auth token :overwrite-if-exists — boolean :channel-partner-id — optional channel-partner-link id :customer — optional override Customer fields
opts:
Import a customer's Cloud Identity into the reseller account. SYNCHRONOUSLY returns the resulting Customer (NOT an Operation — this is not an LRO). parent — the reseller account resource name (the import target). request — map with kebab-case keys: :domain or :cloud-identity-id — required; identifies the source customer :auth-token — optional auth token :overwrite-if-exists — boolean :channel-partner-id — optional channel-partner-link id :customer — optional override Customer fields opts: - :fields — partial response field mask string
(list-billable-skus client parent & [opts])List the billable SKUs within a SKU group.
parent — the SKU-group resource name (e.g. "accounts/A1/skuGroups/sg1").
opts:
List the billable SKUs within a SKU group. parent — the SKU-group resource name (e.g. "accounts/A1/skuGroups/sg1"). opts: - :page-size, :page-token, :fields
(list-channel-partner-link-customers client parent & [opts])List customers under a channel-partner link.
parent — the channel-partner-link resource name.
opts:
List customers under a channel-partner link. parent — the channel-partner-link resource name. opts: - :filter — server-side filter expression - :page-size, :page-token, :fields
(list-channel-partner-links client parent & [opts])List the reseller's channel-partner links.
parent — the reseller account resource name.
opts:
List the reseller's channel-partner links. parent — the reseller account resource name. opts: - :view — "BASIC" or "FULL" (default unspecified) - :page-size, :page-token, :fields
(list-customers client parent & [opts])List customers managed by the reseller account.
parent — the reseller account resource name (e.g. "accounts/A012345").
opts:
List customers managed by the reseller account. parent — the reseller account resource name (e.g. "accounts/A012345"). opts: - :filter — server-side filter expression - :page-size — int (1..1000) - :page-token — token from a previous response - :fields — partial response field mask string
(list-entitlement-changes client parent & [opts])List the change history for one entitlement.
parent — the entitlement resource name.
opts:
List the change history for one entitlement. parent — the entitlement resource name. opts: - :filter — server-side filter expression - :page-size, :page-token, :fields
(list-entitlements client parent & [opts])List the customer's active entitlements.
parent — the customer resource name (e.g. "accounts/A1/customers/C1").
opts:
List the customer's active entitlements. parent — the customer resource name (e.g. "accounts/A1/customers/C1"). opts: - :page-size, :page-token, :fields
(list-offers client parent & [opts])List Offers the reseller can use to create entitlements.
parent — the reseller account resource name.
opts:
List Offers the reseller can use to create entitlements. parent — the reseller account resource name. opts: - :filter — server-side filter expression - :language-code — BCP-47 locale - :show-future-offers — boolean - :page-size, :page-token, :fields
(list-operations client & [opts])List long-running operations.
opts:
List long-running operations. opts: - :filter — server-side filter expression (e.g. "done=false") - :page-size, :page-token, :fields
(list-products client & [opts])List Cloud Channel products visible to the reseller.
opts:
List Cloud Channel products visible to the reseller. opts: - :account — the reseller account resource name (required by the API) - :language-code — BCP-47 locale - :page-size, :page-token, :fields
(list-purchasable-offers client customer & [opts])List Offers the customer can purchase. Pass either the create-entitlement context or the change-offer context (see :create-entitlement-* / :change-offer-* opts below).
customer — the customer resource name.
opts:
List Offers the customer can purchase. Pass either the create-entitlement context or the change-offer context (see :create-entitlement-* / :change-offer-* opts below). customer — the customer resource name. opts: - :create-entitlement-purchase-sku — SKU name (new purchase) - :create-entitlement-purchase-billing-account — billing-account name - :change-offer-purchase-entitlement — entitlement name - :change-offer-purchase-new-sku — SKU name (post-change) - :change-offer-purchase-billing-account — billing-account name - :language-code — BCP-47 locale - :page-size, :page-token, :fields
(list-purchasable-skus client customer & [opts])List SKUs the customer can purchase. Supports either the
create-entitlement context (:create-entitlement-purchase-product) or
the change-offer context (:change-offer-purchase-entitlement plus
:change-offer-purchase-change-type).
customer — the customer resource name.
opts:
List SKUs the customer can purchase. Supports either the create-entitlement context (`:create-entitlement-purchase-product`) or the change-offer context (`:change-offer-purchase-entitlement` plus `:change-offer-purchase-change-type`). customer — the customer resource name. opts: - :create-entitlement-purchase-product — product name (for new purchases) - :change-offer-purchase-entitlement — entitlement name (for change-offer) - :change-offer-purchase-change-type — "UPGRADE"/"DOWNGRADE"/etc. - :language-code — BCP-47 locale - :page-size, :page-token, :fields
(list-sku-groups client parent & [opts])List SKU groups visible to the reseller.
parent — the reseller account resource name.
opts:
List SKU groups visible to the reseller. parent — the reseller account resource name. opts: - :page-size, :page-token, :fields
(list-skus client parent & [opts])List Cloud Channel SKUs under a given product.
parent — the product resource name (e.g. "products/p1").
opts:
List Cloud Channel SKUs under a given product. parent — the product resource name (e.g. "products/p1"). opts: - :account — the reseller account resource name (required by the API) - :language-code — BCP-47 locale - :page-size, :page-token, :fields
(list-subscribers client account & [opts])List Pub/Sub subscriber service-account names registered on the reseller account for Cloud Channel push notifications.
NOTE: this returns Pub/Sub subscriber identities, NOT customer subscriptions. The name shadow is Google's, not ours.
account — the reseller account resource name (e.g. "accounts/A012345").
opts:
List Pub/Sub subscriber service-account names registered on the reseller account for Cloud Channel push notifications. NOTE: this returns Pub/Sub subscriber identities, NOT customer subscriptions. The name shadow is Google's, not ours. account — the reseller account resource name (e.g. "accounts/A012345"). opts: - :page-size — int (1..1000) - :page-token — token from a previous response - :fields — partial response field mask string
(list-transferable-offers client parent request & [opts])List Offers eligible for transfer for a given SKU + customer.
parent — the reseller account resource name. request — map with kebab-case keys: :cloud-identity-id or :customer-name — identifies the customer :sku — required; SKU resource name :page-size, :page-token — pagination :language-code — optional BCP-47 locale :billing-account — optional billing-account name
opts:
List Offers eligible for transfer for a given SKU + customer. parent — the reseller account resource name. request — map with kebab-case keys: :cloud-identity-id or :customer-name — identifies the customer :sku — required; SKU resource name :page-size, :page-token — pagination :language-code — optional BCP-47 locale :billing-account — optional billing-account name opts: - :fields — partial response field mask string
(list-transferable-skus client parent request & [opts])List SKUs eligible for transfer for a customer the reseller does not yet own. The pagination/auth fields live IN the request body, not the wrapper opts.
parent — the reseller account resource name (e.g. "accounts/A012345"). request — map with kebab-case keys: :cloud-identity-id — required; the cloud identity of the target customer :customer-name — alternative to :cloud-identity-id (one or the other) :auth-token — required for non-Google customers :page-size, :page-token — pagination :language-code — optional BCP-47 locale
opts:
List SKUs eligible for transfer for a customer the reseller does not yet own. The pagination/auth fields live IN the request body, not the wrapper opts. parent — the reseller account resource name (e.g. "accounts/A012345"). request — map with kebab-case keys: :cloud-identity-id — required; the cloud identity of the target customer :customer-name — alternative to :cloud-identity-id (one or the other) :auth-token — required for non-Google customers :page-size, :page-token — pagination :language-code — optional BCP-47 locale opts: - :fields — partial response field mask string
(lookup-offer client entitlement & [opts])Get the Offer currently associated with the given entitlement.
entitlement — the entitlement resource name.
opts:
Get the Offer currently associated with the given entitlement. entitlement — the entitlement resource name. opts: - :fields — partial response field mask string
(provision-cloud-identity client customer request & [opts])Provision a Cloud Identity for an existing customer that does not yet have one. Returns the initiating Operation immediately; poll with wait-for-operation.
customer — the customer resource name. request — map with kebab-case keys: :cloud-identity-info — required; CloudIdentityInfo map (e.g. {:language-code "en-US" :alternate-email "..."}) :user — required; admin-user map (:given-name :family-name :email) :validate-only — boolean; when true performs dry-run validation
opts:
Provision a Cloud Identity for an existing customer that does not yet have
one. Returns the initiating Operation immediately; poll with
wait-for-operation.
customer — the customer resource name.
request — map with kebab-case keys:
:cloud-identity-info — required; CloudIdentityInfo map
(e.g. {:language-code "en-US"
:alternate-email "..."})
:user — required; admin-user map
(:given-name :family-name :email)
:validate-only — boolean; when true performs dry-run validation
opts:
- :fields — partial response field mask string(query-eligible-billing-accounts client customer & [opts])List billing-account purchase groups the customer is eligible for. The response field is :sku-purchase-groups (each group maps SKUs to one or more billing accounts).
customer — the customer resource name.
opts:
List billing-account purchase groups the customer is eligible for. The response field is :sku-purchase-groups (each group maps SKUs to one or more billing accounts). customer — the customer resource name. opts: - :fields — partial response field mask string
(transfer-entitlements client parent request & [opts])Transfer entitlements from another reseller (or from a direct-buy customer) into a customer on the receiving reseller account. Returns the initiating Operation immediately; poll with wait-for-operation to await completion.
parent — the receiving customer resource name (e.g. "accounts/A1/customers/C1"). The SDK validates this against ^accounts/[^/]+/customers/[^/]+$ at request-build time. request — map with kebab-case keys: :entitlements — required; a list of entitlement maps to transfer :auth-token — required; the transfer auth token from the source side :request-id — optional client-side idempotency token
opts:
Transfer entitlements from another reseller (or from a direct-buy customer)
into a customer on the receiving reseller account. Returns the initiating
Operation immediately; poll with wait-for-operation to await completion.
parent — the receiving customer resource name
(e.g. "accounts/A1/customers/C1"). The SDK validates this
against ^accounts/[^/]+/customers/[^/]+$ at request-build time.
request — map with kebab-case keys:
:entitlements — required; a list of entitlement maps to transfer
:auth-token — required; the transfer auth token from the source side
:request-id — optional client-side idempotency token
opts:
- :fields — partial response field mask string(transfer-entitlements-to-google client parent request & [opts])Transfer entitlements from a customer back to direct Google billing. Returns the initiating Operation immediately; poll with wait-for-operation.
parent — the customer resource name losing the entitlements (e.g. "accounts/A1/customers/C1"). The SDK validates this against ^accounts/[^/]+/customers/[^/]+$ at request-build time. request — map with kebab-case keys: :entitlements — required; a list of entitlement maps to release :request-id — optional client-side idempotency token
opts:
Transfer entitlements from a customer back to direct Google billing.
Returns the initiating Operation immediately; poll with wait-for-operation.
parent — the customer resource name losing the entitlements
(e.g. "accounts/A1/customers/C1"). The SDK validates this
against ^accounts/[^/]+/customers/[^/]+$ at request-build time.
request — map with kebab-case keys:
:entitlements — required; a list of entitlement maps to release
:request-id — optional client-side idempotency token
opts:
- :fields — partial response field mask string(wait-for-operation client operation-name & [opts])Poll a long-running Operation until it reports :done true, or until :timeout-ms elapses.
operation-name — the full resource name returned by the initiating call (typically the :name field of the Operation map).
opts:
Returns {:data <operation-map>} when the operation reports done=true, or {:error ...} on timeout or on the first polling failure. Note the returned operation map may itself contain :error — that's the operation's own failure result, distinct from a polling failure.
Delegates the polling loop to csl/wait-for-operation; this fn is a thin library-specific shim that closes over Cloud Channel's get-operation.
Poll a long-running Operation until it reports :done true, or until
:timeout-ms elapses.
operation-name — the full resource name returned by the initiating call
(typically the :name field of the Operation map).
opts:
- :poll-interval-ms — int, milliseconds between polls (default 5000)
- :timeout-ms — int, overall deadline in milliseconds (default 600000
= 10 minutes)
- :read-timeout-ms — int, per-poll HTTP read timeout
Returns {:data <operation-map>} when the operation reports done=true, or
{:error ...} on timeout or on the first polling failure. Note the returned
operation map may itself contain :error — that's the operation's own
failure result, distinct from a polling failure.
Delegates the polling loop to csl/wait-for-operation; this fn is a thin
library-specific shim that closes over Cloud Channel's get-operation.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |