Order Search

The Order Search feature is intended for merchants to perform searches on a large number of Orders in a Project.

Order Search is available only in the Google Cloud and AWS Regions.

The retention period for Orders returned by this API is 3 months. This feature is not intended for searching through a customer's order history in a storefront application. The Order Search API does not return the resource data of the matching Orders. Instead, it returns a list of Order IDs, which can then be used to fetch the Orders by their ID.

Since the response also contains the version of the matching Order, it allows you to:

  • maintain a cache of Orders,
  • compare version numbers to detect outdated Orders,
  • detect if the search index for an Order is out of date and react accordingly (for example display a warning, or initiate an update of the Order search index).

Activation of the API

The Order Search API is not active for the Project by default. If the API is deactivated for your Project, the Search Orders endpoint returns a 404 Not Found error.

To activate the API for your Projects, please choose one of the following options:

Once the Project setting has been changed, the indexing of all Orders existing in the Project will start and the Search Orders endpoint will become fully functional soon after.

Automatic deactivation

The Order Search API is automatically deactivated for a Project if there have been no calls to the Search Orders endpoint in the last 30 days. The API can be reactivated again using any of the options listed in Activation of the API.

Representations

OrderSearchRequest

query

The Order search query.

sort
Array of OrderSearchSorting

Controls how results to your query are sorted. If not provided, the results are sorted by relevance in descending order.

limit
Int

The maximum number of search results to be returned on one page.

Default: 10Maximum: 100
offset
Int

The number of search results to be skipped in the response for pagination.

Default: 0Maximum: 10 000
Example: json
{
"query": {
"and": [
{
"fullText": {
"field": "customLineItems.name",
"language": "en",
"value": "banana"
}
},
{
"filter": [
{
"exact": {
"field": "store.name",
"language": "en",
"value": "fruit_store"
}
}
]
}
]
},
"sort": [
{
"field": "customLineItems.name",
"language": "en",
"order": "desc"
}
],
"limit": 50,
"offset": 0
}

OrderPagedSearchResponse

total
Int

Total number of results matching the query.

offset
Int

Number of elements skipped.

limit
Int

Number of results requested.

Maximum: 100
hits
Array of Hit

Actual results.

Hit

id
String

Unique identifier of the Order.

version
Int

Current version of the Order.

relevance
Float

The higher the value is, the more relevant the hit is for the search request.

Maximum: 1

Search Orders

If this endpoint responds with 404 Not Found error, the feature has been deactivated due to inactivity and must be reactivated before API requests will succeed.

Use the Check if Order Search index exists endpoint to see if there is an index available.

POST
https://api.{region}.commercetools.com/{projectKey}/orders/search
OAuth 2.0 Scopes:
view_orders:{projectKey}
Path parameters:
region
String

Region in which the Project is hosted.

projectKey
String

key of the Project.

Request Body:OrderSearchRequestasapplication/json
Response:
200OrderPagedSearchResponseasapplication/json
200 Response Example: OrderPagedSearchResponsejson
{
"total": 3,
"offset": 0,
"limit": 50,
"hits": [
{
"id": "c2d430e8-1ccf-44c8-8976-36763b572f3e",
"version": 12,
"relevance": 0.9871
},
{
"id": "ee8e3533-00d2-43c2-a2f4-57b1eee0f5b4",
"version": 2,
"relevance": 0.735654
},
{
"id": "9a9e129c-2ed1-436d-90d9-af60d83490ed",
"version": 44,
"relevance": 0.42415
}
]
}

Check if Order Search index exists

HEAD
https://api.{region}.commercetools.com/{projectKey}/orders/search

Checks whether a search index for the Project's Orders exists. Returns a 200 OK status if the index exists or a 404 Not Found error otherwise.

OAuth 2.0 Scopes:
view_orders:{projectKey}
Path parameters:
region
String

Region in which the Project is hosted.

projectKey
String

key of the Project.

Response:
200

The index exists and the Search Orders endpoint can be used.

Request Example:cURL
curl --head https://api.{region}.commercetools.com/{projectKey}/orders/search -i \
--header 'Authorization: Bearer ${BEARER_TOKEN}'

On the GraphQL endpoint you can use following query:

query FetchIndicesExists {
ordersIndicesExist {
searchableIndexExists
newInProgress
}
}

