Store Hugs Developers

Customers

The shop's customer accounts: find them, add them, and set the wholesale membership that prices their carts.

Reach them through admin.customers. Reading needs the customers:read scope, changing them customers:write.

List customers

admin.customers.list(query?: ListQuery & { search?: string; email?: string }): Promise<CursorPage<AdminCustomer>>

One page of the shop's customers, by words in the name, email or phone, or an exact email; or oldest change first with updatedSince. Read the next page with meta.nextCursor as cursor. Scope: customers:read.

Parameters

Parameter Type
query object The query fields below, by name.

Query fields

ParameterTypeDescription
searchstringAt most 200 characters.
emailstringAn exact email (case-insensitive). At most 255 characters.
limitintegerAt least 1. At most 100. Default 50.
cursorstringmeta.nextCursor (or the cursor in links.next) of the previous page. At most 1000 characters.
updatedSincestring (date-time)Records changed at or after this time (ISO 8601, any offset or Z), oldest change first, for incremental sync.

Returns

A CursorPage<AdminCustomer>:

FieldTypeDescription
linksobject
links.firstnull
links.lastnull
links.prevstring (uri) or null
links.nextstring (uri) or null
metaobject
meta.pathstring (uri)
meta.perPageinteger
meta.nextCursorstring or null
meta.prevCursorstring or null
dataarray of AdminCustomer
data[].idinteger
data[].namestring
data[].emailstring or null
data[].emailVerifiedboolean
data[].phonestring or null
data[].phoneVerifiedboolean
data[].wholesaleboolean
data[].wholesaleMembershipIdinteger or null
data[].createdAtstring (date-time) or null
data[].updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

const { data } = await admin.customers.list({ email: '[email protected]' });
const customer = data[0];

Iterate over every customer

admin.customers.all(query?: ListQuery & { search?: string; email?: string }): AsyncGenerator<AdminCustomer, void, undefined>

Every customer matching the query, one at a time, fetching the next page as you read. It takes the same query as list, without cursor. Scope: customers:read.

Returns

An async generator of AdminCustomer, each:

FieldTypeDescription
[].idinteger
[].namestring
[].emailstring or null
[].emailVerifiedboolean
[].phonestring or null
[].phoneVerifiedboolean
[].wholesaleboolean
[].wholesaleMembershipIdinteger or null
[].createdAtstring (date-time) or null
[].updatedAtstring (date-time) or null

Example

for await (const customer of admin.customers.all({
    updatedSince: lastSyncedAt,
})) {
    await crm.saveCustomer(customer);
}

Get a customer

admin.customers.get(id: number): Promise<AdminCustomer>

One customer by their id. Scope: customers:read.

Parameters

Parameter Type
id number The customer's id.

Returns

An AdminCustomer:

FieldTypeDescription
idinteger
namestring
emailstring or null
emailVerifiedboolean
phonestring or null
phoneVerifiedboolean
wholesaleboolean
wholesaleMembershipIdinteger or null
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
404not_found: the shop has no such record.
429Rate limited.

Create a customer

admin.customers.create(input: AdminCustomerInput, options?: RequestOptions): Promise<AdminCustomer>

A new customer, emailed at once to choose a password. The email, and the phone when given, must be unique in the shop. Scope: customers:write.

Parameters

Parameter Type
input object The customer's fields, below.
options RequestOptions idempotencyKey, signal and headers (see retries).

Request fields

FieldTypeDescription
name requiredstringAt most 255 characters.
email requiredstring (email)Unique in the shop. At most 255 characters.
phonestring or nullUnique in the shop. At most 50 characters.

Returns

The new AdminCustomer:

FieldTypeDescription
idinteger
namestring
emailstring or null
emailVerifiedboolean
phonestring or null
phoneVerifiedboolean
wholesaleboolean
wholesaleMembershipIdinteger or null
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
409idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

const customer = await admin.customers.create({
    name: 'Sara Ali',
    email: '[email protected]',
});

Set a wholesale membership

admin.customers.setMembership(id: number, wholesaleMembershipId: number | null, options?: UpdateOptions): Promise<AdminCustomer>

Puts the customer in one of the shop's wholesale memberships, or back to retail with null. Business plan (403 plan_required). Scope: customers:write.

Parameters

Parameter Type
id number The customer's id.
wholesaleMembershipId number | null The membership's id, or null for retail.
options UpdateOptions unmodifiedSince (the updatedAt you read; a newer customer is refused with 409 edit_conflict) and idempotencyKey.

Request fields

The SDK sends the membership id as wholesaleMembershipId:

FieldTypeDescription
wholesaleMembershipId requiredinteger or null
updatedAtstring (date-time) or nullThe record's updatedAt as you read it; a newer record gets 409 edit_conflict.

Returns

The changed AdminCustomer:

FieldTypeDescription
idinteger
namestring
emailstring or null
emailVerifiedboolean
phonestring or null
phoneVerifiedboolean
wholesaleboolean
wholesaleMembershipIdinteger or null
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
404not_found: the shop has no such record.
409edit_conflict (the record changed after If-Unmodified-Since or updatedAt), or idempotency_in_progress.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

const customer = await admin.customers.get(88);
await admin.customers.setMembership(88, 3, {
    unmodifiedSince: customer.updatedAt ?? undefined,
});