Storeware Docs
REST

Customers

The shop’s customers and what is kept about them.

List customers

GET /api/v1/stores/{storeId}/customers

A page of customers, newest first unless sort says otherwise, each with what they have bought. Archived customers are left out unless archived asks for them. Each narrowing takes some away, and a value that cannot be read is ignored. meta.breakdown counts every customer not archived; send breakdown=0 to leave it out.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
searchquerystringWords in the email, first name or last name.
sortquerystringOne of created_desc, created_asc, name_asc, name_desc.
accountTypequerystringOne of guest, registered, business.
acceptsMarketingquerystring1 for those who agreed to be emailed, 0 for those who did not. One of 0, 1.
archivedquerystring1 lists archived customers among the rest, only lists the archive alone. One of 1, only.
tagsquerystringComma separated: carrying any of these, up to ten.
ordersquerystringnone for those who never ordered, or a number: at least that many orders.
spentqueryintegerHave spent at least this, in minor units, after refunds. At least 1.
recentqueryintegerHave ordered within this many days. At least 1.
quietqueryintegerHave ordered, and not within this many days. At least 1.
countryquerystringTwo letters: they live there or have had an order sent there.
boughtquerystring (uuid)Have bought this product.
breakdownquerystring0 leaves meta.breakdown out. One of 0.
limitqueryintegerHow many to return, up to 250. Fifty when not given. From 1 to 250.
offsetqueryintegerHow many to skip, for the next page. At least 0.

Answers 200

FieldTypeDescription
dataarray of CustomerSummary
metaobject
meta.totalintegerHow many match, across every page.
meta.breakdownobjectEvery customer not archived, whatever the page asks. Left out with breakdown=0.
meta.breakdown.totalinteger
meta.breakdown.registeredinteger
meta.breakdown.withOrdersintegerHave at least one order not cancelled.
meta.breakdown.acceptsMarketinginteger
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers" \
  -H "Authorization: Bearer $TOKEN"

Create a customer

POST /api/v1/stores/{storeId}/customers

Adds somebody who has not been through the checkout, as a guest. Marketing consent cannot be set here: a customer added this way starts without it. An email another customer of the shop holds, an archived one included, is a 409. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.

Body

FieldTypeRequiredDescription
emailstring (email)YesUp to 254 characters.
firstNamestring or nullNoUp to 120 characters.
lastNamestring or nullNoUp to 120 characters.
phonestring or nullNoUp to 40 characters.
defaultAddressobject or nullNo
defaultAddress.namestring or nullNoUp to 200 characters.
defaultAddress.line_onestringYes1 to 200 characters.
defaultAddress.line_twostring or nullNoUp to 200 characters.
defaultAddress.citystringYes1 to 120 characters.
defaultAddress.statestring or nullNoUp to 120 characters.
defaultAddress.countrystringYesMatches ^[A-Z]{2}$.
defaultAddress.postal_codestringYes1 to 32 characters.
tagsarray of stringNoUp to 100 items.
taxExemptbooleanNo
taxExemptionReferencestring or nullNoUp to 200 characters.
acceptsMarketinganyNo

Answers 201

FieldTypeDescription
dataCustomer
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

List the tags and countries customers have

GET /api/v1/stores/{storeId}/customers/facets

The tags the shop’s customers carry and the countries they live in or have had orders sent to, the commonest first, counted over customers not archived. For offering the values tags and country can narrow listCustomers by.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.

Answers 200

FieldTypeDescription
dataobject
data.tagsarray of stringUp to 100.
data.countriesarray of stringTwo letter codes, up to 250.
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/facets" \
  -H "Authorization: Bearer $TOKEN"

Get a customer

GET /api/v1/stores/{storeId}/customers/{customerId}