The query response contains the following fields indicating the status of the search index:

  • searchableIndexExists - the index exists and Orders can be searched.
  • newInProgress - the index is being created by a job. Use the reIndexAllOrders mutation to get the job ID.

Find below an example for a FetchIndicesExists query to be executed as cURL command:

$ curl -X POST https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphql \
-H "Content-Type:application/json" \
-H "Authorization:Bearer ..." \
-d '{"query": "{ ordersIndicesExist { searchableIndexExists } }" }'

Searchable Order fields

The following list contains the Order fields that are supported in query expressions.

Some fields containing data of referenced resources are not updated automatically. Their values are kept in the their original state, even if the referenced resource was changed. You need to initiate an update to get the most recent values for those fields.

Number and date fields

Use the following fields in exact, exists, and range query expressions. Data type indicates the type of field for the field.

Standard fieldData typeQuery for Orders
completedAtdateTimecompleted at a certain date and time.
createdAtdatetimecreated at a certain date and time.
lastModifiedAtdateTimelast modified at any of its fields at a certain date and time.
versionlongwith a certain version of the resource.
customLineItems.state.quantitylongwith Custom Line Item's ItemState of a certain quantity.
You may need to initiate an update to get the latest state of this field.
lineItems.state.quantitylongwith Line Item's ItemState of a certain quantity.
returnInfo.items.createdAtdateTimewith ReturnItems created at a certain date and time.
returnInfo.items.lastModifiedAtdateTimewith ReturnItems last modified at a certain date and time.
returnInfo.returnDatedateTimewith ReturnInfo of a certain date and time.
totalPrice.centAmountlongwith a total price of a certain amount.

Phone fields

Use the following text type fields in exact, fullText, prefix, and exists query expressions. On these fields all non numeric characters are ignored in search requests. For example, a query of type fullText for (783) 627-3740 will also match (783) 6273740. The same applies to prefix queries. Special characters are only taken into account when performing queries of type exact.

Standard fieldQuery for Orders with
billingAddress.mobilea billing address of a certain mobile number.
billingAddress.phonea billing address of a certain phone number.
itemShippingAddresses.mobilea Line Item shipping address of a certain mobile number.
itemShippingAddresses.phonea Line Item shipping address of a certain phone number.
shippingAddress.mobilea shipping address of a certain mobile number.
shippingAddress.phonea shipping address of a certain phone number.

Text fields

Use the following text type fields in exact, fullText, prefix, wildcard, and exists query expressions.

Standard field on OrderQuery for Orders
allwith a certain string in the combination of all fields.
countrywith a certain country.
createdBy.clientIdcreated by an API Client with a certain client ID.
customerEmailwith a certain Customer email address.
customerGroup.keyfrom Customers of a certain Customer Group specified by its key.
You may need to initiate an update to get the latest state of this field.
customerGroup.namefrom Customers of a certain Customer Group specified by its name.
You may need to initiate an update to get the latest state of this field.
lastModifiedBy.clientIdlast modified by an API Client with a certain client ID.
orderStatewith a certain OrderState.
paymentStatewith a certain PaymentState.
shipmentStatewith a certain ShipmentState.
state.namewith a State of a certain name for the language specified in the query expression..
You may need to initiate an update to get the latest state of this field.
store.namewith a Store of a certain name for the language specified in the query expression..
You may need to initiate an update to get the latest state of this field.
Standard field on Billing AddressQuery for Orders with a billing address of
billingAddress.citya certain city.
billingAddress.companya certain company.
billingAddress.countrya certain country.
billingAddress.firstNamea certain first name.
billingAddress.lastNamea certain last name.
billingAddress.postalCodea certain post code.
Standard field on Item Shipping AddressQuery for Orders with a Line Item Shipping address of
itemShippingAddresses.citya certain city.
itemShippingAddresses.companya certain company.
itemShippingAddresses.countrya certain country.
itemShippingAddresses.firstNamea certain first name.
itemShippingAddresses.lastNamea certain last name.
itemShippingAddresses.postalCodea certain post code.
Standard field on Shipping AddressQuery for Orders with a Shipping address of
shippingAddress.citya certain city.
shippingAddress.companya certain company.
shippingAddress.countrya certain country.
shippingAddress.firstNamea certain first name.
shippingAddress.lastNamea certain last name.
shippingAddress.postalCodea certain post code.
Standard field on Line Items and Custom Line ItemsQuery for Orders with
lineItems.productIdLine Items of a certain Product with a specified id.
lineItems.variant.skuLine Items of a certain Product Variant with a specified sku.
lineItems.nameLine Items of a certain Product name for the language specified in the query expression..
lineItems.state.state.nameLine Items of a certain State name for the language specified in the query expression..
You may need to initiate an update to get the latest state of this field.
customLineItems.nameCustom Line Items of a certain name for the language specified in the query expression..
You may need to initiate an update to get the latest state of this field.
customLineItems.state.state.nameCustom Line Items of a certain State name for the language specified in the query expression..
You may need to initiate an update to get the latest state of this field.
Standard field on Payment, Return, or Shipping InfoQuery for Orders with
paymentInfo.payments.paymentMethodInfo.methoda certain payment method.
You may need to initiate an update to get the latest state of this field.
returnInfo.items.shipmentStatereturn items in a certain shipment state.
returnInfo.items.paymentStatereturn items with a certain payment state.
shippingInfo.shippingMethodNamea certain Shipping Method.

