Leveraging Sitecore's GraphQL API for Automated Content Delivery
The demand for efficient and flexible content management tools continues to grow in the digital space. While Sitecore is renowned for its powerful and adaptable platform, offering solutions for diverse scenarios, it lacks built-in functionality for automated, scheduled content publishing out-of-the-box. Manually publishing content, especially on a regular schedule, can be time-consuming and prone to errors.
Fortunately, Sitecore's inherent flexibility provides a powerful solution: the Sitecore Authoring and Management GraphQL API. This API gives developers granular control over content operations via a dedicated GraphQL endpoint.
This post focuses on harnessing this API to solve a common challenge: setting up automated daily publishing for specific Sitecore content items. We'll walk you through creating a Next.js serverless function that interacts with the Sitecore API and can be easily deployed and scheduled using Vercel Cron Jobs.
Why Automate Sitecore Publishing?
Implementing an automated publishing workflow offers significant advantages:
- Reliable Scheduling: Ensure content goes live exactly when needed, meeting deadlines consistently without manual oversight.
- Streamlined Operations: Free up your team from repetitive manual publishing tasks, reducing the chance of human error and increasing overall productivity.
- Improved Consistency: Maintain a regular publishing cadence effortlessly.
The Automated Publishing Workflow
Our solution involves two core components:
- A Next.js Serverless API Route: This function will contain the logic to authenticate with Sitecore and trigger the publish operation via the GraphQL API.
- A Vercel Cron Job: This scheduler will trigger our Next.js API route at predefined intervals (e.g., daily).
The serverless function itself performs two main steps:
- Authentication: It obtains an access token from the Sitecore Identity service using your application's credentials.
- Publishing: It uses the obtained token to authenticate a GraphQL mutation request to the Sitecore Authoring and Management API, instructing Sitecore to publish the specified content.
Diagram showing the flow: Vercel Cron Job triggers Next.js API route, which calls Sitecore Auth API for a token, then calls Sitecore GraphQL API to publish content.
Setting Up Sitecore XM Cloud Credentials
Before writing any code, we need to generate API credentials within the Sitecore XM Cloud Deploy Platform. These credentials (Client ID and Client Secret) are essential for authenticating our serverless function.
- Log in to the XM Cloud Deploy Platform.
- Navigate to Credentials in the left-hand navigation pane.

- If you don't have suitable credentials, click the Create credentials button on the top right.

- A popup form will appear. Fill in the details to describe the purpose of these credentials (e.g., "Automated Publishing Service").

- After creation, Sitecore will display your Client ID and Client Secret. Crucially, the Client Secret is shown only once. Copy both values immediately and store them securely, typically as environment variables in your deployment environment (like Vercel).

