Use the Square Customers API to search for customers using one or more supported query filters.
Customers API

Search for Customer Profiles

Developers can use the SearchCustomers endpoint in the Customers API to search customer profiles in the Customer Directory using supported query filters. The search results include all customer profiles that meet the query conditions.

The SearchCustomers endpoint searches the Customer Directory for a seller account. When calling this endpoint, you can use one or more of the following search query filters in any combination:

  • phone_number. Filters by the phone number of the customer profile, which was collected by the seller or imported into the Customer Directory.

  • email_address. Filters by the email address of the customer profile, which was collected by the seller or imported into the Customer Directory.

  • creation_source. Filters by the source that created the customer profile.

  • created_at. Filters by the timestamp of when the customer profile was created.

  • updated_at. Filters by the timestamp of when the customer profile was last updated.

  • reference_id. Filters by an ID used to cross-reference the customer to an entity in an external system.

  • group_ids. Filters by the customer groups the customer profile belongs to.

  • segment_ids. Filters by the customer segments the customer profile belongs to.

  • custom_attribute. Filters by the value or updated date of custom attributes that are associated with a customer profile.

Note

For information about using the Customers API to create and manage customer profiles, see Keep Customer Records.

Multiple query filters specified in a search request are combined as AND statements, so the search results include the customer profiles that meet all the query conditions. These matching customer profiles are represented as a list of Customer objects.

Consider the following set of customer profiles, all of which were updated in the last week:

  • Customer A. Created 1 year ago through an eCommerce site that calls the Customers API.

  • Customer B. Created 2 months ago through an eCommerce site that calls the Customers API.

  • Customer C. Created 2 weeks ago using Square Point of Sale.

The following table shows example search queries for the set of customer profiles. Note that only profiles that satisfy all of the filters in the search query are returned in the results.

Search queryCustomers returned
Include profiles created through the Customers API.
Include profiles created in the last 6 months.
Include profiles updated in the last week.
B
Include profiles created through the Customers API.
Include profiles updated in the last week.
A and B
Include profiles updated in the last week.A, B, and C

Combining multiple filters as OR statements in a search query is not supported. To search for customers that meet at least one of a set of query conditions, send multiple single-filter searches and then join the result sets.

When searching by email address, phone number, reference ID, and some custom attributes, the API lets you search with an exact or fuzzy match of the specified customer attributes against a query expression. With an exact search, a query expression is compared literally against the targeted customer attribute value. With a fuzzy match, the query expression is tokenized and each resulting token is compared against targeted attribute values. Customer profiles are returned if their targeted attribute values match all tokens in any order.

You can choose to sort search results using the created_at field or using the default sort order. By default, customer profiles are sorted alphanumerically by concatenating given_name and family_name. If these names are not set, a string comparison is performed using one of the following fields in the following order: company_name, email_address, and phone_number.

Under normal operating conditions, newly created or updated customer profiles become available in SearchCustomers and ListCustomers endpoints in less than 30 seconds after they are created or updated. Some updates can take up to 1 minute to propagate. Occasionally, extraordinary network conditions (such as, incidents or outages) can slow the propagation even further. Under such circumstances, newly created or updated profiles might not be included in your search result. When this happens, wait a short time and then retry your search request.

The default SearchCustomers page size is 100 records, but you can use the limit query filter to specify a smaller page size. If your search results include more than the default or specified limit, the endpoint paginates the results and returns a cursor that you can use to retrieve the next page of results. Note that the SearchCustomers endpoint treats the search limit as advisory and might return more or fewer results.

You can use the Seller Dashboard, a Square Point of Sale application, or the Customers API to create customer profiles in a seller account. Customer profiles created using the Seller Dashboard or a Square Point of Sale application have the Customer creation_source field set to the value of DIRECTORY. Profiles created using an application calling the Customers API have the creation_source field set to the value of THIRD_PARTY. When duplicate customer profiles are merged manually or automatically into a new and updated profile, the new customer profile's creation_source is set to MERGE.

To search customer profiles by creation source, submit a request with the creation_source filter specified in the request body. The following example shows how to search for customer profiles created by the Square Directory service, namely, through the Seller Dashboard or a Square Point of Sale application:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "creation_source": {
          "values": [
            "DIRECTORY"
          ]
        }
      }
    }
  }'

