> ## Documentation Index
> Fetch the complete documentation index at: https://www.plain.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upserting customers

> Learn how to create and update customers programmatically.

<Snippet file="graphql/sdk-note.mdx" />

Creating and updating customers is handled via a single API called `upsertCustomer`.

When you upsert a customer, you define:

1. The identifier: This is the field you'd like to use to select the customer and is one of
   * `emailAddress`: This is the customer's email address. Within Plain email addresses are unique to customers.
   * `customerId`: This is Plain's customer ID. Implicitly if you use this as an identifier you will only be updating the customer since the customer can't have an id unless it already exists.
   * `externalId`: This is the customer's id in your systems. If you previously set this it can be a powerful way of syncing customer details from your backend with Plain.
2. The customer details you'd like to use if creating the customer.
3. The customer details you'd like to update if the customer already exists.

When upserting a customer you will always get back a customer or an error.

## Upserting a customer

This operation requires the following permissions:

* `customer:create`
* `customer:edit`

This will:

* Find a customer with the email '[donald@example.com](mailto:donald@example.com)' (the identifier).
* If a customer with that email exists will update it (see `onUpdate` below)
* Otherwise, it will create the customer (see `onCreate` below)

The GraphQL mutation is the following:

<Snippet file="graphql/upsert-customer.mdx" />

The value of the `result` type will be:

* `CREATED`: if a customer didn't exist and was created
* `UPDATED`: if a customer already existed AND the values being updated **were different**.
* `NOOP`: if a customer already existed AND the values being updated **were the same**
