Operations for managing customers in Plain.
Summary
Functions
Adds a customer to one or more customer groups.
Deletes a customer by ID.
Fetches a customer by their email address.
Returns {:ok, nil} if not found.
Fetches a customer by their external ID (your system's identifier).
Returns {:ok, nil} if not found.
Fetches a customer by their Plain ID (e.g. "c_01HX...").
Returns {:ok, nil} if not found.
Returns a paginated list of customers.
Removes a customer from one or more customer groups.
Updates the company associated with a customer.
Creates or updates a customer (upsert).
Functions
@spec add_to_customer_groups(ExPlain.Client.t(), map()) :: {:ok, list()} | {:error, ExPlain.Error.t()}
Adds a customer to one or more customer groups.
Example
ExPlain.Customers.add_to_customer_groups(client, %{
customer_id: "c_01HX...",
customer_group_identifiers: [%{customer_group_key: "enterprise"}]
})
@spec delete(ExPlain.Client.t(), String.t()) :: {:ok, :deleted} | {:error, ExPlain.Error.t()}
Deletes a customer by ID.
@spec get_by_email(ExPlain.Client.t(), String.t()) :: {:ok, ExPlain.Customers.Customer.t() | nil} | {:error, ExPlain.Error.t()}
Fetches a customer by their email address.
Returns {:ok, nil} if not found.
@spec get_by_external_id(ExPlain.Client.t(), String.t()) :: {:ok, ExPlain.Customers.Customer.t() | nil} | {:error, ExPlain.Error.t()}
Fetches a customer by their external ID (your system's identifier).
Returns {:ok, nil} if not found.
@spec get_by_id(ExPlain.Client.t(), String.t()) :: {:ok, ExPlain.Customers.Customer.t() | nil} | {:error, ExPlain.Error.t()}
Fetches a customer by their Plain ID (e.g. "c_01HX...").
Returns {:ok, nil} if not found.
@spec list( ExPlain.Client.t(), keyword() ) :: {:ok, %{ nodes: [ExPlain.Customers.Customer.t()], page_info: ExPlain.PageInfo.t(), total_count: integer() }} | {:error, ExPlain.Error.t()}
Returns a paginated list of customers.
Options
Pagination: first:, after:, last:, before:.
Filtering: filters: (passed directly as a GraphQL CustomersFilter input map).
Sorting: sort_by: (passed directly as a GraphQL CustomersSort input map).
Example
{:ok, page} = ExPlain.Customers.list(client, first: 50)
customers = page.nodes
next_cursor = page.page_info.end_cursor
@spec remove_from_customer_groups(ExPlain.Client.t(), map()) :: {:ok, :removed} | {:error, ExPlain.Error.t()}
Removes a customer from one or more customer groups.
Example
ExPlain.Customers.remove_from_customer_groups(client, %{
customer_id: "c_01HX...",
customer_group_identifiers: [%{customer_group_key: "enterprise"}]
})
@spec update_company(ExPlain.Client.t(), map()) :: {:ok, ExPlain.Customers.Customer.t()} | {:error, ExPlain.Error.t()}
Updates the company associated with a customer.
The input map must include :customer_id and :company_identifier.
:company_identifier is one of %{company_id: id} or %{domain_name: domain}.
Example
ExPlain.Customers.update_company(client, %{
customer_id: "c_01HX...",
company_identifier: %{domain_name: "example.com"}
})
@spec upsert(ExPlain.Client.t(), map()) :: {:ok, %{result: :created | :updated, customer: ExPlain.Customers.Customer.t()}} | {:error, ExPlain.Error.t()}
Creates or updates a customer (upsert).
The input map must include:
:identifier— one of:email_address,:customer_id, or:external_id.:on_create— fields to set on creation (required::email,:full_name).:on_update— fields to update if the customer already exists.
Snake_case keys are automatically converted to camelCase before sending.
Example
ExPlain.Customers.upsert(client, %{
identifier: %{email_address: %{email: "alice@example.com"}},
on_create: %{email: %{email: "alice@example.com"}, full_name: "Alice"},
on_update: %{full_name: %{value: "Alice Updated"}}
})