The customer, with their 100 most recent orders in meta.orders.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataCustomerSummary
metaobject
meta.ordersarray of objectNewest first, up to 100.
meta.orders[].idstring (uuid)
meta.orders[].storeIdstring (uuid)
meta.orders[].sessionIdstring (uuid) or null
meta.orders[].customerIdstring (uuid) or null
meta.orders[].buyerProvenboolean
meta.orders[].orderNumberstring
meta.orders[].customerNotestring or null
meta.orders[].statusstringOne of created, confirmed, manual_review, processing, shipped, delivered, canceled.
meta.orders[].currencystring
meta.orders[].localestring or null
meta.orders[].buyerEmailstring
meta.orders[].buyerFirstNamestring or null
meta.orders[].buyerLastNamestring or null
meta.orders[].buyerPhonestring or null
meta.orders[].shippingAddressany or null
meta.orders[].billingAddressany or null
meta.orders[].fulfillmentOptionany or null
meta.orders[].subtotalAmountnumber
meta.orders[].discountAmountnumber
meta.orders[].fulfillmentAmountnumber
meta.orders[].taxAmountnumber
meta.orders[].fulfillmentTaxAmountnumber
meta.orders[].fulfillmentDiscountAmountnumber
meta.orders[].companyIdstring (uuid) or null
meta.orders[].priceListIdstring (uuid) or null
meta.orders[].paymentTermsNetDaysnumber or null
meta.orders[].dueAtstring (date-time) or null
meta.orders[].purchaseOrderNumberstring or null
meta.orders[].totalAmountnumber
meta.orders[].refundedAmountnumber
meta.orders[].changeAmountnumber
meta.orders[].creditAppliedAmountnumber
meta.orders[].taxCalculationIdstring or null
meta.orders[].taxTransactionIdstring or null
meta.orders[].discountIdstring (uuid) or null
meta.orders[].discountCodestring or null
meta.orders[].tagsarray of string
meta.orders[].heldAtstring (date-time) or null
meta.orders[].heldBystring or null
meta.orders[].holdReasonstring or null
meta.orders[].originstringOne of storefront, agent, admin, plugin, imported, subscription.
meta.orders[].agentIdstring or null
meta.orders[].conversationIdstring (uuid) or null
meta.orders[].referralIdstring (uuid) or null
meta.orders[].adLinkIdstring (uuid) or null
meta.orders[].placedAtstring (date-time)
meta.orders[].canceledAtstring (date-time) or null
meta.orders[].subscriptionIdstring (uuid) or null
meta.orders[].createdAtstring (date-time)
meta.orders[].updatedAtstring (date-time)
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID" \
  -H "Authorization: Bearer $TOKEN"

Update a customer

PATCH /api/v1/stores/{storeId}/customers/{customerId}

Changes only the fields sent; a null empties one, and an address is replaced whole. Marketing consent cannot be set here. Changing the email to one another customer holds is a 409, and any new email counts as unverified until the customer signs in with it. note is the merchant’s own and is never shown to the customer. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Body

FieldTypeRequiredDescription
emailstring (email)NoUp to 254 characters.
firstNamestring or nullNoUp to 120 characters.
lastNamestring or nullNoUp to 120 characters.
phonestring or nullNoUp to 40 characters.
defaultAddressobject or nullNo
defaultAddress.namestring or nullNoUp to 200 characters.
defaultAddress.line_onestringYes1 to 200 characters.
defaultAddress.line_twostring or nullNoUp to 200 characters.
defaultAddress.citystringYes1 to 120 characters.
defaultAddress.statestring or nullNoUp to 120 characters.
defaultAddress.countrystringYesMatches ^[A-Z]{2}$.
defaultAddress.postal_codestringYes1 to 32 characters.
tagsarray of stringNoUp to 100 items.
taxExemptbooleanNo
taxExemptionReferencestring or nullNoUp to 200 characters.
acceptsMarketinganyNo
notestring or nullNoUp to 5,000 characters.

Answers 200

FieldTypeDescription
dataCustomer
curl -X PATCH "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

List a customer’s saved addresses

GET /api/v1/stores/{storeId}/customers/{customerId}/addresses