Keyword fields

Use the following keyword type fields, containing unique IDs or keys, in exact, prefix, wildcard, and exists query expressions. To query for multiple values of the same field or for several fields in the same request, combine the query expressions with a compound expression.

Standard field on OrderQuery for
idan Order with a specific id.
orderNumberan Order with a specific orderNumber.
createdBy.anonymousIdOrders created by anonymous session with a specific ID.
createdBy.externalUserIdOrders created by a Customer using external OAuth with a specific user ID.
lastModifiedBy.anonymousIdOrders last modified by anonymous session with a specific ID.
lastModifiedBy.externalUserIdOrders last modified by a Customer using external OAuth with a specific user ID.
originOrders with a specific origin.
customerGroup.idOrders from Customers of a certain Customer Group specified by its id.
customLineItems.state.state.keyCustom Line Items with a certain State specified by its key.
You may need to initiate an update to get the latest state of this field.
lineItems.state.state.keyLine Items with a certain State specified by its key.
You may need to initiate an update to get the latest state of this field.
paymentInfo.payments.interfaceIda Payment of a certain inferfaceId.
You may need to initiate an update to get the latest state of this field.
paymentInfo.payments.transactions.ida Payment Transaction of a certain id.
You may need to initiate an update to get the latest state of this field.
paymentInfo.payments.transactions.interactionIda Payment Transaction of a certain inferactionId.
You may need to initiate an update to get the latest state of this field.
returnInfo.returnTrackingIda certain returnTrackingId on the ReturnInfo.
You may need to initiate an update to get the latest state of this field.
shippingInfo.deliveries.parcels.trackingData.trackingIda certain trackingId on a Parcel's TrackingData.
You may need to initiate an update to get the latest state of this field.
state.keyOrders with a certain State specified by its key.
You may need to initiate an update to get the latest state of this field.
store.keyOrders with a certain Store specified by its key.
You may need to initiate an update to get the latest state of this field.
totalPrice.currencyCodeOrders with a total price of a certain CurrencyCode.

Custom Fields

In addition to the standard fields on an Order, you can also search for its Custom Fields, if any.

Custom Field on Order, Payment, and TransactionQuery for Orders
custom.<field-name>with a Custom Field of a specific name.
paymentInfo.payments.custom.<field-name>with Payments with a Custom Field of a specific name.
You may need to initiate an update to get the latest state of this field.
paymentInfo.payments.transactions.custom.<field-name>with Payment Transactions with a Custom Field of a specific name.
You may need to initiate an update to get the latest state of this field.

To determine the data type of the Custom Field, you must provide the customType in query expressions.

CustomType

Possible values for the customType property on query expressions indicating the data type of the field.

BooleanType

For CustomFieldBooleanType Custom Fields.

StringType

For CustomFieldStringType Custom Fields.

LocalizedStringType

For CustomFieldLocalizedStringType Custom Fields.

EnumType

For CustomFieldEnumType Custom Fields.

LocalizedEnumType

For CustomFieldLocalizedEnumType Custom Fields.

NumberType

For CustomFieldNumberType Custom Fields.

DateType