To search for customer profiles created by third-party applications, change the creation_source filter in the previous example to use THIRD_PARTY in place of DIRECTORY:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "creation_source": {
          "values": [
            "THIRD_PARTY"
          ]
        }
      }
    }
  }'

To search for customer profiles created by the Directory service or a third-party application, use the following filter in the request body:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "creation_source": {
          "values": [
            "DIRECTORY",
            "THIRD_PARTY"
          ]
        }
      }
    }
  }'

You can call the SearchCustomers endpoint with the created_at or updated_at filter to search for customer profiles based on the time they were created or last updated, respectively. Such filters are useful to synchronize customer data by polling. For example, you can send updated_at search queries at a given time interval and determine subsequent actions to take on the customer profiles returned in the results.

The created_at and updated_at filters are identical in structure. They both require that you specify a start_at and end_at time to specify a time interval in which the targeted customer profiles were created or updated. For example, the following created_at filter defines the time interval when targeted customer profiles were created:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "created_at": {
          "end_at": "2020-04-30T00:00:00.001Z",
          "start_at": "2020-03-30T00:00:00.001Z"
        }
      }
    }
  }'

The timestamp format must be RFC-3339 compliant.

To search for a customer profile created or updated at a specific point of time, set the start_at value slightly smaller than the end_at value. The following updated_at filter shows an example of how to specify a specific time when a customer profile was updated:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "created_at": {
          "end_at": "2020-04-15T00:19:28.6Z",
          "start_at": "2020-04-15T00:19:28Z"
        }
      }
    }
  }'

You can search for customer profiles by email address with an exact or fuzzy filter. A search query can include either an exact filter or a fuzzy filter, but not both.

To search for customer profiles by email address with an exact match, use the email_address filter as shown in the following search request example:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "email_address": {
          "exact": "johndoe@hotmail.com"
        }
      }
    }
  }'

This returns all customer profiles whose email_address field holds the value of "johndoe@hotmail.com".

If you make an error in your query expression (for example, enter "johndoe@hotmail.com" as "johndoe@hotmail.co"), none of the previous results are returned. As shown in the following example, this behavior differs from the fuzzy search.

To search for customer profiles by email address with a fuzzy match, use the email_address filter as shown in the following search request example:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "email_address": {
          "fuzzy": "john.doe"
        }
      }
    }
  }'

The query expression of john.doe is first tokenized into two tokens of john and doe. The customer profile containing the email address of johndoe@hotmail.com matches both tokens and is therefore returned in the search result.

A fuzzy search also serves as a partial search. For example, if you typed johndoe@hotmail.co by mistake in the fuzzy query filter, you still get customer profiles containing the email address johndoe@hotmail.com.

A fuzzy search provides you with great flexibility. For example, you can obtain the customer profiles containing johndoe@hotmail.com even with the following fuzzy filter:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "email_address": {
          "fuzzy": "doe.john #com"
        }
      }
    }
  }'

Tokenization of the query expression of doe.john #com turns it into a three-token (john, doe, and com) query. The fuzzy search then selects customers profiles whose email addresses are john*doe@*.com or doe*john@*.com, where * stands for any valid email-address characters that can include, for example, ., _, or even a middle of name like joe.

Fuzzy search by email addresses can be a powerful option when used in a simple partial match or more advanced type-ahead user interfaces or embedded search experiences.

You can search for customer profiles by phone number with an exact or fuzzy filter. A search query can include either an exact filter or a fuzzy filter, but not both.

Phone numbers are represented by the phone_number field of a Customer object. Searches by phone number are applicable only to customer profiles that are stored in or imported into the seller's Customer Directory.

To conduct an exact search by phone number, specify the complete phone number in E.164-compliant format. This format starts with a + symbol and is followed by a country code and the subscriber number (which includes the area code). Spaces, dashes, parentheses, and periods are allowed in the query expression.

For an exact match operation, Square removes spaces and non-numeric characters from the query expression and the stored phone numbers.

The following are E.164-compliant examples:

  • +12345678901 (standard form)

  • +1-234-567-8901

  • +1 234.567.8901

  • +1 (234) 567-8901

The following example request shows an exact search by phone number using an E.164-compliant format:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "phone_number": {
          "exact": "+1 (234) 567-8901"
        }
      }
    }
  }'

Did you know?

For exact matching, specifying an E.164-compliant query expression (for example +12345678901) also returns phone numbers that use an international prefix instead of the + symbol (for example 0012345678901).