The addresses a customer has besides their default, oldest first, up to 50. The default is defaultAddress on the customer and is not repeated here.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataarray of CustomerSavedAddress
metaobject
meta.totalintegerHow many match, across every page.
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/addresses" \
  -H "Authorization: Bearer $TOKEN"

Save an address for a customer

POST /api/v1/stores/{storeId}/customers/{customerId}/addresses

Saves another address, whole. One the customer already has, their default included, is a 409, and so is one past the 50 a customer can keep. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Body

FieldTypeRequiredDescription
addressobjectYes
address.namestring or nullNoUp to 200 characters.
address.line_onestringYes1 to 200 characters.
address.line_twostring or nullNoUp to 200 characters.
address.citystringYes1 to 120 characters.
address.statestring or nullNoUp to 120 characters.
address.countrystringYesMatches ^[A-Z]{2}$.
address.postal_codestringYes1 to 32 characters.

Answers 201

FieldTypeDescription
dataCustomerSavedAddress
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/addresses" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

Correct a customer’s saved address

PATCH /api/v1/stores/{storeId}/customers/{customerId}/addresses/{addressId}

Replaces the address whole. Sending what is already there changes nothing. Lines that match another address the customer has are a 409. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.
addressIdpathstringThe address.

Body

FieldTypeRequiredDescription
addressobjectYes
address.namestring or nullNoUp to 200 characters.
address.line_onestringYes1 to 200 characters.
address.line_twostring or nullNoUp to 200 characters.
address.citystringYes1 to 120 characters.
address.statestring or nullNoUp to 120 characters.
address.countrystringYesMatches ^[A-Z]{2}$.
address.postal_codestringYes1 to 32 characters.

Answers 200

FieldTypeDescription
dataCustomerSavedAddress
curl -X PATCH "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/addresses/$ADDRESS_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

Remove a customer’s saved address

DELETE /api/v1/stores/{storeId}/customers/{customerId}/addresses/{addressId}

Removes one saved address. The default is not one and stays. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.
addressIdpathstringThe address.

Answers 200

FieldTypeDescription
dataobject
data.removedtrue
curl -X DELETE "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/addresses/$ADDRESS_ID" \
  -H "Authorization: Bearer $TOKEN"

Make a saved address the default

POST /api/v1/stores/{storeId}/customers/{customerId}/addresses/{addressId}/default

Puts this address on the customer as defaultAddress, and saves the old default in its place, so no address is lost. Send an Idempotency-Key header to make a retry safe.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.
addressIdpathstringThe address.

Answers 200

FieldTypeDescription
dataobject
data.madeDefaulttrue
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/addresses/$ADDRESS_ID/default" \
  -H "Authorization: Bearer $TOKEN"

Archive a customer

POST /api/v1/stores/{storeId}/customers/{customerId}/archive

Puts the customer away without deleting anything: their orders, credit and email stay theirs. They leave the lists and totals, and are signed out of their account on the shop until unarchived. Archiving one already archived changes nothing.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataCustomer
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/archive" \
  -H "Authorization: Bearer $TOKEN"

Unarchive a customer

POST /api/v1/stores/{storeId}/customers/{customerId}/unarchive

Brings the customer back as they were. One not archived is answered as it is.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataCustomer
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/unarchive" \
  -H "Authorization: Bearer $TOKEN"

DELETE /api/v1/stores/{storeId}/customers/{customerId}/marketing-consent

Records that the customer asked not to be emailed, and sends customer.consent_withdrawn.v1 with their email. Consent can only be withdrawn here, never given. A customer already off the list is answered as they are.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataCustomer
curl -X DELETE "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/marketing-consent" \
  -H "Authorization: Bearer $TOKEN"

List a customer’s metafields

GET /api/v1/stores/{storeId}/customers/{customerId}/metafields

