Help teams manage content creation and approval in a clear and structured way
Hygraph
Docs

#Run batch migrations with the Management SDK

With batch migrations, you can apply multiple schema updates to an environment in a single operation.

This workflow uses the Client.getEnvironmentDiff method to get the diff, then submits all required schema changes at once. The migration either succeeds completely or fails entirely. If any step fails, no changes are applied. This reduces the risk of partial or inconsistent updates.

While supported and commonly used, submitting schema changes directly to production does not guarantee zero risk, especially when content already exists.

#How it works

Submitting batch changes is a two-step process:

  1. Generate a diff: The Management SDK compares the source environment with a target environment using getEnvironmentDiff and produces a list of schema operations required to make the target match the source.

  2. Submit the diff as a single batch: The generated diff is submitted using applySchemaChanges, which applies all operations together in a single action.

The batch either succeeds completely or fails entirely. If any operation fails validation or execution, the entire batch is rolled back.

#Supported schema elements

The following schema elements are supported for batch changes submissions:

  • Models
  • Components
  • Locales
  • Simple fields
  • Conditional visibility in fields
  • Relational fields
  • Enumerations
  • Enumerable fields
  • Initial values in enumeration fields
  • Stages
  • Union fields
  • Apps
  • Custom renderers and app fields
  • Sidebar elements
  • Remote fields
  • Remote type definitions
  • Remote sources

#Get the environment name

First, you need the environment name. For this query, you need to provide the project ID. You can find the Project ID in Project settings or in the project URL - https://app.hygraph.com/<projectId>/<environmentId>/.

  1. Navigate to the API Playground in your Hygraph project.
  2. In the API selector dropdown, select the Management API.
  3. Run the following query to get the environment names:
query MyQuery {
viewer {
project(id: "<your-project-id>") {
environments {
name
id
}
}
}
}

#Create a Management SDK client

Create a new file, for example submit-batch-changes.ts, and initialize the client with the following parameters:

import { Client } from '@hygraph/management-sdk';
const client = new Client({
authToken,
endpoint,
name, // optional
});
OptionDescription
authTokenPermanent auth token for your project. This can be retrieved from your Hygraph project in Project Settings > Permanent Auth Tokens > Token. Make sure the token has proper Management API permissions depending on what you plan to execute via the SDK.
endpointEndpoint of the High Performance Content API that belongs to the environment that you will work with. The URL can be retrieved from your Hygraph project in Project Settings > Endpoints > High Performance Content API.
nameOptional identifier used for logging and debugging. Every migration has a unique name within an environment. If unspecified, a name will be generated and will be part of the response of a successful migration. Subsequent migrations with the same name in the same environment will fail.

For more information, read this document.

#Generate a diff

Use the getEnvironmentDiff method to generate a list of operations required to make the target environment match the specified source environment.

In this example:

  • The client is initialized with the master environment's auth token and endpoint. This is the target environment where changes will be applied.
  • In the getEnvironmentDiff method, we pass development as the parameter. This is the source environment where changes come from.
  • The result is a list of operations that will make master (target) match development (source).
const diff = await client.getEnvironmentDiff("development");

This returns operations to sync schema changes from development (source) to master (target).

#Required fields in diffs

When you make a field required in the source environment (development), existing content in the target environment (master) may contain null values for that field. To apply this change successfully, you must provide a migration value that replaces null for existing entries.

Migration value in field validationsMigration value in field validations

When generating a diff, the Management SDK suggests updating the field to required, but it does not automatically include a migration value. If you apply the diff without adding one, the operation will fail.

Before applying the diff, you must manually add a migrationValue to the corresponding change.

{
"changes": [
{
"createSimpleField": {
"apiId": "newField",
"parentApiId": "Post",
"type": "STRING",
"displayName": "NewField",
"description": null,
"initialValue": null,
"tableRenderer": "GCMS_SINGLE_LINE",
"formRenderer": "GCMS_SINGLE_LINE",
"tableExtension": null,
"formExtension": null,
"formConfig": {},
"tableConfig": {},
"isList": false,
"isLocalized": false,
"isRequired": true,
"isUnique": false,
"isHidden": false,
"embeddableModels": [],
"visibility": "READ_WRITE",
"isTitle": false,
"position": 3,
"validations": null,
"embedsEnabled": null,
"migrationValue": "value"
}
}
]
}

The provided migrationValue replaces existing null values when batch changes are applied.

#Apply schema changes

Use the following method to schedule the generated diff for the target environment:

client.applySchemaChanges(diff);

This schedules all operations from the diff.

#Dry run a migration

You can dry run your migration to preview what changes would be applied.

const changes = client.dryRun();
console.log(changes);

Inspect the changes array and validate the list of operations that will be applied to the target environment.

#Run a migration in production

The run() method executes the applied schema changes, making the target environment (master) match the source environment (development).

const result = await client.run(true);
if (result.errors) {
console.log(result.errors);
} else {
console.log(result.name);
}

#Full example

Here's a complete workflow showing source/target relationships. All schema changes from development (source) are applied to master (target), making master identical to development.

import { Client } from '@hygraph/management-sdk';
async function syncEnvironments() {
// Create client for TARGET environment (where changes will be applied)
const targetClient = new Client({
authToken: '',
endpoint: '',
name: 'sync-dev-to-master'
});
// Generate diff from SOURCE environment (where changes come from)
const diff = await targetClient.getEnvironmentDiff("development");
// Apply schema changes to TARGET
try {
targetClient.applySchemaChanges(diff);
const result = await targetClient.run(true);
if (result.errors) {
console.error('Migration failed with errors:', result.errors);
return;
}
console.log('Successfully synced master to match development');
console.log(`Migration name: ${result.name}`);
console.log(`Finished at: ${result.finishedAt}`);
} catch (error) {
console.error('Migration failed:', error);
}
}
syncEnvironments();

#How schema changes affect the target environment

Batch changes submitted with the Management SDK do not merge schemas. Instead, the target schema is replaced so that it exactly matches the source schema.

The SDK first generates a diff using getEnvironmentDiff, which lists the operations required to transform the target environment (master) into the source environment (development). When this diff is applied, schema elements are added, modified, or deleted as needed to achieve an exact match. Any schema elements present in master but missing or different in development, including models, fields, and sidebar elements, may be overwritten or deleted.

If a schema change exists only in master, the diff will include operations to remove or overwrite that change. To reduce the risk of unintended deletions or content loss:

  • Freeze schema changes in master while working in development
  • Keep schema changes mirrored across environments as you go
  • Always review the generated diff before applying it

#Example scenarios

  • You clone master to create development, make schema changes in development, and later make additional schema changes directly in master. When you generate and apply the diff, the SDK will suggest deleting the changes that exist only in master, because they are not present in development.

  • A field named Title Field exists in both environments, but you rename it to Title only in master. The diff will suggest deleting Title and recreating Title Field, which aligns the schemas but results in content loss.

  • You delete a field in development and then create a new field with the same name. The diff may not detect this as a deletion and recreation, even though the underlying field identity has changed.