Migrate content between SitecoreAI environments using the Content Transfer API and the Item Transfer API
This walkthrough describes how to use the Content Transfer API and the Item Transfer API to migrate content from one SitecoreAI environment to another. The instructions cover all the steps required to complete a migration:
- Create the transfer
- Wait for the transfer to be ready
- Transfer chunks
- Delete the transfer in the source environment
- Load the content into the destination database
Note that the same instructions are also available in the Migrating content sections of the Content Transfer API and the Item Transfer API specifications. This allows AI coding assistants and agent tools that directly consume the OpenAPI specifications to guide you through the migration workflow without leaving your development environment.
- Ensure you have the Organization Admin or Organization Owner role in the Sitecore Cloud Portal. Both APIs require this role.
- Find the host names for your source and destination environments in SitecoreAI Deploy > Projects > your project > Authoring environments > your environment > Details > Environment host name. You use the host name to construct the base URL for each API request.
- Create automation client credentials for both environments and generate a JWT for each. See the Content Transfer API and Item Transfer API specifications for instructions.
Create the transfer
Make the following API request in your source environment:
POST /sitecore/api/content/transfer/v1/transfers
Specify a unique TransferId UUID of your choice, and one or more entries in DataTrees. Use one entry per item path you want to transfer. For each entry, set:
ItemPath- the Sitecore content path of the item.Scope- chooseSingleItemto transfer only the item. ChooseItemAndDescendantsto transfer the item and its entire subtree. Ensure that the item's parent chain exists in the destination environment with the same item IDs. If it does not, the item will transfer successfully but will not appear in the content tree. To avoid this, transfer from a common ancestor usingItemAndDescendants, or ensure all parent items are transferred first.MergeStrategy- how to handle conflicts with items that already exist in the destination. The options are:OverrideExistingItem- replace the existing item with the transferred version.KeepExistingItem- leave the existing item unchanged.OverrideExistingTree- remove the item and all its descendants from the destination, then write all items from the transfer. This is the only merge strategy that can delete existing items. Use with caution.
Example request body:
A successful request returns 202 Accepted.
Wait for the transfer to be ready
Make the following API request in your source environment using the TransferId from the previous procedure:
GET /sitecore/api/content/transfer/v1/transfers/{transferId}/status
Poll this endpoint until State is Completed. If State is Failed, the transfer was not successful and cannot continue. In this scenario, create a new transfer. The response includes a ChunkSetsMetadata array. For each chunk set, record:
ChunkSetId- the unique identifier of the chunk set, used as a path parameter in subsequent requests.ChunkCount- the number of chunks to retrieve. Chunks are numbered0throughChunkCount - 1.
Transfer chunks
For each chunk, repeat the retrieve and save steps. After all chunks in a set are saved, complete the chunk set once.
Retrieve a chunk from the source environment
Make the following API request in your source environment:
GET /sitecore/api/content/transfer/v1/transfers/{transferId}/chunksets/{chunksetId}/chunks/{chunkId}
Make one request per chunk, using chunkId values 0 through ChunkCount - 1. The response body is a binary stream. Note the IsMedia value from the Content-Disposition response header because you'll use it in the next step.
You can retrieve multiple chunks in parallel.
Save the chunk in the destination environment
Make the following API request in your destination environment:
PUT /sitecore/api/content/transfer/v1/transfers/{transferId}/chunksets/{chunksetId}/chunks/{chunkId}
- Set
Content-Type: application/octet-stream. - Set the
isMediaquery parameter to theIsMediavalue from the previous step. - Forward the binary stream exactly as received. Do not decompress, decrypt, or modify the data.
A successful request returns 201 Created.
You can save chunks in parallel with retrieval, but all chunks in a set must be saved before you complete that chunk set.
Complete the chunk set in the destination environment
After all chunks in a set are saved, make the following API request in your destination environment:
POST /sitecore/api/content/transfer/v1/transfers/{transferId}/chunksets/{chunksetId}/complete
This generates a .raif file in the destination and returns its name:
Record this file name because you'll use it in a later procedure.
Delete the transfer in the source environment
Make the following API request in your source environment:
DELETE /sitecore/api/content/transfer/v1/transfers/{transferId}
This cleans up the transfer operation and all associated resources. You can do this immediately after downloading all chunks from the source environment.
Load the content into the destination database
To complete the migration, use the Item Transfer API in your destination environment to incorporate the .raif files into the database.
Verify the blob is available
Before consuming a .raif file, confirm it is available in Azure Blob Storage by making the following API request in your destination environment:
GET /sources/blobs
The response lists available blob sources and their states. The .raif file you recorded in the previous step should appear with a BlobState of Uploaded, which means that the file is ready to consume.
Start consuming the blob
Make the following API request in your destination environment:
POST /transfers/databases/{databaseName}/sources?blobName={ContentTransferFileName}
The location response header contains a URL. The final path segment of this URL is the transfer ID used in subsequent requests.
Transferred items are immediately available to work with in the destination environment while the system completes the sync to the database in the background.
Monitor the transfer
Although items are available immediately, poll the transfer status to detect failures. If the background sync fails before completing, items that were not yet synced will become unavailable and the transfer must be retried.
Make the following API request in your destination environment and poll it until TransferState is Finished:
GET /transfers/{transferId}
If TransferState is Failed, retry the transfer using the following endpoint:
PUT /transfers/databases/{databaseName}/sources/{sourceName}
Clean up the destination environment
After the transfer is finished, make the following API request in your destination environment:
DELETE /sources/blobs/{blobName}
This removes the .raif file, which is no longer needed.
Transferred items follow your normal publishing workflow.
Troubleshooting
TransferredWithErrors state
If BlobState is TransferredWithErrors, this is a terminal state indicating a partial success. To investigate, retrieve the transfer details to review the ValidationErrors list:
GET /transfers/{transferId}
Items transferred but not visible in the content tree
If a transferred item does not appear in the destination content tree, the most likely cause is that the parent chain does not exist in the destination environment with the same item IDs. To fix this, either transfer from a common ancestor using Scope: ItemAndDescendants, or transfer the parent items first before transferring the child item.