For our code example, we'll assume you've stored these in environment variables named SITECORE_CLIENT_ID
and SITECORE_CLIENT_SECRET
. You'll also need the URL for your Sitecore Authoring GraphQL endpoint, which we'll store as SITECORE_AUTHORING_ENDPOINT
.
Building the Next.js API Route for Publishing
Now, let's create the Next.js API route (a serverless function) that handles the authentication and publishing logic. Create a file like pages/api/publish-content.ts
:
import type { NextApiRequest, NextApiResponse } from 'next';
// Retrieve sensitive information and endpoints from environment variables
const CLIENT_ID = process.env.SITECORE_CLIENT_ID ?? '';
const CLIENT_SECRET = process.env.SITECORE_CLIENT_SECRET ?? '';
const GRAPHQL_ENDPOINT = process.env.SITECORE_AUTHORING_ENDPOINT ?? '';
// Static Sitecore Identity URL for token generation
const SITECORE_IDENTITY_URL = 'https://auth.sitecorecloud.io/oauth/token';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method Not Allowed' });
}
try {
// Step 1: Get auth token
const tokenRes = await fetch(SITECORE_IDENTITY_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
audience: 'https://api.sitecorecloud.io',
}),
});
const tokenData = await tokenRes.json();
if (!tokenRes.ok) throw new Error(tokenData.error_description || 'Failed to get token');
const accessToken = tokenData.access_token;
// Step 2: Publish item using GraphQL
const graphqlQuery = {
query: `
mutation {
publishItem(
input: {
languages: ["en"]
rootItemPaths: [
"/sitecore/content/Blogs"
]
targetDatabases: "experienceedge"
publishItemMode: SMART
publishRelatedItems: false
publishSubItems: true
}
) {
operationId
}
}
`,
};
const graphqlRes = await fetch(GRAPHQL_ENDPOINT, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(graphqlQuery),
});
const result = await graphqlRes.json();
if (result.errors) {
return res.status(500).json({ error: result.errors });
}
return res.status(200).json({ result: result.data.publishItem });
} catch (error) {
console.error(error);
res.status(500).json({ error: (error as Error).message || 'Unexpected error' });
}
}
Understanding the Code
Let me breakdown the code above and give some explanation on each important section.
Setting Up the API Route
import type { NextApiRequest, NextApiResponse } from 'next';
const CLIENT_ID = process.env.SITECORE_CLIENT_ID ?? '';
const CLIENT_SECRET = process.env.SITECORE_CLIENT_SECRET ?? '';
const SITECORE_IDENTITY_URL = 'https://auth.sitecorecloud.io/oauth/token';
const GRAPHQL_ENDPOINT = process.env.SITECORE_AUTHORING_ENDPOINT ?? '';
- We import Next.js types for API routes.
- We set up environment variables for authentication.
- We define the Sitecore authentication endpoint and GraphQL endpoint.
Creating the API Handler Function
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method Not Allowed' });
}
// Implementation will go here
}
- We define an async function that handles API requests
- We ensure only POST requests are accepted, returning a 405 error for other methods
Authentication with Sitecore
try {
// Step 1: Get auth token
const tokenRes = await fetch(SITECORE_IDENTITY_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
audience: 'https://api.sitecorecloud.io',
}),
});
const tokenData = await tokenRes.json();
if (!tokenRes.ok) throw new Error(tokenData.error_description || 'Failed to get token');
const accessToken = tokenData.access_token;
- We make a
POST
request to Sitecore's authentication endpoint. - We use the client credentials flow with our client ID and secret.
- We parse the response to extract the access token.
- We handle potential authentication errors.
Publishing Content with GraphQL
The Sitecore Authoring and Management GraphQL API provides a good amount of mutation options that will fit into different objectives. Checkout some of their examples here. In the query below we are using publishItem
, which should function similarly to the publish function available on the editors.
// Step 2: Publish item using GraphQL
const graphqlQuery = {
query: `
mutation {
publishItem(
input: {
languages: ["en"]
rootItemPaths: [
"/sitecore/content/Blogs"
]
targetDatabases: "experienceedge"
publishItemMode: SMART
publishRelatedItems: false
publishSubItems: true
}
) {
operationId
}
}
`,
};
const graphqlRes = await fetch(GRAPHQL_ENDPOINT, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(graphqlQuery),
});
const result = await graphqlRes.json();
Handling the Response
The rest of the code basically deals with what to do with response and handling any errors.
if (result.errors) {
return res.status(500).json({ error: result.errors });
}
return res.status(200).json({ result: result.data.publishItem });
} catch (error) {
console.error(error);
res.status(500).json({ error: (error as Error).message || 'Unexpected error' });
}
Scheduling with Vercel Cron Jobs
With the Next.js API route created and deployed, scheduling it is straightforward using Vercel Cron Jobs:
- Define the Cron Job: Add a crons configuration to your vercel.json file in the root of your project.
- Specify Path and Schedule: Point the path to your API route (e.g.,
/api/publish-content
) and define the schedule using standard cron syntax.
// vercel.json
{
"crons": [
{
"path": "/api/publish-content",
"schedule": "0 8 * * *" // Runs every day at 8:00 AM UTC
}
// Add more cron jobs if needed
]
}
The schedule 0 8 * * *
means the job runs at 0 minutes past the 8th hour, every day, every month, every day of the week (i.e., 8:00 AM UTC daily). Adjust the schedule to fit your requirements. You can use tools like crontab.guru to help generate cron expressions.
Deploy your Next.js application to Vercel. Vercel will automatically detect the crons configuration and schedule the job.
Streamlining Your Content Workflow with Automated Publishing
While Sitecore doesn’t offer built-in scheduled publishing, its powerful Authoring and Management GraphQL API provides the necessary tools for developers to implement this crucial functionality. By creating a simple Next.js serverless function and leveraging a scheduler like Vercel Cron Jobs, you can build a robust, automated publishing workflow. This not only saves valuable time and reduces manual errors but also ensures your content reaches your audience consistently and reliably, directly addressing a common pain point for content teams. This approach highlights the flexibility of Sitecore’s platform and the power of modern web development practices.