Clojure wrapper for the Google Admin SDK Directory API.
Provides idiomatic Clojure functions for managing users, groups, group members, and organizational units in a Google Workspace domain.
Auth: use csl/scoped-delegated-credentials with the appropriate scope and a super-admin impersonation target:
All list functions return {:data [...] :next-page-token "..."}. :next-page-token is absent when there are no further pages.
Update semantics: functions named update-* use PATCH (partial update); functions named replace-* use PUT (full replacement). Both return the updated resource.
All functions return {:data ...} on success or {:error ...} on failure.
Clojure wrapper for the Google Admin SDK Directory API.
Provides idiomatic Clojure functions for managing users, groups,
group members, and organizational units in a Google Workspace domain.
Auth: use csl/scoped-delegated-credentials with the appropriate scope
and a super-admin impersonation target:
- DirectoryScopes/ADMIN_DIRECTORY_USER (user read/write)
- DirectoryScopes/ADMIN_DIRECTORY_USER_READONLY
- DirectoryScopes/ADMIN_DIRECTORY_GROUP (group read/write)
- DirectoryScopes/ADMIN_DIRECTORY_GROUP_READONLY
- DirectoryScopes/ADMIN_DIRECTORY_GROUP_MEMBER (member read/write)
- DirectoryScopes/ADMIN_DIRECTORY_GROUP_MEMBER_READONLY
- DirectoryScopes/ADMIN_DIRECTORY_ORGUNIT (org unit read/write)
- DirectoryScopes/ADMIN_DIRECTORY_ORGUNIT_READONLY
- DirectoryScopes/ADMIN_DIRECTORY_ROLEMANAGEMENT (roles + assignments write; privileges read)
- DirectoryScopes/ADMIN_DIRECTORY_ROLEMANAGEMENT_READONLY (roles + assignments + privileges read)
- DirectoryScopes/ADMIN_DIRECTORY_USER_SECURITY (tokens/mobile/ASPs — read + revoke;
this library only exposes reads)
- DirectoryScopes/ADMIN_DIRECTORY_DOMAIN_READONLY (domains read)
- DirectoryScopes/ADMIN_DIRECTORY_RESOURCE_CALENDAR_READONLY (calendar resources read)
All list functions return {:data [...] :next-page-token "..."}.
:next-page-token is absent when there are no further pages.
Update semantics: functions named update-* use PATCH (partial update);
functions named replace-* use PUT (full replacement). Both return
the updated resource.
All functions return {:data ...} on success or {:error ...} on failure.(admin-client credentials)(admin-client credentials opts)Build an authenticated Admin SDK Directory client.
credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with a super-admin impersonation target.
opts (optional):
Per-request opts on individual call sites override the client-level defaults.
Build an authenticated Admin SDK Directory client. credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with a super-admin impersonation target. 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.
(create-group client group-data & [opts])Create a new group.
group-data — map with kebab-case keys: :email — the group's email address (required) :name — display name :description — group description
Create a new group. group-data — map with kebab-case keys: :email — the group's email address (required) :name — display name :description — group description
(create-org-unit client customer-id org-unit-data & [opts])Create a new organizational unit.
customer-id — customer ID (e.g. "my_customer") org-unit-data — map with kebab-case keys: :name — the org unit's name (required) :parent-org-unit-path — parent path (e.g. "/") (required)
Create a new organizational unit. customer-id — customer ID (e.g. "my_customer") org-unit-data — map with kebab-case keys: :name — the org unit's name (required) :parent-org-unit-path — parent path (e.g. "/") (required)
(create-role client customer role-data & [opts])Create an admin role definition.
customer is either "my_customer" or an explicit customer id.
role-data — map with kebab-case keys: :role-name — the role's display name (required) :role-description — human-readable description (optional) :role-privileges — [{:privilege-name … :service-id …} …]: the privileges the role grants (optional; the pairs come from list-privileges / flatten-privileges)
The response carries the tenant-assigned :role-id as a NUMBER (a Long). Ledger it as-is for the undo path; the write-side fns (delete-role, insert-role-assignment) accept either a number or a string.
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
opts:
Create an admin role definition.
`customer` is either "my_customer" or an explicit customer id.
role-data — map with kebab-case keys:
:role-name — the role's display name (required)
:role-description — human-readable description (optional)
:role-privileges — [{:privilege-name … :service-id …} …]: the privileges
the role grants (optional; the pairs come from
list-privileges / flatten-privileges)
The response carries the tenant-assigned :role-id as a NUMBER (a Long).
Ledger it as-is for the undo path; the write-side fns (delete-role,
insert-role-assignment) accept either a number or a string.
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
opts:
- :fields — partial response field mask string(create-user client user-data & [opts])Create a new user.
user-data — map with kebab-case keys: :primary-email — the user's email address (required) :name — {:given-name "..." :family-name "..."} (required) :password — initial password (required) :org-unit-path — organizational unit (optional, defaults to "/")
Create a new user.
user-data — map with kebab-case keys:
:primary-email — the user's email address (required)
:name — {:given-name "..." :family-name "..."} (required)
:password — initial password (required)
:org-unit-path — organizational unit (optional, defaults to "/")(delete-group client group-key & [opts])Delete a group.
Delete a group.
(delete-member client group-key member-key & [opts])Remove a member from a group.
Remove a member from a group.
(delete-org-unit client customer-id org-unit-path & [opts])Delete an organizational unit.
Delete an organizational unit.
(delete-role client customer role-id & [opts])Delete an admin role definition by id.
role-id may be a string or the Long ledgered from a create-role /
list-roles response — it is str-coerced internally (roleId is a
@JsonString id; see ->role-assignment-model).
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
Delete an admin role definition by id. `role-id` may be a string or the Long ledgered from a create-role / list-roles response — it is str-coerced internally (roleId is a @JsonString id; see ->role-assignment-model). Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
(delete-role-assignment client customer role-assignment-id & [opts])Delete a role assignment by id.
role-assignment-id may be a string or the Long ledgered from an
insert-role-assignment / list-role-assignments response — it is str-coerced
internally (roleAssignmentId is a @JsonString id).
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
Delete a role assignment by id. `role-assignment-id` may be a string or the Long ledgered from an insert-role-assignment / list-role-assignments response — it is str-coerced internally (roleAssignmentId is a @JsonString id). Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
(flatten-privileges privileges)Flatten a privilege tree (the :data of list-privileges) into a flat vector of privilege maps, depth-first (pre-order), each with :child-privileges removed. Pure.
The Directory privileges.list response nests child privileges under :child-privileges; a fidelity check that needs set-membership over {:privilege-name :service-id} pairs wants them flat:
(->> (:data (list-privileges client "my_customer")) flatten-privileges (map #(select-keys % [:privilege-name :service-id])) set)
Flatten a privilege tree (the :data of list-privileges) into a flat vector
of privilege maps, depth-first (pre-order), each with :child-privileges
removed. Pure.
The Directory privileges.list response nests child privileges under
:child-privileges; a fidelity check that needs set-membership over
{:privilege-name :service-id} pairs wants them flat:
(->> (:data (list-privileges client "my_customer"))
flatten-privileges
(map #(select-keys % [:privilege-name :service-id]))
set)(get-calendar-resource client customer resource-id & [opts])Get a single calendar resource by id.
customer is either "my_customer" or an explicit customer id.
opts:
Get a single calendar resource by id. `customer` is either "my_customer" or an explicit customer id. opts: - :fields — partial response field mask string
(get-domain client customer domain-name & [opts])Get a single domain by name (primary, secondary, or alias).
customer is either "my_customer" for the caller's own tenant, or an
explicit customer id from a delegated-admin context.
opts:
Get a single domain by name (primary, secondary, or alias). `customer` is either "my_customer" for the caller's own tenant, or an explicit customer id from a delegated-admin context. opts: - :fields — partial response field mask string
(get-group client group-key & [opts])Get a group by email address or group ID.
opts:
Get a group by email address or group ID. opts: - :fields — partial response field mask string
(get-member client group-key member-key & [opts])Get a member of a group by email or user ID.
Get a member of a group by email or user ID.
(get-org-unit client customer-id org-unit-path & [opts])Get an organizational unit by path.
org-unit-path — path without the leading "/" (e.g. "Engineering" or "Engineering/Backend")
opts:
Get an organizational unit by path.
org-unit-path — path without the leading "/"
(e.g. "Engineering" or "Engineering/Backend")
opts:
- :fields — partial response field mask string(get-role client customer role-id & [opts])Get a single admin role definition.
opts:
Get a single admin role definition. opts: - :fields — partial response field mask string
(get-role-assignment client customer role-assignment-id & [opts])Get a single role assignment.
opts:
Get a single role assignment. opts: - :fields — partial response field mask string
(get-token client user-key client-id & [opts])Get a single OAuth grant by client id.
opts:
Get a single OAuth grant by client id. opts: - :fields — partial response field mask string
(get-user client user-key & [opts])Get a user by primary email or user ID.
opts:
Get a user by primary email or user ID. opts: - :projection — :basic, :custom, or :full - :fields — partial response field mask string
(has-member client group-key member-key & [opts])Check whether a user is a member of a group. Returns {:data {:is-member true/false}}.
Check whether a user is a member of a group.
Returns {:data {:is-member true/false}}.(insert-member client group-key member-data & [opts])Add a member to a group.
member-data — map with kebab-case keys: :email — the member's email address (required) :role — "MEMBER" (default), "MANAGER", or "OWNER"
Add a member to a group. member-data — map with kebab-case keys: :email — the member's email address (required) :role — "MEMBER" (default), "MANAGER", or "OWNER"
(insert-role-assignment client customer assignment-data & [opts])Bind an existing role to an existing principal (a user OR a group).
Named insert (not create) per the insert-member precedent — it attaches
an existing role to an existing principal.
customer is either "my_customer" or an explicit customer id.
assignment-data — map with kebab-case keys: :role-id — id of the role to assign; string or number, normalized internally (see ->role-assignment-model) (required) :assigned-to — directory id of the USER or GROUP to grant the role to; not validated to users — a group id is valid (required) :scope-type — "CUSTOMER" (tenant-wide) or "ORG_UNIT" (required) :org-unit-id — the org unit id; required iff :scope-type is "ORG_UNIT" :condition — optional condition expression (pass-through)
The response carries the tenant-assigned :role-assignment-id as a NUMBER; ledger it as-is for delete-role-assignment.
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
opts:
Bind an existing role to an existing principal (a user OR a group).
Named `insert` (not `create`) per the insert-member precedent — it attaches
an existing role to an existing principal.
`customer` is either "my_customer" or an explicit customer id.
assignment-data — map with kebab-case keys:
:role-id — id of the role to assign; string or number, normalized
internally (see ->role-assignment-model) (required)
:assigned-to — directory id of the USER or GROUP to grant the role to;
not validated to users — a group id is valid (required)
:scope-type — "CUSTOMER" (tenant-wide) or "ORG_UNIT" (required)
:org-unit-id — the org unit id; required iff :scope-type is "ORG_UNIT"
:condition — optional condition expression (pass-through)
The response carries the tenant-assigned :role-assignment-id as a NUMBER;
ledger it as-is for delete-role-assignment.
Requires the writeable ADMIN_DIRECTORY_ROLEMANAGEMENT scope.
opts:
- :fields — partial response field mask string(list-asps client user-key & [opts])List application-specific passwords the user has created.
ASPs are used for legacy clients (older mail clients, etc.) and do not migrate across tenants.
user-key accepts an email or Google user id.
opts:
List application-specific passwords the user has created. ASPs are used for legacy clients (older mail clients, etc.) and do not migrate across tenants. `user-key` accepts an email or Google user id. opts: - :fields — partial response field mask string
(list-calendar-resources client customer & [opts])List calendar resources (conference rooms, equipment) in the tenant.
customer is either "my_customer" or an explicit customer id.
opts:
List calendar resources (conference rooms, equipment) in the tenant.
`customer` is either "my_customer" or an explicit customer id.
opts:
- :max-results — page size
- :page-token — token from a previous response
- :query — server-side filter (e.g. "buildingId=BLDG-1 capacity>=8")
- :order-by — :capacity or :resource-name (kebab keyword coerced
to camelCase; raw strings also accepted)
- :fields — partial response field mask string(list-domains client customer & [opts])List all domains owned by the tenant (primary, secondary, alias).
customer is either "my_customer" or an explicit customer id.
Pagination is not supported by the Admin SDK; the API returns all domains in a single response. The :next-page-token key will always be absent from the result.
opts:
List all domains owned by the tenant (primary, secondary, alias). `customer` is either "my_customer" or an explicit customer id. Pagination is not supported by the Admin SDK; the API returns all domains in a single response. The :next-page-token key will always be absent from the result. opts: - :fields — partial response field mask string
(list-groups client & [opts])List groups. Filter by customer, domain, or user membership.
opts:
List groups. Filter by customer, domain, or user membership. opts: - :customer — customer ID (e.g. "my_customer") - :domain — domain name - :user-key — list groups that this user belongs to (email or user ID) - :query — search query string - :order-by — :email (currently the only supported value) - :sort-order — "ASCENDING" or "DESCENDING" - :page-token — token from a previous response - :page-size — max groups per page - :fields — partial response field mask string
(list-members client group-key & [opts])List members of a group.
opts:
List members of a group. opts: - :roles — comma-separated role filter (e.g. "MEMBER,MANAGER") - :include-derived-membership — boolean; include indirect members - :page-token — token from a previous response - :page-size — max members per page - :fields — partial response field mask string
(list-mobile-devices client customer-id & [opts])List mobile devices synced against the tenant.
customer-id is either "my_customer" or an explicit customer id.
The response items-key is :mobiledevices (Google chose lowercase
plural for the response array field name).
opts:
List mobile devices synced against the tenant. `customer-id` is either "my_customer" or an explicit customer id. The response items-key is `:mobiledevices` (Google chose lowercase plural for the response array field name). opts: - :max-results — page size - :order-by — :device-id, :email, :last-sync, :model, :name, :os, :status, :type - :page-token — token from a previous response - :projection — :basic or :full - :query — search query string - :sort-order — "ASCENDING" or "DESCENDING" - :fields — partial response field mask string
(list-org-units client customer-id & [opts])List organizational units.
opts:
List organizational units. opts: - :org-unit-path — parent path to list children of (default: all) - :type — :all (default), :children, or :all-including-parent - :fields — partial response field mask string
(list-privileges client customer & [opts])List the privilege tree for the tenant (Directory privileges.list).
customer is either "my_customer" or an explicit customer id.
Pagination is not supported by the Admin SDK; the API returns the full privilege tree in a single response. The :next-page-token key will always be absent from the result.
Items preserve the API's nested :child-privileges tree (fidelity to the wrapped API). For set-membership over {:privilege-name :service-id} pairs, flatten the tree with flatten-privileges.
Reads work under either ADMIN_DIRECTORY_ROLEMANAGEMENT or its READONLY variant.
opts:
List the privilege tree for the tenant (Directory privileges.list).
`customer` is either "my_customer" or an explicit customer id.
Pagination is not supported by the Admin SDK; the API returns the full
privilege tree in a single response. The :next-page-token key will always
be absent from the result.
Items preserve the API's nested :child-privileges tree (fidelity to the
wrapped API). For set-membership over {:privilege-name :service-id} pairs,
flatten the tree with flatten-privileges.
Reads work under either ADMIN_DIRECTORY_ROLEMANAGEMENT or its READONLY
variant.
opts:
- :fields — partial response field mask string(list-role-assignments client customer & [opts])List admin role assignments (user/group → role bindings) in the tenant.
customer is either "my_customer" or an explicit customer id.
opts:
List admin role assignments (user/group → role bindings) in the tenant.
`customer` is either "my_customer" or an explicit customer id.
opts:
- :max-results — page size
- :page-token — token from a previous response
- :user-key — limit to assignments for a specific user (email or id)
- :role-id — limit to assignments of a specific role
- :include-indirect-role-assignments — boolean; when true, also include
assignments inherited via group membership. Google's
default is false (direct assignments only) — the shape a
caller-side has-assignment idempotency probe expects.
- :fields — partial response field mask string(list-roles client customer & [opts])List admin role definitions in the tenant.
customer is either "my_customer" for the caller's own tenant, or
an explicit customer id from a delegated-admin context.
opts:
List admin role definitions in the tenant. `customer` is either "my_customer" for the caller's own tenant, or an explicit customer id from a delegated-admin context. opts: - :max-results — page size - :page-token — token from a previous response - :fields — partial response field mask string
(list-tokens client user-key & [opts])List OAuth grants the user has issued to third-party apps.
These describe scopes the user authorized to apps outside the tenant's own first-party Workspace apps — they do not migrate with the user.
user-key accepts an email or Google user id.
opts:
List OAuth grants the user has issued to third-party apps. These describe scopes the user authorized to apps outside the tenant's own first-party Workspace apps — they do not migrate with the user. `user-key` accepts an email or Google user id. opts: - :fields — partial response field mask string
(list-users client & [opts])List users in a domain. Requires either :customer or :domain.
opts:
List users in a domain. Requires either :customer or :domain. opts: - :customer — customer ID (e.g. "my_customer" for the caller's domain) - :domain — domain name (alternative to :customer) - :query — search query string - :order-by — :email, :family-name, or :given-name - :sort-order — "ASCENDING" or "DESCENDING" - :projection — :basic, :custom, or :full - :show-deleted — boolean - :page-token — token from a previous response - :page-size — max users per page - :fields — partial response field mask string
(replace-group client group-key group-data & [opts])Fully replace a group (PUT semantics).
Fully replace a group (PUT semantics).
(replace-member client group-key member-key member-data & [opts])Fully replace a member (PUT semantics).
Fully replace a member (PUT semantics).
(replace-org-unit client customer-id org-unit-path org-unit-data & [opts])Fully replace an organizational unit (PUT semantics).
Fully replace an organizational unit (PUT semantics).
(replace-user client user-key user-data & [opts])Fully replace a user (PUT semantics). The entire user resource is replaced with the provided data; omitted fields are cleared.
Fully replace a user (PUT semantics). The entire user resource is replaced with the provided data; omitted fields are cleared.
(update-group client group-key group-data & [opts])Partially update a group (PATCH semantics).
Partially update a group (PATCH semantics).
(update-member client group-key member-key member-data & [opts])Partially update a member's properties (PATCH semantics).
member-data — map with fields to update (e.g. {:role "MANAGER"})
Partially update a member's properties (PATCH semantics).
member-data — map with fields to update (e.g. {:role "MANAGER"})(update-org-unit client customer-id org-unit-path org-unit-data & [opts])Partially update an organizational unit (PATCH semantics).
Partially update an organizational unit (PATCH semantics).
(update-user client user-key user-data & [opts])Partially update a user (PATCH semantics). Only the fields present in the user-data map are modified; unspecified fields are left unchanged.
Partially update a user (PATCH semantics). Only the fields present in the user-data map are modified; unspecified fields are left unchanged.
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 |