Automate the reordering process for frequently purchased products.
Recurring Orders automate the reordering process for a Customer. You can define the Cart containing the products to be ordered, the reorder frequency, and the start and end dates. Once configured, orders are placed automatically for the Customer at the scheduled interval. Recurring Orders can be modified, paused, or canceled to accommodate changes in demand.
Representations
RecurringOrder
id​String​ | Unique identifier of the RecurringOrder. |
version​Int​ | Current version of the RecurringOrder. |
key​String​ | User-defined unique identifier of the RecurringOrder. MinLength:Â2​MaxLength: 256​Pattern: ^[A-Za-z0-9_-]+$​ |
cart​ | Reference to the Cart for a RecurringOrder.
The referenced Cart will have the RecurringOrder CartOrigin. |
originOrder​ | |
startsAt​DateTime​ | Date and time (UTC) when the RecurringOrder starts creating new Orders. |
resumesAt​DateTime​ | Date and time (UTC) when the RecurringOrder resumes creating Orders after being unpaused. |
expiresAt​DateTime​ | Date and time (UTC) when the RecurringOrder expires. |
lastOrderAt​DateTime​ | Date and time (UTC) when the last Order was created from this RecurringOrder. |
nextOrderAt​DateTime​ | Date and time (UTC) when the next Order will be created from this RecurringOrder. |
skipConfiguration​ | Information about current and future skips for this RecurringOrder. |
store​ | Reference to a Store. |
businessUnit​ | Reference to the Business Unit that the RecurringOrder belongs to. |
state​ | State of the RecurringOrder in a custom workflow. |
recurringOrderState​ | Current state of the RecurringOrder. |
schedule​ | Schedule of the RecurringOrder. |
customer​ | The Customer that the RecurringOrder belongs to. |
customerEmail​String​ | Email address of the Customer that the RecurringOrder belongs to. |
custom​CustomFields​ | Custom Fields of the RecurringOrder. |
createdAt​DateTime​ | Date and time (UTC) when the RecurringOrder was created. |
createdBy​BETACreatedBy​ | IDs and references that created the RecurringOrder. |
lastModifiedAt​DateTime​ | Date and time (UTC) when the RecurringOrder was last updated. |
lastModifiedBy​BETA | IDs and references that last modified the RecurringOrder. |
RecurringOrderDraft
Recurring Orders are automatically assigned the Store and/or Business Unit from the associated Cart.
key​String​ | User-defined unique identifier of the RecurringOrder. MinLength: 2​MaxLength: 256​Pattern: ^[A-Za-z0-9_-]+$​ |
cart​ | ResourceIdentifier to the Cart from which the RecurringOrder is created. |
cartVersion​Int​ | Current version of the referenced Cart. |
startsAt​DateTime​ | Date and time (UTC) when the RecurringOrder will start. When specified, the date and time must be in the future. If not specified, the recurring order will start immediately. |
expiresAt​DateTime​ | Date and time (UTC) when the RecurringOrder will expire. |
state​ | State for the RecurringOrder in a custom workflow. |
custom​ | Custom Fields for the RecurringOrder. |
RecurringOrderPagedQueryResponse
limit​Int​ | Number of results requested. Default: 20​Minimum: 0​Maximum: 500​ |
offset​Int​ | Number of elements skipped. Default: 0​Minimum: 0​Maximum: 10000​ |
count​Int​ | Actual number of results returned. |
total​Int​ | Total number of results matching the query.
This number is an estimation that is not strongly consistent.
This field is returned by default.
For improved performance, calculating this field can be deactivated by using the query parameter withTotal=false.
When the results are filtered with a Query Predicate, total is subject to a limit. |
results​Array of RecurringOrder​ | RecurringOrders matching the query. |
RecurringOrderReference
id​String​ | Unique identifier of the referenced RecurringOrder. |
typeId​ | recurring-orderType of referenced resource. |
obj​ | Contains the representation of the expanded RecurringOrder.
Only present in responses to requests with Reference Expansion for RecurringOrders. |
RecurringOrderResourceIdentifier
id or key is required. If both are set, an InvalidJsonInput error is returned.id​String​ | Unique identifier of the referenced RecurringOrder. Required if key is absent. |
key​String​ | User-defined unique identifier of the referenced RecurringOrder. Required if id is absent. |
typeId​ | recurring-orderType of referenced resource. If given, it must match the expected ReferenceTypeId of the referenced resource. |
RecurringOrderState
ActiveThe default state of a new RecurringOrder.
PausedIndicates that the RecurringOrder is paused.
ExpiredIndicates that the RecurringOrder has expired.
CanceledIndicates that the RecurringOrder is canceled.
Failed- Indicates that the process of creating new orders has failed. The field
failurestores the error encountered (inventory unavailable, etc). New orders will not be created until the issue is fixed.
RecurringOrderStateDraft
RecurringOrderActive
Changes the Recurring Order state to active.
type​String​ | "active" |
resumesAt​DateTime​ | If set, the Recurring Order will automatically resume at the date and time (UTC) specified. |
RecurringOrderPaused
Changes the Recurring Order state to paused.
type​String​ | "paused" |
RecurringOrderExpired
Changes the Recurring Order state to expired.
type​String​ | "expired" |
RecurringOrderCanceled
Changes the Recurring Order state to canceled.
type​String​ | "canceled" |
reason​String​ | The reason for the cancelation. |
SkipConfiguration
Generic type that shows how future orders will be skipped.
Supported data types:
Counter
Counter
type​String​ | "Counter" |
totalToSkip​Int​ | Number of Orders that will be skipped. |
skipped​Int​ | Number of Orders that were already skipped. |
lastSkippedAt​DateTime​ | Date and time (UTC) when the last Order creation was skipped. |
SkipConfigurationDraft
CounterDraft
Configuration that uses a counter to track the number of Orders that will be skipped.
type​String​ | "Counter" |
totalToSkip​Int​ | Number of Orders that will be skipped. |
PriceSelectionMode
Fixed- The price set when the Recurring Order was created is used for each subsequent order.
DynamicThe price is updated each time a new Order is created.
Get RecurringOrder
Get RecurringOrder by ID
id.view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
idString ​ | id of the RecurringOrder. |
expand | The parameter can be passed multiple times. |
application/jsoncurl --get https://api.{region}.commercetools.com/{projectKey}/recurring-orders/{id} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" {
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Get RecurringOrder by Key
key.view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
keyString ​ | key of the RecurringOrder. |
expand | The parameter can be passed multiple times. |
application/jsoncurl --get https://api.{region}.commercetools.com/{projectKey}/recurring-orders/key={key} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" {
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Query RecurringOrders
Retrieves Recurring Orders in the Project.
view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
where | The parameter can be passed multiple times. |
sort | The parameter can be passed multiple times. |
expand | The parameter can be passed multiple times. |
limitInt ​ | Number of results requested. Default: 20​Minimum: 0​Maximum: 500​ |
offsetInt ​ | Number of elements skipped. Default: 0​Maximum: 10000​ |
withTotalBoolean ​ | Controls the calculation of the total number of query results. Set to false to improve query performance when the total is not needed.Default: true​ |
var.<varName>String ​ | Predicate parameter values. The parameter can be passed multiple times. |
RecurringOrderPagedQueryResponse
asapplication/jsoncurl --get https://api.{region}.commercetools.com/{projectKey}/recurring-orders -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" {
"limit": 20,
"offset": 0,
"count": 1,
"total": 1,
"results": [
{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}
]
}Check if RecurringOrder exists
Check if RecurringOrder exists by ID
id. Returns a 200 status if the Recurring Order exists, or a NotFound error otherwise.view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
idString ​ | id of the RecurringOrder. |
curl --head https://api.{region}.commercetools.com/{projectKey}/recurring-orders/{id} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" Check if RecurringOrder exists by Key
key. Returns a 200 status if the Recurring Order exists, or a NotFound error otherwise.view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
keyString ​ | key of the RecurringOrder. |
curl --head https://api.{region}.commercetools.com/{projectKey}/recurring-orders/key={key} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" Check if RecurringOrder exists by Query Predicate
200 status if any Recurring Orders match the query predicate, or a NotFound error otherwise.view_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
where | The parameter can be passed multiple times. |
curl --head https://api.{region}.commercetools.com/{projectKey}/recurring-orders -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" Create RecurringOrder
Expired, and no Order will be created.If a server-side problem occurs, indicated by a 500 Internal Server Error HTTP response, the Recurring Order creation may still successfully complete after the error is returned. If you receive this error, you should verify the status of the Recurring Order by querying a unique identifier supplied during the creation request, such as the key.
manage_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
expand | The parameter can be passed multiple times. |
application/jsonapplication/jsoncurl https://api.{region}.commercetools.com/{projectKey}/recurring-orders -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--header 'Content-Type: application/json' \
--data-binary @- << DATA
{
"cart" : {
"id" : "7c2e2694-aefe-43d7-888e-6a99514caaca",
"typeId" : "cart"
},
"cartVersion" : 10,
"startsAt" : "2017-01-04T19:54:49.797Z"
}
DATA{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Update RecurringOrder
Update RecurringOrder by ID
manage_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
idString ​ | id of the RecurringOrder. |
expand | The parameter can be passed multiple times. |
application/jsonversion​Int​ | Expected version of the RecurringOrder on which the changes should be applied.
If the expected version does not match the actual version, a ConcurrentModification error will be returned. |
actions​Array of RecurringOrderUpdateAction​ | Update actions to be performed on the RecurringOrder. |
application/jsoncurl https://api.{region}.commercetools.com/{projectKey}/recurring-orders/{id} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--header 'Content-Type: application/json' \
--data-binary @- << DATA
{
"version" : 1,
"actions" : [ {
"action" : "setKey",
"key" : "new-key"
} ]
}
DATA{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Update RecurringOrder by Key
manage_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
keyString ​ | key of the RecurringOrder. |
expand | The parameter can be passed multiple times. |
application/jsonversion​Int​ | Expected version of the RecurringOrder on which the changes should be applied.
If the expected version does not match the actual version, a ConcurrentModification error will be returned. |
actions​Array of RecurringOrderUpdateAction​ | Update actions to be performed on the RecurringOrder. |
application/jsoncurl https://api.{region}.commercetools.com/{projectKey}/recurring-orders/key={key} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--header 'Content-Type: application/json' \
--data-binary @- << DATA
{
"version" : 1,
"actions" : [ {
"action" : "setKey",
"key" : "new-key"
} ]
}
DATA{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Update actions
Set Key
action​String​ | "setKey" |
key​String​ | Value to set. If empty, any existing key will be removed. MinLength:Â2​MaxLength: 256​Pattern: ^[A-Za-z0-9_-]+$​ |
{
"action": "setKey",
"key": "new-key"
}Transition State
transitions, there must be a direct transition to the new State.
If transitions is not set, no validation is performed.action​String​ | "transitionState" |
state​ | Value to set. If there is no State yet, the new State must be an initial State. |
force​Boolean​ | Set to Default: true to turn off validation.false​ |
{
"action": "transitionState",
"state": {
"typeId": "state",
"id": "{{state-id}}"
}
}Set RecurringOrderState
action​String​ | "setRecurringOrderState" |
recurringOrderState​ | New state of the RecurringOrder. |
{
"action": "setRecurringOrderState",
"recurringOrderState": {
"type": "active"
}
}Set Order Skip Configuration
action​String​ | "setOrderSkipConfiguration" |
skipConfigurationInputDraft​ | Configuration for skipping future orders of the Recurring Order. |
updatedExpiresAt​DateTime​ | Date and time (UTC) the Recurring Order will expire and stop generating new orders. |
{
"action": "setOrderSkipConfiguration",
"skipConfigurationInputDraft": {
"type": "Counter",
"totalToSkip": 3
},
"updatedExpiresAt": "2025-10-15T15:00:00.000Z"
}Set Starts At
action​String​ | "setStartsAt" |
startsAt​DateTime​ | Date and time (UTC) the Recurring Order should be started. The date and time must be in the future. |
{
"action": "setStartsAt",
"startsAt": "2025-10-15T15:00:00.000Z"
}Set Expires At
action​String​ | "setExpiresAt" |
expiresAt​DateTime​ | Date and time (UTC) the Recurring Order should expire. If empty, any existing value will be removed. If the date or time is extended or removed when the RecurringOrderState is Expired, the state will be updated to Active. |
{
"action": "setExpiresAt",
"expiresAt": "2025-10-15T15:00:00.000Z"
}Set Schedule
action​String​ | "setSchedule" |
recurrencePolicy​ | Value to set. |
{
"action": "setSchedule",
"recurrencePolicy": {
"typeId": "recurrence-policy",
"id": "{{recurrence-policy-id}}"
}
}Set Custom Type
action​String​ | "setCustomType" |
type​ | Defines the Type that extends the RecurringOrder with Custom Fields.
If absent, any existing Type and Custom Fields are removed from the RecurringOrder. |
fields​ | Sets the Custom Fields fields for the RecurringOrder. |
{
"action": "setCustomType",
"type": {
"id": "{{type-id}}",
"typeId": "type"
},
"fields": {
"exampleStringField": "TextString"
}
}Set CustomField
action​String​ | "setCustomField" |
name​String​ | Name of the Custom Field. |
value​ | If value is absent or null, this field will be removed if it exists.
Removing a field that does not exist returns an InvalidOperation error.
If value is provided, it is set for the field defined by name. |
{
"action": "setCustomField",
"name": "ExampleStringTypeField",
"value": "TextString"
}Delete RecurringOrder
recurringOrderState of Expired or Canceled can be deleted.Delete RecurringOrder by ID
Deletes a Recurring Order in the Project.
manage_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
idString ​ | id of the RecurringOrder. |
versionInt ​ | Last seen version of the resource. |
expand | The parameter can be passed multiple times. |
dataErasureBoolean ​ | To erase all related personal data in compliance with GDPR, set to true.Default: false​ |
application/jsoncurl -X DELETE https://api.{region}.commercetools.com/{projectKey}/recurring-orders/{id}?version={version} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}"{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}Delete RecurringOrder by Key
Deletes a Recurring Order in the Project.
manage_recurring_orders:{projectKey}regionString ​ | Region in which the Project is hosted. |
projectKeyString ​ | key of the Project. |
keyString ​ | key of the RecurringOrder. |
versionInt ​ | Last seen version of the resource. |
expand | The parameter can be passed multiple times. |
dataErasureBoolean ​ | To erase all related personal data in compliance with GDPR, set to true.Default: false​ |
application/jsoncurl -X DELETE https://api.{region}.commercetools.com/{projectKey}/recurring-orders/key={key}?version={version} -i \
--header "Authorization: Bearer ${BEARER_TOKEN}"{
"id": "42c72ffb-d1e6-4eb2-b05f-17d227f8422d",
"version": 1,
"createdAt": "2025-01-06T20:09:33.751Z",
"lastModifiedAt": "2025-01-06T20:09:33.751Z",
"cart": {
"typeId": "cart",
"id": "d688de05-dc0a-43de-91dc-94ab30f21c1e"
},
"originOrder": {
"typeId": "order",
"id": "68c20103-fc7b-430f-8f00-094c312b19e6"
},
"businessUnit": {
"typeId": "business-unit",
"key": "bu-key"
},
"startsAt": "2025-01-02T20:09:33.644Z",
"lastOrderAt": "2025-01-06T16:00:25.657Z",
"nextOrderAt": "2025-01-07T20:09:33.644Z",
"recurringOrderState": "Active",
"schedule": {
"type": "standard",
"value": 1,
"intervalUnit": "Days"
}
}