The following table shows more examples to demonstrate the behavior of the exact match phone_number filter:

Search queryMatched phone numbersUnmatched phone numbers
+14152345678 or
+1 (415) 234-5678
For US sellers:
4152345678
415.234.5678
415-234-5678
(415) 234-5678
+1(415)234-5678
For US sellers:
+12344155678
415-234-5679
+61298765432 or
+61 2 9876 5432
For AU sellers:
298765432
2 9876 5432
02 9876 5432
(02) 9876-5432
+61-2-9876-5432
For AU sellers:
+61 3 9876 5432
2 9876 5431

Fuzzy search by phone number works in a similar way to fuzzy search by email addresses. A phone number is tokenized by removing non-numeric characters. Matched customer profiles are those whose phone_number field has tokens that match all the provided tokens in the search query at least once in any order of tokens.

For a fuzzy match operation, Square first removes non-numeric characters from the query expression and then tokenizes the expression on spaces. For example, +33 becomes 33 and (234) 567-8901 becomes 234 5678901.

To use the fuzzy search by phone number, you can specify part of a customer's phone number. For example:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "phone_number": {
          "fuzzy": "(234) 567-8901"
        }
      }
    }
  }'

As another example, if you use the following fuzzy search filter:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "phone_number": {
          "fuzzy": "(234)567"
        }
      }
    }
  }'

You get all the US customers whose phone numbers use the following formats:

  • (234) 567-NNNN, (234) N56-7NNN, (234) NN5-67NN, (234) NNN-567N, (234) NNN-N567

  • (n23) 456-7NNN, (n23) 4N5-67NN, (n23) 4NN-567N, (n23) 4NN-N567

  • (nN2) 345-67NN, (nN2) 34N-567N, (nN2) 34N-N567

  • (nNN) 234-567N, (nNN) N23-4567, (nNN) 234-N567

  • (nNN) 567-234N, (nNN) N56-7243, (nNN) 567-N234

  • (nN5) 672-34NN, (nN5) 67N-234N, (nN5) 67N-N234

  • (n56) 723-4NNN, (n56) 7N2-34NN, (n56) 7NN-234N, (n56) 7NN-N234

  • (567) 234-NNNN, (567) N23-4NNN, (567) NN23-4NN, (567) NNN-234N, (567) NNN-N234

where "n" stands for any number between 1 and 9 and "N" stands for a number between 0 and 9. This example shows that the fuzzy phone_number filter matches a query expression with the stored phone_number field token by token, irrespective of the token order.

Fuzzy search by phone numbers can be powerful. For example, you can use a fuzzy search filter to offer likely matches that users can select while they enter the phone number digit by digit, provided that you have defined metrics for the likelihood of the match.

When a Square customer profile is associated with an external entity in another system, the association is captured by the reference_id field of the Square Customer object.

Given the ID of an external entity, you can use the Square Customers API search by reference ID to determine the associated customer profiles in a Square seller's Customer Directory. To do so, you specify a reference_id filter when calling the SearchCustomers endpoint.

As with search by email address and by phone number, the reference_id search filter lets you query customer profiles with an exact or fuzzy match of the query expression against the value of the reference_id field.

To search Square customer profiles by reference ID with an exact match, use a reference_id filter as shown in the following example search request:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "reference_id": {
          "exact": "ZGYZ-ABZG-97YX-XJ16"
        }
      }
    }
  }'

The response returns the Square customer profiles whose reference_id field is exactly ZGYZ-ABZG-97YX-XJ16.

To perform a fuzzy search by reference ID, use a fuzzy search filter as shown in the following example search filter:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "reference_id": {
          "fuzzy": "ZGYZ-97YX"
        }
      }
    }
  }'

This filter returns the customer profiles whose reference_id field contains the ZGYZ and 97YX tokens at least once each and in any order.

As a string value, a reference ID is tokenized by removing non-alphanumeric characters. A customer profile is selected if each provided token is matched at least once against the profile's reference_id field, irrespective of the order of the tokens.

Fuzzy search by reference ID can be a useful tool for managing customer profiles. For example, when used with a structured, multi-part identifier schema, a fuzzy search helps simplify the discovery of customer profiles in a structured way by matching part of a reference ID (for example, a prefix or suffix) or by querying reference IDs that contain multiple tokens.