For CustomFieldDateType Custom Fields.

TimeType

For CustomFieldTimeType Custom Fields.

DateTimeType

For CustomFieldDateTimeType Custom Fields.

SetType.StringType

For CustomFieldSetType of StringType Custom Fields.

SetType.LocalizedStringType

For CustomFieldSetType of LocalizedStringType Custom Fields.

SetType.EnumType

For CustomFieldSetType of EnumType Custom Fields.

SetType.LocalizedEnumType

For CustomFieldSetType of LocalizedEnumType Custom Fields.

SetType.NumberType

For CustomFieldSetType of NumberType Custom Fields.

SetType.DateType

For CustomFieldSetType of DateType Custom Fields.

SetType.TimeType

For CustomFieldSetType of TimeType Custom Fields.

SetType.DateTimeType

For CustomFieldSetType of DateTimeType Custom Fields.

Query expression supported for which CustomType

A checkmark indicates which query expression you can use for which CustomType of field. You can apply the same expressions for the SetType of the CustomType as for the individual CustomType itself.

CustomTypeexactfullTextprefixrangewildcardexists
BooleanType
NumberType
StringType, EnumType, DateType, TimeType, DateTimeType
LocalizedStringType, LocalizedEnumType

Examples

An exact query on a StringType Custom Field.

{
"query": {
"exact": {
"field": "custom.myOrderField",
"value": "special order",
"customType": "StringType"
}
}
}

An exists query on a SetType of DateType Custom Field searching through all values for the Custom Field:

{
"query": {
"exists": {
"field": "custom.myDateField",
"value": "2021-05-10",
"customType": "SetType.DateType"
}
}
}

Order Search Query

The query expressions to be used for the query field on OrderSearchRequest, as well as for the Advanced Order Search in the Merchant Center, are documented for multiple Search APIs on the Search query language page. Search query language terms specific to Order Search are documented on this page.

Query expressions

The field in query expressions can have any of the searchable Order fields, like orderNumber, createdAt, country including fields of nested objects like LineItems (lineItems.productId) or ShippingMethods (shippingAddress.firstName).

For Order Search query expressions with Custom Fields, the customType field must be used instead of the fieldType field that is documented for the generic search query language.

Compound expressions

For compound expressions, the following restriction applies to Order Search:

A compound expression can only be used one time on the same level of composition.
For example, this composition of two and expressions is not supported: Z = (A and B and C),
using only one and expression, like: X = (A and B), is allowed.
Using a different compound expression is allowed too, like for: Y = (A and B or C).
Z can still be specified by (X and C) since X is a compound expression on a different level then.

Example queries

fullText

A fulltext query for Orders that have "yellow car" as the English name for any Custom Line Item in the Order.

{
"query": {
"fullText": {
"field": "customLineItems.name",
"language": "en",
"value": "yellow car",
"mustMatch": "any"
}
}
}

exact

An exact query for Orders that have the SKU "chiquita_yellow_123" in any of the Line Items in the Order. The case of the SKU is ignored.

{
"query": {
"exact": {
"field": "lineItems.variant.sku",
"value": "chiquita_yellow_123",
"caseInsensitive": true
}
}
}

prefix

A prefix query for Orders with customer emails starting with "commercetoo". The case of the email address is ignored.

{
"query": {
"prefix": {
"field": "customerEmail",
"value": "commerceto",
"caseInsensitive": true
}
}
}

range

A range query for Orders last modified between two specific dates:

{
"query": {
"range": {
"field": "lastModifiedAt",
"gte": "2018-08-25T12:00:00.000Z",
"lte": "2018-08-26T12:00:00.000Z"
}
}
}

wildcard

A wildcard query for Orders with customer emails that start with "ab" and may or may not contain any additional characters.

{
"query": {
"wildcard": {
"field": "customerEmail",
"value": "ab*@commercetools.com"
}
}
}

A wildcard query for Orders with customer emails that start with "ab" and have exactly one additional character after that. Case is ignored.

{
"query": {
"wildcard": {
"field": "customerEmail",
"value": "ab?@commercetools.com",
"caseInsensitive": true
}
}
}

The similar wildcard query as before, but now with another wildcard in the same value. The email domain can be any as long as it ends with ".com".

