Change History
Change History is an Audit Log feature that tracks creations, deletions, and updates of resources on commercetools Composable Commerce.
Change History provides a historical view into your Project’s resource changes. Changes made against resources are stored along with the time of change, source of the change, and, if provided, the user who made the change. These eventually consistent changes can then be retrieved via the Change History API or via the Merchant Center.
The Audit Log tracks and stores resource changes made after 15 March 2021. The tracked changes are represented as Records containing a list of Changes that happened together. Changes have varying data representations depending on the type of change. These are documented in the change types documentation.
The default limits are:
- tracks changes originating from within the Merchant Center only. (See the information box below.)
- maximum of 100 000 Records stored.
- maximum of 1 year retention of Records.
Extension of these limits is possible by contacting Support via the Support Portal. Such extension might be subject to a separate fee.
The API response data is based on the changes tracked and stored by Audit Log. The default Audit Log setting is to only track Merchant Center originated changes, and therefore any response data targeted at a source other than Merchant Center is an empty set.
Hosts
The Change History API has different hosts from the HTTP API. The Change History API is hosted at the following URLs:
Region | API URL |
---|---|
Europe (Google Cloud, Belgium) | https://history.europe-west1.gcp.commercetools.com/ |
North America (Google Cloud, Iowa) | https://history.us-central1.gcp.commercetools.com/ |
Australia (Google Cloud, Sydney) | https://history.australia-southeast1.gcp.commercetools.com/ |
Europe (AWS, Frankfurt) | https://history.eu-central-1.aws.commercetools.com/ BETA |
North America (AWS, Ohio) | https://history.us-east-2.aws.commercetools.com/ BETA |
If documentation refers to https://history.{region}.commercetools.com
, the {region}
placeholder has to be replaced with the actual value.
Representations
RecordPagedQueryResponse
Response to a query request for Record.
limit Int | Number of results requested. |
count Int | Actual number of results returned. |
total Int | Total number of results matching the query. This number is an estimation and not strongly consistent. |
offset Int | Number of elements skipped. |
results Array of Record |
{"limit" : 20,"offset" : 0,"count" : 1,"total" : 0,"results" : [ {"version" : 2,"previousVersion" : 1,"type" : "ResourceUpdated","modifiedAt" : "2020-03-22T23:00:00.000Z","modifiedBy" : {"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""},"resource" : {"id" : "some_entity_id_123","typeId" : "product"},"label" : {"value" : "some_label","type" : "StringLabel"},"previousLabel" : {"value" : "some_label","type" : "StringLabel"},"withoutChanges" : false,"stores" : [ {"key" : "store-1","typeId" : "store"} ],"changes" : [ {"change" : "setKey","previousValue" : "Key 1","nextValue" : "Key 2","type" : "SetKeyChange"} ]} ]}
Record
The default maximum number of Records that can be stored is 100 000. The default maximum retention period of Records is 1 year.
A Record captures the differences in a resource between one version and the next. (Recall that the version number is not always incremented by one; see Optimistic Concurrency Control.)
version Int | Version of the resource after the change. |
previousVersion Int | Version of the resource before the change. |
type String | Type of the change (creation, update or deletion). Can be"ResourceUpdated" , "ResourceCreated" , or "ResourceDeleted" |
modifiedBy | Information about the user or the API client who performed the change. |
modifiedAt String | Date and time when the change was made. |
label Label | Information that describes the resource after the change. |
previousLabel Label | Information that describes the resource before the change. |
changes Array of Change | Shows the differences in the resource between |
resource Reference | Reference to the changed resource. |
stores Array of KeyReference | |
withoutChanges Boolean |
|
{"version" : 2,"previousVersion" : 1,"type" : "ResourceUpdated","modifiedAt" : "2020-03-22T23:00:00.000Z","modifiedBy" : {"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""},"resource" : {"id" : "some_entity_id_123","typeId" : "product"},"label" : {"value" : "some_label","type" : "StringLabel"},"previousLabel" : {"value" : "some_label","type" : "StringLabel"},"withoutChanges" : false,"stores" : [ ],"changes" : [ {"change" : "setKey","previousValue" : "Key 1","nextValue" : "Key 2","type" : "SetKeyChange"} ]}
ModifiedBy
Information about the user or the API client who performed the change. This is a variant of LastModifiedBy.
id String | ID of the Merchant Center user who made the change. Present only if the change was made in the Merchant Center. |
type String | Indicates whether the change was made by a user or the API client with or without an External user ID. Can be"user" , or "external-user" |
customer Reference | Reference to the Customer who made the change. Present only if the change was made using a token from the Password Flow. |
anonymousId String | Present only if the change was made using a token from an Anonymous Session. |
clientId String | ID of the API Client that made the change. Present only if the change was made using an API Client. |
isPlatformClient Boolean |
|
{"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""}
ChangeHistoryResourceType
Represents the supported resource types. The value must be one of the following:
cart-discount
(CartDiscount)category
(Category)channel
(Channel)customer
(Customer)customer-group
(CustomerGroup)discount-code
(DiscountCode)inventory-entry
(InventoryEntry)key-value-document
(CustomObject)order
(Order)payment
(Payment)product
(Product)product-discount
(ProductDiscount)product-selection
(ProductSelection)product-type
(ProductType)quote-request
(QuoteRequest)quote
(Quote)review
(Review)shopping-list
(ShoppingList)state
(State)staged-quote
(StagedQuote)store
(Store)tax-category
(TaxCategory)type
(Type)zone
(Zone)
Label
Labels provide human readable descriptive information specific to the change.
CustomerLabel
customerNumber String | |
type String | "CustomerLabel" |
firstName String | |
lastName String |
CustomObjectLabel
key String | |
type String | "CustomObjectLabel" |
container String |
LocalizedLabel
type String | "LocalizedLabel" |
value LocalizedString |
OrderLabel
type String | "OrderLabel" |
customerEmail String | |
orderNumber String |
PaymentLabel
key String | |
type String | "PaymentLabel" |
amountPlanned Money |
ProductLabel
type String | "ProductLabel" |
slug LocalizedString | |
name LocalizedString |
QuoteRequestLabel
key String | |
type String | "QuoteRequestLabel" |
customer Reference |
QuoteLabel
key String | |
type String | "QuoteLabel" |
customer Reference | |
stagedQuote Reference | |
quoteRequest Reference |
ReviewLabel
key String | |
type String | "ReviewLabel" |
title String |
StagedQuoteLabel
key String | |
type String | "StagedQuoteLabel" |
customer Reference | |
quoteRequest Reference |
StringLabel
type String | "StringLabel" |
value String |
DateStringFilter
This type consists of one enum value:
now
PlatformInitiatedChange
excludeAll
changeLineItemName
changeReviewRatingStatistics
setApplicationVersion
setIsValid
setVariantAvailability
Query Records
Query Records
The view_audit_log:{projectKey}
scope is always required in addition to the respective scopes for the resource type to query for.
view_audit_log:{projectKey},
view_cart_discounts:{projectKey},
view_categories:{projectKey},
view_customers:{projectKey},
view_customer_groups:{projectKey},
view_discount_codes:{projectKey},
view_key_value_documents:{projectKey},
view_orders:{projectKey},
view_orders:{projectKey}:{storeKey},
view_payments:{projectKey},
view_products:{projectKey},
view_product_selections:{projectKey},
view_quotes:{projectKey},
view_quote_requests:{projectKey},
view_shopping_lists:{projectKey},
view_states:{projectKey},
view_staged_quotes:{projectKey},
view_stores:{projectKey},
view_tax_categories:{projectKey},
view_types:{projectKey}
region String | The Region in which the project is hosted. |
projectKey String |
|
expand Boolean | If |
limit Int | Number of results requested. |
offset Int | Number of elements skipped. |
resourceTypes | Can be used to filter for Records of specified resource types. By default, the API returns the Records of all supported resource types. The parameter can be passed multiple times. |
date.from | Can be DateTime, non-negative integer, or |
date.to | Can be DateTime, non-negative integer, or |
userId String | ID of the Merchant Center user who made the change. Can be used to query changes made by a Merchant Center user. |
type String | Can be |
clientId String | ID of the API Client that made the change. |
resourceId String | ID of the changed resource. |
source String | Name of the source with which changes were made. Can be |
changes String | Restrict the types of Changes returned by passing the value of the The parameter can be passed multiple times. |
stores String |
The parameter can be passed multiple times. |
customerId String | ID of the Customer who made the change using a token from the Password Flow. |
excludePlatformInitiatedChanges | Exclude Changes initiated by background processes by passing the values of the
The parameter can be passed multiple times. |
curl --get https://history.{region}.commercetools.com/{projectKey} -i \--header 'Authorization: Bearer ${BEARER_TOKEN}'
{"limit" : 20,"offset" : 0,"count" : 1,"total" : 0,"results" : [ {"version" : 2,"previousVersion" : 1,"type" : "ResourceUpdated","modifiedAt" : "2020-03-22T23:00:00.000Z","modifiedBy" : {"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""},"resource" : {"id" : "some_entity_id_123","typeId" : "product"},"label" : {"value" : "some_label","type" : "StringLabel"},"previousLabel" : {"value" : "some_label","type" : "StringLabel"},"withoutChanges" : false,"stores" : [ {"key" : "store-1","typeId" : "store"} ],"changes" : [ {"change" : "setKey","previousValue" : "Key 1","nextValue" : "Key 2","type" : "SetKeyChange"} ]} ]}
Query Records for specific resource type
The view_audit_log:{projectKey}
scope is always required in addition to the respective scopes for the resource type to query for.
view_audit_log:{projectKey},
view_cart_discounts:{projectKey},
view_categories:{projectKey},
view_customers:{projectKey},
view_customer_groups:{projectKey},
view_discount_codes:{projectKey},
view_key_value_documents:{projectKey},
view_orders:{projectKey},
view_orders:{projectKey}:{storeKey},
view_payments:{projectKey},
view_products:{projectKey},
view_product_selections:{projectKey},
view_quotes:{projectKey},
view_quote_requests:{projectKey},
view_shopping_lists:{projectKey},
view_states:{projectKey},
view_staged_quotes:{projectKey},
view_stores:{projectKey},
view_tax_categories:{projectKey},
view_types:{projectKey}
region String | The Region in which the project is hosted. |
projectKey String |
|
resourceType String | Resource type for which a query is made.
The value must be one of the following:
|
expand Boolean | If |
limit Int | Number of results requested. |
offset Int | Number of elements skipped. |
date.from | Can be DateTime, non-negative integer, or |
date.to | Can be DateTime, non-negative integer, or |
userId String | ID of the Merchant Center user who made the change. Can be used to query changes made by a Merchant Center user. |
type String | Can be |
clientId String | ID of the API Client that made the change. |
resourceId String | ID of the changed resource. |
source String | Name of the source with which changes were made. Can be |
changes String | Restrict the types of Changes returned by passing the value of the The parameter can be passed multiple times. |
stores String |
The parameter can be passed multiple times. |
customerId String | ID of the Customer who made the change using a token from the Password Flow. |
excludePlatformInitiatedChanges | Exclude Changes initiated by background processes by passing the values of the
The parameter can be passed multiple times. |
curl --get https://history.{region}.commercetools.com/{projectKey}/{resourceType} -i \--header 'Authorization: Bearer ${BEARER_TOKEN}'
{"limit" : 20,"offset" : 0,"count" : 1,"total" : 0,"results" : [ {"version" : 2,"previousVersion" : 1,"type" : "ResourceUpdated","modifiedAt" : "2020-03-22T23:00:00.000Z","modifiedBy" : {"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""},"resource" : {"id" : "some_entity_id_123","typeId" : "product"},"label" : {"value" : "some_label","type" : "StringLabel"},"previousLabel" : {"value" : "some_label","type" : "StringLabel"},"withoutChanges" : false,"stores" : [ {"key" : "store-1","typeId" : "store"} ],"changes" : [ {"change" : "setKey","previousValue" : "Key 1","nextValue" : "Key 2","type" : "SetKeyChange"} ]} ]}
Query Records by resource ID
The view_audit_log:{projectKey}
scope is always required in addition to the respective scopes for the resource type to query for.
view_audit_log:{projectKey},
view_cart_discounts:{projectKey},
view_orders:{projectKey},
view_orders:{projectKey}:{storeKey},
view_categories:{projectKey},
view_products:{projectKey},
view_customers:{projectKey},
view_customer_groups:{projectKey},
view_discount_codes:{projectKey},
view_key_value_documents:{projectKey},
view_payments:{projectKey},
view_product_selections:{projectKey},
view_quotes:{projectKey},
view_quote_requests:{projectKey},
view_shopping_lists:{projectKey},
view_states:{projectKey},
view_staged_quotes:{projectKey},
view_stores:{projectKey},
view_tax_categories:{projectKey},
view_types:{projectKey}
region String | The Region in which the project is hosted. |
projectKey String |
|
resourceType String | Resource type for which a query is made.
The value must be one of the following:
|
id String | ID of the resource for which a query is made. |
expand Boolean | If |
limit Int | Number of results requested. |
offset Int | Number of elements skipped. |
date.from | Can be DateTime, non-negative integer, or |
date.to | Can be DateTime, non-negative integer, or |
userId String | ID of the Merchant Center user who made the change. Can be used to query changes made by a Merchant Center user. |
type String | Can be |
clientId String | ID of the API Client that made the change. |
source String | Name of the source with which changes were made. Can be |
changes String | Restrict the types of Changes returned by passing the value of the The parameter can be passed multiple times. |
stores String |
The parameter can be passed multiple times. |
customerId String | ID of the Customer who made the change using a token from the Password Flow. |
excludePlatformInitiatedChanges | Exclude Changes initiated by background processes by passing the values of the
The parameter can be passed multiple times. |
curl --get https://history.{region}.commercetools.com/{projectKey}/{resourceType}/{id} -i \--header 'Authorization: Bearer ${BEARER_TOKEN}'
{"limit" : 20,"offset" : 0,"count" : 1,"total" : 0,"results" : [ {"version" : 2,"previousVersion" : 1,"type" : "ResourceUpdated","modifiedAt" : "2020-03-22T23:00:00.000Z","modifiedBy" : {"isPlatformClient" : true,"id" : "example_user_123","type" : "user","customer" : {"id" : "test1","typeId" : "customer"},"anonymousId" : "","clientId" : ""},"resource" : {"id" : "some_entity_id_123","typeId" : "product"},"label" : {"value" : "some_label","type" : "StringLabel"},"previousLabel" : {"value" : "some_label","type" : "StringLabel"},"withoutChanges" : false,"stores" : [ {"key" : "store-1","typeId" : "store"} ],"changes" : [ {"change" : "setKey","previousValue" : "Key 1","nextValue" : "Key 2","type" : "SetKeyChange"} ]} ]}
Query Records via GraphQL
GraphQL endpoint
You can access the GraphQL endpoint with following URL:
https://history.{region}.commercetools.com/{projectKey}/graphql
The endpoint accepts HTTP POST requests with following fields in a JSON body:
query
- String - GraphQL query as a stringvariables
- Object - Optional - containing JSON object that defines variables for your queryoperationName
- String - Optional - the name of the operation, in case you defined several of them in the query
Find below an example for a query for changes on Products to be executed as cURL command:
$ curl -X POST https://history.{region}.commercetools.com/{projectKey}/graphql \-H "Content-Type:application/json" \-H "Authorization:Bearer ..." \-d '{"query": "query (resourceTypes: Product) {results {type changes {previousValue nextValue change} }}" }'
Interactive GraphQL console
To query for the Records via GraphQL you can use an interactive GraphiQL environment that is available on following URL:
https://history.{region}.commercetools.com/{projectKey}/graphiql
To be able to use it, you need to provide a valid OAuth token for an API Client that has the above mentioned scopes.
{"authorization": "Bearer XXXXXXX"}
This console lets you explore the docs for the supported GraphQL queries and to introspect the GraphQL schema.
Scopes
Application of OAuth 2.0 scopes
You always need to grant the view_audit_log:{projectKey}
scope to the query, plus (depending on the resource type you query for), the respective scopes additionally:
view_cart_discounts:{projectKey}
view_categories:{projectKey}
view_customers:{projectKey}
view_customer_groups:{projectKey}
view_discount_codes:{projectKey}
view_key_value_documents:{projectKey}
view_orders:{projectKey}
view_orders:{projectKey}:{storeKey}
view_payments:{projectKey}
view_product_selections:{projectKey}
view_products:{projectKey}
view_quote_requests:{projectKey}
view_quotes:{projectKey}
view_shopping_lists:{projectKey}
view_states:{projectKey}
view_staged_quotes:{projectKey}
view_stores:{projectKey}
view_tax_categories:{projectKey}
view_types:{projectKey}
Stores data fencing
Stores provide an extra level of granularity to Project data.
If Audit Log tracked a Change on a supported resource that has stores
linked to it, then the Audit log Record has attached the store
or stores
that were linked at the time the Change was initiated.
A Record attached to a Store means that users would have limited access to the change depending on the store they are assigned to. The access will vary depending on the entity type.
Audit Log considers the two following premises:
- A Record without Stores is considered a global change.
- A Record with a Store attached to it is considered a Store-specific change.
See below how store-specific scopes are applied on queries for Changes on supported resource types:
Customers
If an API Client only has the view_customers:{projectKey}:store-1
scope it can only see changes on Customers associated with store-1
and global changes.
Orders
If an API Client only has the view_orders:{projectKey}:store-1
scope it can only see changes on Orders associated with store-1
.
Shopping Lists
If an API Client only has the view_shopping_lists:{projectKey}:store-1
scope it can only see changes on Shopping Lists associated with store-1
.