Search queryMatched reference_idsUnmatched reference_ids
XJ15XJ15-ABZG-97YX-ZGYZ,
ZGYZ-ABZG-97YX-XJ15
ZGYZ-ABZG-97YX-XJ16
NYC MNYC_M_35_JOHNSON
NYC27MURRAY
NYC-F-27_WILSON
SFO_M_35_THOMAS

A customer can belong to one or more customer groups. Group membership is represented by the group_ids field of the corresponding customer profile, which stores the IDs of the groups the customer belongs to. This field is present only if the customer belongs to at least one group.

You can use the group_ids filter to search customer profiles based on their group membership. This filter specifies groups by ID and can contain any combination of the all, any, and none fields:

  • For all, the customer must belong to all of the specified groups (logical AND).

  • For any, the customer must belong to at least one of the specified groups (logical OR).

  • For none, the customer must not belong to any of the specified groups (logical NOT).

When multiple fields are provided, they are combined as AND statements. Customers must meet all filter conditions to be returned in the results.

If needed, you can obtain group IDs by calling ListCustomerGroups in the Customer Groups API.

The following example query searches for customers who belong to all the specified groups:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "group_ids": {
          "all": [
            "3XC8C32TMDEBMQBYX4NHD18C0E",
            "7DAZDCNJ8E4T72NYGZAZQWXB7V",
            "GHW0ZG7WAFS5JYJAEKBMZRCAN"
          ]
        }
      }
    }
  }'

The following example searches for regular customers (based the LOYAL segment) who enrolled in the Free Lunch Giveaway group (7WDV991WCZD7BW4896CZYGAEAS) and who have not yet won a free lunch in this period (HEM2Z4Y5DJKA172RSNKSNHKX5S):

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "group_ids": {
          "all": [
            "7WDV991WCZD7BW4896CZYGAEAS"
          ],
          "none": [
            "HEM2Z4Y5DJKA172RSNKSNHKX5S"
          ]
        },
        "segment_ids": {
          "all": [
            "8QJTJCE6AZSN6.LOYAL"
          ]
        }
      }
    }
  }'

A customer can belong to one or more customer segments. Segment membership is represented by the segment_ids field of the corresponding customer profile, which stores the IDs of the segments the customer belongs to. This field is present only if the customer belongs to at least one segment. Segment membership is dynamic and adjusts automatically based on whether the customer currently meets the segment criteria.

You can use the segment_ids filter to search customer profiles based on their segment membership. This filter can specify up to three segment IDs using any combination of the any, all, and none fields:

  • For all, the customer must belong to all of the specified segments (logical AND).

  • For any, the customer must belong to at least one of the specified segments (logical OR).

  • For none, the customer must not belong to any of the specified segments (logical NOT).

When multiple fields are provided, they are combined as AND statements. Customers must meet all filter conditions to be returned in the results.

If needed, you can obtain segment IDs by calling ListCustomerSegments in the Customer Segments API.

The following example query searches for customers who belong to any of the specified segments:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "segment_ids": {
          "any": [
            "gv2:3G1SNN8M0X2AXFEBN0GSY85M39",
            "gv2:4TR2ND9K1FVP8N63FZ5E62VD78",
            "gv2:8H24YRH20M7430XWJWP9F0MAEZ"
          ]
        }
      }
    }
  }'

The following example query searches for customer profiles created in the first half of 2022 who are lapsed and can be reached, but who do not have a history of low visits (gv2:KF92J19VXN5FK30GX2E8HSGQ20).

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "segment_ids": {
          "all": [
            "1KB9JE5EGJXCW.CHURN_RISK",
            "1KB9JE5EGJXCW.REACHABLE"
          ],
          "none": [
            "gv2:KF92J19VXN5FK30GX2E8HSGQ20"
          ]
        },
        "created_at": {
          "start_at": "2022-01-01T00:00:00Z",
          "end_at": "2022-05-31T23:59:59Z"
        }
      }
    }
  }'

When the segment_ids filter is included in a search query, Square validates that the specified IDs map to existing segments. If an invalid segment ID is found, Square stops processing the request and returns a 400 BAD_REQUEST error with the invalid ID.

You can search customer profiles by one or more custom attributes, which contain custom properties or metadata for the customer profile. For example, a customer profile might have EmergencyContactName and EmergencyContactPhone custom attributes. You can search based on the value of a custom attribute or its last updated date.