{
"query": {
"wildcard": {
"field": "customerEmail",
"value": "ab?@*.com",
"caseInsensitive": true
}
}
}

exists

An exists query for Orders that have the field customerEmail set:

{
"query": {
"exists": {
"field": "customerEmail"
}
}
}

Compound expression AND

Example of a query with compound expression finding orders with a specific price:

{
"query": {
"and": [
{
"exact": {
"field": "totalPrice.currencyCode",
"value": "EUR"
}
},
{
"exact": {
"field": "totalPrice.centAmount",
"value": 2222
}
}
]
}
}

Compound expression OR with boost

Orders that have butter in the lineItems.name field are scored as more relevant than those that have butter in their customLineItems.name field.

{
"query": {
"or": [
{
"fullText": {
"field": "lineItems.name",
"language": "en",
"value": "butter",
"boost": 2
}
},
{
"fullText": {
"field": "customLineItems.name",
"language": "en",
"value": "butter"
}
}
]
}
}

Sorting

Sorting allows you to control how the results of your search query are sorted. If no sort is specified, the results are sorted by relevance in descending order. For more information about sorting the Order Search result, see the search query language documentation.

Example:

The following expression sorts the results ascending by the English Line Item name, but filtered on a specific Product ID:

{
"sort": [
{
"field": "lineItems.name",
"language": "en",
"order": "asc",
"filter": {
"exact": {
"field": "lineItems.productId",
"value": "4054a159-7f3e-4fe9-a30c-8db80ca7d665"
}
}
}
]
}

Note that you can only filter on the same parent field you sort by. In this case on the root of the Order.

Pagination

Pagination allows you to retrieve a large number of search results by requesting them page by page. For the OrderSearchRequest, the default limit for a page is 10, all other parameters of this feature behave as described in the documentation for the search query language.

Search Index updates

As the number of Orders in the Project grows over time and Order States change on the existing Orders, the Order Search index has to be kept in sync with the changes.

Automatic updates

The Order Search index is automatically updated whenever there is a change to an Order. However, this update mechanism only applies to changes to the Order resource itself. Data for resources referenced by an Order, such as Payments, States, or Stores, are initially indexed if they exist when the Order is created, but subsequent changes to these resources will not trigger an update to the Order Search index. You can update the information in these searchable Order fields by initiating an update as described in the next section.

Initiate update

If you notice that the Search Orders endpoint is not returning the most recent Orders, you can initiate a search index rebuild. When a Project is re-indexed, all existing Orders from the last 3 months are re-processed to update the search index. This ensures that any changes made to the Orders, including state transitions or updates to Order details, are accurately reflected in search results.

Re-indexing can take several hours, depending on the volume of Orders.

This service is provided on a GraphQL endpoint by submitting a specific reindex mutation.

Reindex mutation

OAuth 2.0 Scopes: manage_project_settings:{projectKey}, view_orders:{projectKey}

mutation ReindexAllOrders {
reIndexAllOrders {
indexingJobId
existingIndexingJobId
}
}

This mutation returns following indexing job IDs:

  • indexingJobId is the ID of a new indexing job.
  • existingIndexingJobId is the ID of an already running job making progress.

Check indexing progress

For each indexing job ID you can check the status of the respective jobs like so:

OAuth 2.0 Scopes: manage_project_settings:{projectKey}, view_orders:{projectKey}

query GetReindexingStatus($jobId: String!) {
getReindexingStatus(id: $jobId) {
nbrOfIndexedDocuments
nbrOfFailedDocuments
totalNbrOfDocuments
percentCompleted
completed
}
}

Stop indexing jobs

You can stop the indexing of all Orders with following mutation:

OAuth 2.0 Scopes: manage_project_settings:{projectKey}

mutation StopIndexingOrders {
stopOrdersIndexing {
status
}
}

The response contains the status of the indexing job.

GraphQL endpoint

You can access the GraphQL endpoint with following URL:

https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphql

The endpoint accepts HTTP POST requests with following fields in a JSON body:

  • query - String - GraphQL query as a string
  • variables - Object - Optional - containing JSON object that defines variables for your query
  • operationName - String - Optional - the name of the operation, in case you defined several of them in the query

GraphiQL

To explore the GraphQL endpoint, you can use an interactive GraphiQL environment with a web browser, accessible through the following URL:

https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphiql?token={access_token}