Every metafield value set on a customer, each with its definition.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataarray of object
data[].definitionIdstring (uuid)
data[].namespacestring
data[].keystring
data[].labelstringThe merchant’s name for the field.
data[].typestringsingle_line_text, multi_line_text, integer, decimal, boolean, date, url and the other definition types.
data[].isListboolean
data[].storefrontVisibleboolean
data[].searchFacetboolean
data[].positioninteger
data[].valueanyThe value, or a list of values when isList.
data[].displayValuestringThe value as one line of text, lists joined.
data[].sourcestringWho set it: the merchant, an import, or an app’s slug.
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/metafields" \
  -H "Authorization: Bearer $TOKEN"

Set a customer’s metafields

PUT /api/v1/stores/{storeId}/customers/{customerId}/metafields

Sets up to 25 values in one call. A null value clears its field; keys not named are left alone. An app may set only the fields its manifest declares.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Body

FieldTypeRequiredDescription
metafieldsarray of objectYesUp to 25 items. At least 1 item.
metafields[].namespacestringNoDefault custom.
metafields[].keystringYes
metafields[].valueanyNo

Answers 200

FieldTypeDescription
dataarray of object
data[].definitionIdstring (uuid)
data[].namespacestring
data[].keystring
data[].labelstringThe merchant’s name for the field.
data[].typestringsingle_line_text, multi_line_text, integer, decimal, boolean, date, url and the other definition types.
data[].isListboolean
data[].storefrontVisibleboolean
data[].searchFacetboolean
data[].positioninteger
data[].valueanyThe value, or a list of values when isList.
data[].displayValuestringThe value as one line of text, lists joined.
data[].sourcestringWho set it: the merchant, an import, or an app’s slug.
curl -X PUT "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/metafields" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

List the trade accounts a customer buys for

GET /api/v1/stores/{storeId}/customers/{customerId}/companies

The companies the customer buys on behalf of, by name. At most one today.

Needs companies:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataarray of object
data[].idstring (uuid)
data[].storeIdstring (uuid)
data[].namestring
data[].slugstring
data[].statusstringOnly an active account gets its agreed prices. One of pending, active, archived.
data[].taxExemptboolean
data[].taxExemptionReferencestring or null
data[].paymentTermsNetDaysnumber or nullDays it has to pay an invoice. Null pays at the till; 0 is due on receipt.
data[].creditLimitAmountnumber or nullThe most it may owe at once, in minor units of creditCurrency. Null is no limit.
data[].creditCurrencystring or null
data[].priceListIdstring (uuid) or null
data[].notestring or nullThe merchant’s own note. Never shown to the buyer.
data[].createdAtstring (date-time)
data[].updatedAtstring (date-time)
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/companies" \
  -H "Authorization: Bearer $TOKEN"

Get a customer’s store credit

GET /api/v1/stores/{storeId}/customers/{customerId}/store-credit

What the customer holds in each currency, and the entries behind it, newest first. orders:read will do in place of customers:read.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.
limitqueryintegerHow many entries to return, up to 200. Fifty when not given. From 1 to 200.

Answers 200

FieldTypeDescription
dataobject
data.balancesarray of objectOne for each currency they hold credit in.
data.balances[].accountIdstring (uuid)
data.balances[].customerIdstring (uuid)
data.balances[].currencystring
data.balances[].balanceAmountintegerIn minor units.
data.entriesarray of objectAcross every currency, newest first.
data.entries[].idstring (uuid)
data.entries[].storeIdstring (uuid)
data.entries[].accountIdstring (uuid)
data.entries[].deltanumberIn minor units. Positive puts credit on, negative spends it.
data.entries[].currencystringCredit is held per currency.
data.entries[].balanceAfternumberThe balance after this entry, in minor units.
data.entries[].reasonstringOne of return_refund, goodwill, order_payment, order_canceled, manual_adjustment, exchange_difference, gift_card.
data.entries[].notestring or null
data.entries[].orderIdstring (uuid) or null
data.entries[].returnIdstring (uuid) or null
data.entries[].adjustmentIdstring (uuid) or null
data.entries[].giftCardIdstring (uuid) or null
data.entries[].sessionIdstring (uuid) or null
data.entries[].idempotencyKeystring or null
data.entries[].actorTypestring or null
data.entries[].actorIdstring or null
data.entries[].createdAtstring (date-time)
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/store-credit" \
  -H "Authorization: Bearer $TOKEN"

