The requestedAction mechanism and the full patch-style update logic are already available in the current version of the API.
However, support for the replaceAll: true flag is part of an upcoming release.
This documentation anticipates that change to help you understand the evolution of the API and prepare for its extended update capabilities.
When it comes to updating records in GraphQL, particularly using Hot Chocolate, the logic closely resembles the concept of the PATCH method in RESTful APIs.
Remember
In GraphQL, the act of modification, including updates, aligns with the concept of a mutation.
Mutations in GraphQL are carried out using the HTTP POST method, which is consistent with all other mutation and query actions. This ensures a standardized and intuitive approach to making changes to data within the GraphQL schema.
Granular Data Modification
The focus is on modifying only the specific fields that need to be changed, rather than sending the entire dataset.
This approach ensures efficiency and minimizes unnecessary data transfer.
In a typical update, you only need to send the fields that have changed.
This patch-style logic avoids sending unchanged fields, reducing payload size and improving performance.
For example, if you want to update just the vatNumber of a customer, your mutation can be minimal and efficient:
However, when dealing with nested sub-resources, such as a customer’s contacts, or the phones belonging to those contacts, the situation becomes more complex.
These nested structures are common in various parts of the API, for example:
In the context of Sage Active Public API V2’s public API, the requestedAction field and the replaceAll flag play a crucial role when updating sub-resources, enabling precise control over whether to modify individual items or replace entire collections.
When dealing with nested sub-resources like contacts or phones, you have two possible strategies:
You can use a granular patch logic, combining id and requestedAction to add, modify, or delete individual items.
Or, when it’s simpler to reset everything, you can use the replaceAll flag to fully replace an entire collection, either:
at a local level (e.g. all phones of a specific contact), or
at a global level (e.g. all contacts of a customer — including their phones, emails, etc.).
This hybrid model — patch by default, with optional replace by reset — allows flexibility depending on what the calling system is capable of providing.
For example, consider the case of updating a customer who has multiple contacts, and each contact has multiple phones.
In a single update operation, you might need to:
Delete a contact who has left the company
Create a new contact
Modify the phone number of an existing contact
Add or remove phones for specific contacts
All these changes can be expressed together using the requestedAction field or simply relying on the presence or absence of id, as part of a patch-style mutation.
However, if your system does not track precisely what changed, for example, it only knows the final expected list of contacts and phones, then replaceAll becomes a better fit.
In that case, it’s easier to clear the previous values and recreate the full structure in one step. You can apply replaceAll at the appropriate collection level depending on whether you want to reset contacts, phones, or both.
Remember
Use requestedAction when your system can identify and send only the specific changes.
Use replaceAll when your system provides snapshots of the full target state, and you want to reset everything without computing diffs.
Example using requestedAction
This example demonstrates a patch-style update where:
The phones of an existing contact are individually updated (modify, delete, create)
Example using replaceAllCOMING SOON This feature is currently in development and will be available in the next version. It’s already documented to keep you informed about its upcoming availability
This example replaces the entire list of contacts and their phones:
All existing contacts are removed
The list is fully replaced by two new contacts
Each contact’s phone list is also entirely replaced (no need for replaceAll at phone level since contacts are replaced)
Recreate everything (replaceAll) COMING SOON This feature is currently in development and will be available in the next version. It’s already documented to keep you informed about its upcoming availability
❌ / ✅
Ignored
Full replacement
requestedAction: Rules and Requirements
This approach is suitable when the system replicating the data knows the exact changes to apply and can identify each sub-resource by its id.
Typically, this means the original application has stored the identifiers and is able to send only what was modified, added, or deleted.
When is requestedAction necessary?
requestedAction: DELETE → Required
You must explicitly specify this action to delete a sub-resource, along with its id.
requestedAction: MODIFY or CREATE → Optional
These are optional because the presence or absence of an id is usually sufficient:
With an id → treated as a modification
Without an id → treated as a creation
This makes payloads lighter and simplifies integration for clients who do not wish to over-specify intent.
Example: Updating a contact’s phones using requestedAction
Effect:
The phone with id = {phone1Id} is modified.
The phone with id = {phone2Id} is deleted.
A new phone is created.
The rest of the contact and other phones remain unchanged.
replaceAll: Rules and Requirements COMING SOON This feature is currently in development and will be available in the next version. It’s already documented to keep you informed about its upcoming availability
This approach is ideal when the system replicating the data does not track individual changes or identifiers, but instead only knows the final expected state.
For example, it may know that the customer has changed, but cannot determine what changed in the list of contacts or phones. In this case, it’s easier and safer to fully replace the collection.
The replaceAll flag can be used at any level of a nested resource, depending on the desired behavior.
You can apply replaceAll on a specific sub-resource, such as phones, to replace all the phones of a contact while leaving the rest of the contact unchanged.
Or you can apply replaceAll on a higher-level collection such as contacts, in which case all contacts are replaced, and each new contact replaces the previous one entirely — including its sub-resources like phones, emails, etc.
In this second case, replaceAll is only required at the top level (e.g. contacts), and you do not need to repeat it for each sub-resource like phones, emails, or socialMedias.
Rules to keep in mind:
If you apply replaceAll on a sub-resource (like phones), only that specific list is reset.
If you apply replaceAll on contacts, each contact will be recreated from scratch, including all nested sub-resources.
If you mix update modes (e.g. patching one contact and replacing another), you must apply replaceAll at the relevant sub-levels (e.g. per-contact phones).
replaceAll must always be accompanied by an items array with the new values.
Example: Replacing all contacts and their phones
Effect:
All existing contacts are deleted.
Each contact is recreated with their own sub-resources (phones, etc.).
No replaceAll is needed for nested lists, since the contacts themselves are fully replaced.
Example: Replacing only the phones of a specific contact
Effect:
The contact remains unchanged (e.g. same name, same email, same ID if provided).
Only the list of phones is fully replaced for that contact.
replaceAll is applied only at the phones level, since we are not modifying or replacing the contact itself.
This is useful when the external system knows the IDs of the contacts it needs to update, but does not track changes inside their sub-resources like phones.
It simply knows the final expected list of phones and prefers to overwrite the entire list.