The custom_attribute filter has a filters array that can contain up to 10 custom attribute filters. Each custom attribute filter must specify:

  • The key of the target custom attribute.

  • One or both of the following:

    • filter with the value filter that corresponds to the data type of the target custom attribute. For example, use the address filter to search by an Address-type custom attribute.

    • updated_at with start_at, end_at, or both.

The following example includes two custom attribute filters. This query searches for all customer profiles whose veterinarian_name custom attribute is Pet Hospital and whose is_member custom attribute is true and was last updated in April 2022.

Multiple custom attribute filters in a search query are combined as AND statements. Combining filters as OR statements in a query is not supported, but you can send multiple single-filter queries and join the result sets.

The following are supported custom attribute filters:

The following considerations apply when using the custom_attribute filter:

  • The SearchCustomers endpoint returns matching customer profiles, which do not contain custom attributes. However, you can call RetrieveCustomerCustomAttribute or ListCustomerCustomAttributes using a customer ID from the result set to retrieve or list custom attributes for a specified customer profile.

  • To be valid for a search, the custom attributes must be visible to the requesting application. Specifically, the requesting application must be the definition owner or the visibility setting of the custom attributes in the query must be VISIBILITY_READ_ONLY or VISIBILITY_READ_WRITE_VALUES. Note that seller-defined custom attributes (also known as custom fields) are always set to VISIBILITY_READ_WRITE_VALUES.

  • A CustomAttributeDefinition object defines properties for its corresponding custom attributes. Some properties (such as the key identifier and visibility setting) are copied from the definition. Other properties (such as the schema data type or name) are defined only on the definition but apply to the custom attribute.

    You can use the following Customer Custom Attributes API endpoints if you need to retrieve a custom attribute definition to get information for your query:

  • Square returns an empty result set if no matches are found or if one of the following conditions is true:

    • A custom attribute in the query corresponds to a custom attribute definition that does not exist in the seller account.

    • A custom attribute in the query corresponds to a custom attribute definition that was created by another application and has a visibility setting of VISIBILITY_HIDDEN.

    • The data type of a custom attribute in the query does not match the provided value filter. For example, the data type of the custom attribute is PhoneNumber but the value filter is email.

Use the address filter to search based on the value of an Address-type custom attribute. The filter can include postal_code, country, or both. The postal_code parameter only supports the exact match condition.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "business-address",
              "filter": {
                "address": {
                  "country": "FR",
                  "postal_code": {
                    "exact": "98101"
                  }
                }
              }
            }
          ]
        }
      }
    }
  }'

Other address fields are not supported as search parameters.

Use the boolean filter to search based on the value of a Boolean-type custom attribute.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "sq0idp-BughoY39o1X-GPxSSUWc0A:is_member",
              "filter": {
                "boolean": true
              }
            }
          ]
        }
      }
    }
  }'

Use the date filter to search based on the value of a Date-type custom attribute. This filter defines a date range using start_at, end_at, or both. Range boundaries are inclusive. Dates can be specified in RFC 3339 full-date or date-time format.

The following example uses the full-date (YYYY-MM-DD) format to search for any date in February 2022:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "square:4e70944b-fb56-452b-8e23-f0e06b856397",
              "filter": {
                "date": {
                  "start_at": "2022-02-01",
                  "end_at": "2022-02-28"
                }
              }
            }
          ]
        }
      }
    }
  }'

The following example uses the date-time format for the same search:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "square:4e70944b-fb56-452b-8e23-f0e06b856397",
              "filter": {
                "date": {
                  "start_at": "2022-02-01T00:00:00Z",
                  "end_at": "2022-02-28T23:59:59Z"
                }
              }
            }
          ]
        }
      }
    }
  }'

Use the email filter to search based on the value (case-insensitive) of an Email-type custom attribute. This filter can include exact or fuzzy, but not both.

For an exact match, provide the complete email address.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "secondaryEmail",
              "filter": {
                "exact": "j.doe@company.com"
              }
            }
          ]
        }
      }
    }
  }'

For a fuzzy match, provide a query expression containing one or more query tokens in any order to match against the email address. For example, doe or doe j matches j.doe@gmail.com and john@doe.com.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "secondaryEmail",
              "filter": {
                "fuzzy": "doe j"
              }
            }
          ]
        }
      }
    }
  }'

