
In a multi-brand setup, you might host one site in Umbraco and another site in a different CMS. You want consistent, up-to-date FAQ items across all brands. Whenever an FAQ is updated in the other system, we automatically push that change into Umbraco so both sites stay in sync without manual work.
How this works with the Umbraco Management API
When the other CMS, such as a site running on a different platform like Sitecore, saves or modifies a frequently asked question, it triggers a webhook that sends the updated data in JSON format. Our .NET application processes this payload and uses the Umbraco Management API to update the corresponding FAQ content node in Umbraco.
The Management API provides a secure way for external systems to interact with Umbraco through HTTP requests, authenticated using a Bearer token. This approach eliminates the need for special Umbraco NuGet packages or additional dependencies, allowing for a straightforward integration.
For more information on how to configure and work with the Management API, visit the official Umbraco Management API documentation.
Code example
Below is the core snippet from a .NET 9 minimal API (though you could use any language or version of .NET):
// -------------------------------------------------------------------------
// Configuration - Umbraco
// -------------------------------------------------------------------------
string umbracoHost = "https://localhost:44392";
string umbracoClientId = "umbraco-back-office-my-client";
string umbracoClientSecret = "umbraco-client-secret";
string umbracoFaqDocId = "e75d2a2b-295c-48e6-bea0-f83c5100682b";
string umbracoTitleAlias = "title";
string umbracoTextAlias = "text";
// -------------------------------------------------------------------------
// Endpoint: Receive Sitecore Webhook -> Update Umbraco
// -------------------------------------------------------------------------
app.MapPost("/api/webhooks/sitecore", async (HttpContext context, ILogger<Program> logger) =>
{
// 1) Read the raw JSON body
var doc = await context.Request.ReadFromJsonAsync<JsonDocument>();
// 2) Parse JSON for Title/Text. You can get it from:
// - "Item.VersionedFields"
string? titleFromSitecore = null;
string? textFromSitecore = null;
// Look in "VersionedFields" array
if (doc.RootElement.TryGetProperty("Item", out var itemElem) &&
itemElem.TryGetProperty("VersionedFields", out var versionedFieldsElem) &&
versionedFieldsElem.ValueKind == JsonValueKind.Array)
{
foreach (var fieldElem in versionedFieldsElem.EnumerateArray())
{
if (!fieldElem.TryGetProperty("Id", out var fieldIdElem)) continue;
var fieldId = fieldIdElem.GetString() ?? string.Empty;
// Title field
if (fieldId.Equals("75577384-3c97-45da-a847-81b00500e250", StringComparison.OrdinalIgnoreCase))
{
if (fieldElem.TryGetProperty("Value", out var valElem))
{
titleFromSitecore = valElem.GetString();
}
}
// Text field
else if (fieldId.Equals("a60acd61-a6db-4182-8329-c957982cec74", StringComparison.OrdinalIgnoreCase))
{
if (fieldElem.TryGetProperty("Value", out var valElem))
{
textFromSitecore = valElem.GetString();
}
}
}
}
// 3) Update Umbraco using the parsed fields
var httpFactory = context.RequestServices.GetRequiredService<IHttpClientFactory>();
// (a) Acquire an Umbraco token (Client Credentials)
var umbracoToken = await GetUmbracoTokenAsync(httpFactory, umbracoHost, umbracoClientId, umbracoClientSecret);
// (b) Build the JSON for the Umbraco PUT
// We'll update "title" and "text".
var valuesList = new List<object>();
if (!string.IsNullOrEmpty(titleFromSitecore))
{
valuesList.Add(new
{
alias = umbracoTitleAlias,
value = titleFromSitecore
});
}
if (!string.IsNullOrEmpty(textFromSitecore))
{
valuesList.Add(new
{
alias = umbracoTextAlias,
value = textFromSitecore
});
}
var bodyObject = new
{
values = valuesList.ToArray(),
variants = new[]
{
new
{
name = "FAQ item"
}
}
};
var updateJson = JsonSerializer.Serialize(bodyObject, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
});
// (c) Send the PUT to Umbraco
var client = httpFactory.CreateClient();
client.BaseAddress = new Uri(umbracoHost);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", umbracoToken);
var content = new StringContent(updateJson, Encoding.UTF8, "application/json");
var response = await client.PutAsync($"/umbraco/management/api/v1/document/{umbracoFaqDocId}", content);
var responseBody = await response.Content.ReadAsStringAsync();
logger.LogInformation("Umbraco FAQ updated successfully");
return Results.Ok("Sitecore data used to update Umbraco successfully!");
});
// -----------------------------------------------------------------------
// Helper: Acquire a token from Umbraco Management API (Client Credentials)
// -----------------------------------------------------------------------
static async Task<string?> GetUmbracoTokenAsync(
IHttpClientFactory httpFactory,
string umbracoHost,
string clientId,
string clientSecret)
{
using var tokenClient = httpFactory.CreateClient();
tokenClient.BaseAddress = new Uri(umbracoHost);
var req = new ClientCredentialsTokenRequest
{
Address = "/umbraco/management/api/v1/security/back-office/token",
ClientId = clientId,
ClientSecret = clientSecret
};
var resp = await tokenClient.RequestClientCredentialsTokenAsync(req);
return resp.AccessToken;
}
You can view all the code in this Gist.
Key Steps:
- Read JSON from the Sitecore webhook: Use
ReadFromJsonAsync<JsonDocument>()
to parse the incoming payload. - Extract fields: Typically something like
properties.title
andproperties.text.markup
. - Obtain Token: Use a simple client-credentials request to
POST /umbraco/management/api/v1/security/back-office/token
. - PUT to Umbraco: Call
PUT /umbraco/management/api/v1/document/{guid}
with aBearer <token>
header.
When the request succeeds, Umbraco’s FAQ content node, for example "How do I reset my password?", is updated with the new text from the external system.
Short demo video
In the demo, you’ll see how content synchronization works between Sitecore and Umbraco using the Sitecore Authoring API and the Umbraco Management API: https://youtu.be/QHxpJ2EozBU
Conclusion
We have synchronized an FAQ into Umbraco without relying on any official Umbraco NuGet references. This can be done in .NET 9, Node.js, or any environment that can read JSON and perform HTTP requests. It is a real-time approach that keeps FAQs in sync for multi-brand sites with minimal overhead.
For the other direction, see how content edits in Umbraco can be synced back to Sitecore using the Sitecore Authoring API:
Seamless Sync: Updating Sitecore Using the Authoring API.