Give a customer store credit

POST /api/v1/stores/{storeId}/customers/{customerId}/store-credit

Puts credit on the customer’s account in one currency, for them to spend at checkout. amount is in minor units. It needs orders:write, as a refund does. An idempotencyKey already used is refused, so a retry cannot credit twice.

Needs orders:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Body

FieldTypeRequiredDescription
amountintegerYes
currencystringYes3 to 3 characters.
reasonstringNoOne of return_refund, goodwill, order_payment, order_canceled, manual_adjustment, exchange_difference, gift_card. Default goodwill.
notestringNoUp to 500 characters.
orderIdstring (uuid)No
idempotencyKeystringNoUp to 200 characters.

Answers 201

FieldTypeDescription
dataobject
data.idstring (uuid)
data.storeIdstring (uuid)
data.accountIdstring (uuid)
data.deltanumberIn minor units. Positive puts credit on, negative spends it.
data.currencystringCredit is held per currency.
data.balanceAfternumberThe balance after this entry, in minor units.
data.reasonstringOne of return_refund, goodwill, order_payment, order_canceled, manual_adjustment, exchange_difference, gift_card.
data.notestring or null
data.orderIdstring (uuid) or null
data.returnIdstring (uuid) or null
data.adjustmentIdstring (uuid) or null
data.giftCardIdstring (uuid) or null
data.sessionIdstring (uuid) or null
data.idempotencyKeystring or null
data.actorTypestring or null
data.actorIdstring or null
data.createdAtstring (date-time)
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/store-credit" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

Get what the shop remembers about a customer

GET /api/v1/stores/{storeId}/customers/{customerId}/memory

What the customer told the shop they want while shopping signed in (a budget, requirements, context), which the shop keeps to narrow and rank what it shows them.

Needs customers:read.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Answers 200

FieldTypeDescription
dataobject or nullNull when the shop keeps nothing about them.
data.profileobject
data.profile.maxPricenumber or nullThe most they said they would pay, in whole units of the currency, not minor units.
data.profile.minPricenumber or nullThe least, in the same units.
data.profile.requiredAttributesarray of objectWhat they said it must be, such as a colour or a size.
data.profile.requiredAttributes[].keystring
data.profile.requiredAttributes[].valuestring
data.profile.contextarray of stringWho it is for, the occasion, the conditions. It ranks what they see and never hides anything.
data.confirmedAtstring (date-time)When they last said any of it.
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/memory" \
  -H "Authorization: Bearer $TOKEN"

Make the shop forget what a customer told it

POST /api/v1/stores/{storeId}/customers/{customerId}/memory

Removes all of it, or one part. There is no default: a body that names nothing is a 400. Answers with what remains.

Needs customers:write.

Parameters

ParameterInTypeDescription
storeIdpathstringThe shop.
customerIdpathstringThe customer.

Body

FieldTypeRequiredDescription
forgetstringYesWhat to forget. attribute forgets one requirement, named by key. One of all, budget, context, attribute.
keystringNoWith attribute: the requirement’s key.

Answers 200

FieldTypeDescription
dataobject or nullNull when the shop keeps nothing about them.
data.profileobject
data.profile.maxPricenumber or nullThe most they said they would pay, in whole units of the currency, not minor units.
data.profile.minPricenumber or nullThe least, in the same units.
data.profile.requiredAttributesarray of objectWhat they said it must be, such as a colour or a size.
data.profile.requiredAttributes[].keystring
data.profile.requiredAttributes[].valuestring
data.profile.contextarray of stringWho it is for, the occasion, the conditions. It ranks what they see and never hides anything.
data.confirmedAtstring (date-time)When they last said any of it.
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/customers/$CUSTOMER_ID/memory" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json

On this page