The Fuzzy search by email address section provides more information about how fuzzy matching works with email addresses.

Use the number filter to search based on the value of a Number-type custom attribute, which can be an integer or a decimal with up to five digits of precision. This filter defines a range using start_at, end_at, or both. Range boundaries are inclusive. The absolute value of range boundaries must not exceed (2^63-1)/10^5, or 92233720368547.

Provide string representations of decimals or integers (if your search parameters do not require decimal precision). The following example searches for any value from -28.5 to 40:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "square:d91576d3-07e7-45c7-b79b-29c4242bfcea",
              "filter": {
                "number": {
                  "start_at": "-28.5",
                  "end_at": "40"
                }
              }
            }
          ]
        }
      }
    }
  }'

Use the phone filter to search based on the value of a PhoneNumber-type custom attribute. This filter can include exact or fuzzy, but not both.

For an exact match, provide the complete phone number, including the leading + sign.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "sq0idp-BughoY39o1X-GPxSSUWc0A:EmergencyContactPhone",
              "filter": {
                "phone": {
                  "exact": "+16095551234"
                }
              }
            }
          ]
        }
      }
    }
  }'

For a fuzzy match, provide a query expression containing one or more query tokens in any order to match against the phone number. For example, 609 or 609 555 matches +16095551234 and +12155536090.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "sq0idp-BughoY39o1X-GPxSSUWc0A:EmergencyContactPhone",
              "filter": {
                "phone": {
                  "fuzzy": "609"
                }
              }
            }
          ]
        }
      }
    }
  }'

The Fuzzy search by phone number section provides more information about how fuzzy matching works with phone numbers.

Use the text filter to search based on the value (case-insensitive) of a String-type custom attribute. This filter can include exact or fuzzy, but not both.

For an exact match, provide the complete string. The following example searches for the customer profile that has the specified account number:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "AccountNumber",
              "filter": {
                "text": {
                  "exact": "10000902472323706458"
                }
              }
            }
          ]
        }
      }
    }
  }'

The following example searches for customer profiles whose favorite-drink custom attribute is Iced Mocha Latte:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "favorite-drink",
              "filter": {
                "text": {
                  "exact": "iced mocha latte"
                }
              }
            }
          ]
        }
      }
    }
  }'

For a fuzzy match, provide a query expression containing one or more query tokens in any order that contain complete words to match against the string. Square tokenizes the expression using a grammar-based tokenizer. For example, the expressions quick brown, brown quick, fox dog, and jumps all match "The quick brown fox jumps over the lazy dog". However, quick foxes and qui do not match.

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "favorite-drink",
              "filter": {
                "text": {
                  "fuzzy": "iced"
                }
              }
            }
          ]
        }
      }
    }
  }'

Use the selection filter to search based on the display name (case-sensitive) for a Selection-type custom attribute. This filter can contain any, all, or both. The none condition is not supported.

Provide the display name of each item that you want to search for. The following example searches for customer profiles whose interests custom attribute includes UUIDs that map to both science and culture:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "interests",
              "filter": {
                "selection": {
                  "all": [
                    "science",
                    "culture"
                  ]
                }
              }
            }
          ]
        }
      }
    }
  }'

The following example searches for customer profiles whose pet-type custom attribute includes a UUID that maps to any of the following values: lizard, snake, turtle, or iguana:

Search Customers
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
curl https://connect.squareup.com/v2/customers/search \
  -X POST \
  -H 'Square-Version: 2023-01-19' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "custom_attribute": {
          "filters": [
            {
              "key": "pet-type",
              "filter": {
                "selection": {
                  "any": [
                    "lizard",
                    "snake",
                    "turtle",
                    "iguana"
                  ]
                }
              }
            }
          ]
        }
      }
    }
  }'

To find the display names for the selection, you must retrieve the corresponding custom attribute definition and then check the schema.items.names field. You can use the following Customer Custom Attributes API endpoints to retrieve the definition:

The following is an excerpt of an example Selection-type definition. The schema.items.names field contains the display names and the schema.items.enum field contains Square-generated UUIDs that map to each name. These UUIDs are unique per seller.

When a Selection-type custom attribute is assigned to a customer profile, the custom attribute value is a list of one or more UUIDs that map to the item names.

If you need more assistance, contact Developer Support or ask for help in the Developer Forums.