Only this pageAll pages
Powered by GitBook
1 of 60

Umbraco Heartcore

Loading...

Loading...

Loading...

Getting Started

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

API Documentation

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Backoffice

Loading...

Client Libraries

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Tutorials

Loading...

Loading...

Loading...

Release Notes

Loading...

Loading...

Loading...

Loading...

Loading...

What is Umbraco Heartcore?

Umbraco Heartcore is a headless Software As A Service (SAAS) offered by Umbraco. The service enables you to create and manage content and media in the Umbraco backoffice and make it available to any platforms, devices, channels and so forth.

All Umbraco Heartcore projects include a Content Delivery Network (CDN) using CloudFlare. This CDN is used for caching content and media fetched through the Content Delivery API. Additionally, the media CDN (media.umbraco.io) allows for resizing and cropping options, which improves both performance and stability.

There are 3 ways to get your hands on an Umbraco Heartcore project:

In this section, you will find documentation on how to work with Umbraco Heartcore.

It includes REST API documentation, the basics of how to get started, and how to work with the available Client Libraries. Please note that Umbraco Heartcore is a specific type of project only available via Umbraco Cloud.

Reference documentation for the APIs available, as well as details about common HTTP headers, versioning, REST Standard, and how to work with authentication and authorization.

GraphQL

Reference documentation and tutorials for the GraphQL API.

Learn more about how we handle versioning and updates of Heartcore projects.

Backoffice Users and API Keys

Managing Umbraco Heartcore Users and API keys

In this article you will learn how to add Users to the backoffice and how to manage the API Keys.

The Backoffice User

A Backoffice user can be added in two ways.

  • Added from the portal from the Team Management section, or

  • From the Users Section in the Backoffice

A feature that is unique for Umbraco Heartcore is the option to create an API Key for specific users. The API Key can be created from the API Key section of the User page. This page can be found under the Users Section in the top-left navigation of the backoffice.

API Keys

By default, the Content Delivery API is public, if you would like to protect it you can do so in the "Settings" section and "Headless" tree.

If your Content Delivery API is protected or you want to use Content Management APIs, your user will need to have an API Key assigned. When you have navigated to the Users section mentioned above you can create the API Key by clicking the "Create API Key" button.

A modal will pop up where you enter the name of the key and set a date for when it should expire. If there is no expire data, the API Key will be valid until you delete it manually.

Once the API Key has been created you will see the actual key and two examples on how to use the key with the Authorization header and an API-Key header.

You are able to see a list of all your created API Keys and all relevant information. You are also able to revoke a generated key.

You can read more about all the features and benefits on the . You can also look at the pricing, plans, and features on the page.

- requires that you already have an account

Do you have questions that are not covered by this documentation? Please create an issue on our or get in touch with Umbraco Support using the chat in the portal or write a mail to support@umbraco.com.

API Documentation
GraphQL API
Deployment workflow
Umbraco Heartcore product page
Umbraco Heartcore Pricing
Take a 14-day free trial
Purchase a Heartcore from Umbraco.com
Setup a project directly from the Umbraco Cloud Portal
API Documentation for the Umbraco Heartcore REST API endpoints
Content Delivery API
Content Management API
GraphQL API Documentation
Versions and updates
Frequently asked questions
Documentation Issue Tracker

Compare with Umbraco CMS

Differences between Heartcore and Umbraco CMS

There are some differences between Heartcore and Umbraco CMS.

Managed Upgrades

With Umbraco Heartcore you won't need to worry about upgrading your project.

As Heartcore is a SasS product, we manage upgrades for your Heartcore project.

Template section

Umbraco Heartcore is a headless offering, meaning the frontend is decoupled from the backend. It is not possible to create templates in Umbraco Heartcore and the section is not available.

Custom Grid Editor

In Heartcore, the Grid editor is working a bit differently compared to the CMS. To see how to work with the Grid editor in Heartcore, have a look at the Creating a Custom Grid Editor Tutorial.

Environments

In this article, you can learn more about how to work with environments on your Umbraco Heartcore project.

Having multiple environments means that you have a place to test both your content and the content structure before deploying it to the production environments, from where the content is served to your application.

What is an environment?

An environment on a Heartcore project can be defined as a workspace and is at the same time a Git repository. When you have more than one environment on your project, these environments will act as branches of the main repository.

Umbraco Heartcore uses a deployment model that relies on Git and other core technology, which gives you the option to move both content and structure files from one environment to another.

Manage environments

When you upgrade your Heartcore project from the Starter to the Standard plan, it will be possible to add a Development environment. Once you've upgraded to the Professional plan, you will be able to add the Staging environment as well.

You can add and remove the environments any time you want, as long as you have multiple environments enabled.

Adding and removing environments is done from the Project page in the Cloud Portal.

Please note you will need to restart environments after they have been set up or removed from your project. This is to ensure that the Umbraco Deploy configuration is updated.

Below is a screenshot of how the project page looks on the standard plan with only the Live environment. There's an option to add a Development environment. How this page looks is dependent on the plan your project is using.

Setup

You can set up a new project with a few clicks through the .

Your project will then be up and running within a couple of minutes.

Packages

Heartcore comes out of the box with installed on the starter plan and above.

It is however not possible to install other packages in Umbraco Heartcore as the code base is Closed source.

Instead, other features like GraphQL, an out-of-the-box Content Delivery Network (CDN) by Cloudflare, and a Preview API are available in Umbraco Heartcore.

Special property aliases

Some can manipulate the standard Umbraco routing pipeline in the Umbraco CMS.

Since the frontend and backend of Umbraco Heartcore are decoupled, it's not possible to use these aliases in Umbraco Heartcore.

The aliases are:

  • umbracoRedirect

  • umbracoInternalRedirectId

  • umbracoUrlAlias

The umbracoUrlName property type alias works correctly in Umbraco Heartcore.

Learn more about the deployment model in the.

How many environments you can work with depends on the your Umbraco Heartcore project is running.

Umbraco Cloud Portal
Umbraco Forms
special property aliases
Deployment workflow article
plan
How to create a Heartcore Trial
Umbraco Heartcore: API keys

GraphQL Playground

Documentation for Umbraco Heartcore GraphQL Playground.

With the GraphQL query language, you will be able to limit the amount of data transferred to and from your Heartcore instance and the client by specifying exactly what kind of information you would like to get in your API calls.

You can test and build GraphQL queries directly in the backoffice-integrated GraphQL Playground.

In the Settings section in the Umbraco Backoffice, you will find the Headless tree. From there you can use the GraphQL Playground to test your queries against your project's schema.

The Playground comes with basic features such as real-time error highlighting, syntax highlighting, formatting, query history and more.

Accessing GraphQL Playground

  1. Log into the project backoffice

  2. Navigate to the Settings dashboard

  3. Find the Headless tree near the bottom of the navigation list

  4. Click on GraphQL

From there, you can start querying as soon as your content is published.

Features

Documentation & Schema

The GraphQL Playground's build-in documentation and schema browser can be found on the left toolbar

This button will open a panel that grants you a quick overview of how content is structured using the Document Types in your solution.

It also gives an idea of how to access specific properties on each Document Type, nested properties, and properties from compositions.

At the same time, it also explains relationships between specific objects and properties in your solution.

This will be updated automatically as you change the project's schema meaning Document Types, Data Types, Document Type Compositions, and Document Type Elements.

Running GraphQL queries

To run a query use the left side of the GraphQL Playground to type in your query - could be something as basic as getting the names of all your content pages:

{
  allContent {
    items {
      name
    }
  }
}

The Heartcore GraphQL endpoint only supports queries - other operation types, that is mutations and subscriptions, are not supported.

After that, press the "Play" button sitting in the center of the Playground. If the query is constructed correctly, the results will be loaded into the right section.

When you are satisfied with the result, you can copy the client URL (CURL) by clicking the COPY CURL button located in the top part of the Playground, next to the address bar.

Sending HTTP headers

GraphQL Playground supports requests with HTTP headers if an authorization token is needed. The HTTP HEADERS section can be accessed from the bottom-right corner of the Playground window. By default, it contains the umb-project-alias header, the alias of your Heartcore project. It is possible to add multiple headers.

Query variables

It is also possible to define variables for queries - such variables's values can be changed in the bottom-left corner of the Playground window, next to the HTTP HEADERS section.

History

If you happen to make an amazing query and afterward erase it by accident, you can re-use it by finding it in the History.

The History pane can be opened by clicking the history button in the toolbar to the left.

Prettify

The Playground gives you an option to "prettify" your query with a click of a button, which makes it easier for humans to read.

Persisted Queries

Create a new persisted query

  1. Click the Create Persisted Query button

  2. Enter a name for the query in the new query editor that appears

  3. Write your query in the editor

  4. Click the Save button

Update a persisted query

  1. Find the query you want to update in the persisted queries list

  2. Click on the name of the query

  3. Make your changes in the editor that appears with the query

  4. Click the Save button

Delete a persisted query

  1. Find the query you want to delete in the persisted queries list

  2. Click on the name of the query

  3. Click the action menu in the top right corner of the editor with the query

  4. Click the Delete button

  5. Confirm the deletion

Preview

Prerequisites

You will also need a client consuming the Content Delivery API. If you don't already have one you can use one of the samples included with the Client Libraries.

Enabling preview for editors

To make it easier for your editors to access the preview version of you website, you can add a Preview button to content nodes in the backoffice.

This can be done by going to the Settings section, expanding the Headless item and clicking on Preview.

Here you'll get an overview of the preview urls created.

Right now the list is empty, so go ahead and click on Add Preview Url

This will open up a dialog on the right side of the backoffice, from where you can select which Root Content the preview url should be assigned to, and for which language it should be available for.

The Name field is used when there are multiple Preview Urls for a Content item.

Path Type controls how the path should be appended to the url, there are 3 different options.

  • Append path to url: this will append the path of the Content item to the end of url.

  • Path in querystring: this will add a querystring parameter to the url containing the path of the Content item.

  • Id in querystring: this will add a querystring parameter to the url containing the id of the Content item.

Default controls whether this url is the default one when clicking the Preview button.

After you click save you'll return to the overview where the configured urls is shown. From here, you can edit or delete them.

Now if you go back to the Content section and click on the node you selected as the Root node or one of its child items, you should now have a Preview button in the bottom right section of the screen.

If multiple urls have been added for the Content item, there will be an arrow next to the button. When clicked, it will show all the Preview Urls available.

Accessing the Preview API

Now that we have setup the backoffice, we need to update our site to use the Preview API.

The Preview API is always protected and requires an API Key to be passed with the request.

If you are using the GraphQL API a preview argument can be passed to the root query fields.

query {
  allContent(
    preview: true
  ) {
    edges {
      node {
        name
      }
    }
  }
}
import {Client} from '@umbraco/headless-client'

const client = new Client({
  projectAlias: 'your-project-alias',
  apiKey: 'your-api-key',
  language: 'iso-code',
  preview: true,
})
using Umbraco.Headless.Client.Net.Delivery;

class Program
{
    static async Task Main(string[] args)
    {
        var previewService = new ContentPreviewService("your-project-alias", "your-api-key");
    }
}

To test that you get draft content back try changing the name of a Content item in the backoffice and click on Save, the change should now show up on your preview site but not on the live site.

Tour of the Backoffice

Tour of Umbraco Heartcore backoffice

In this article you will get an introduction to the different sections in the Umbraco Backoffice.

Login screen

When you go to the backoffice of your Umbraco Heartcore project you will be asked to log in.

From here you are able to log in with the credentials used when the project was created.

Sections

The backoffice is divided into specific sections for example Content, Media and Settings. This will allow you to do work related to a specific section of your project.

The sections menu is located in the top-left corner of the screen.

Section Tree

Every section has a section tree that gives you an overview of the content you have in each section.

Folders and nested content can be expanded by clicking the arrow next to the node. This can also be done by double-clicking on the node.

Nodes

Every item you have is considered a node. It could be a media item or content in the content section.

Dashboard

Every section in the Umbraco backoffice has one or more dashboard associated with them. The first thing you will see when accessing the backoffice on your Umbraco Heartcore project is the "Getting Started" dashboard. Here you can find links to news and resources useful to your project.

Content

In this section you will find all the content you have on your page. Each item in the tree is called a Content Node. Every node is made up by different fields. Each field is defined by a property.

The content tree holds all the content nodes you have created.

The left holds the content tree that will automatically nest your content if you have created nodes with parent-child relationships.

On the left you can see what properties the highlighted Content Node has. In the above example there is a group called Main which holds a few properties. By clicking on the Info tap you will be able to see some useful information for the specific Content Node.

At the top you can see the automatically generated URL to the specific Content Node. Below you also get a handy history overview that shows who has done what at what time. Lastly you can see some general information such as Status, Creation Date and a direct link to the Document Type. You can edit it without leaving the current view.

Lastly you can either Save, Save and publish, Schedule a publication or unpublish the Content Node. You can change the action by clicking the small up arrow next in the green button in the lower right corner.

Media

Media items are used to store images and videos in the Media section. These items can be referenced from your content. You are also able to create folders in the Media section to keep all your Media Items sorted.

A handy feature is that if you have a Media Picker in your Content Node and you upload an image. This image will automatically be added in the Media Section.

Settings

In the settings section you find the before mentioned Document Types, Data Types and Media Types among other settings that will be covered below.

Document type

Document Types defines the content nodes the editors can create in the Content section. A Document Type has a set of properties that is made up of specific Data Types like text or a numbers. A property is the fields that holds the content in a content node that can be edited by the content editor.

Media Types

What differs from Document Types is that Media Types are specifically made for media items in the Media section.

Member Types

When you have a website with a login you might want to create Member Types. Umbraco comes with a standard Member Type. You can extend of this, but you can also create your own type for more customized members.

Data Type

Each Document Type property consists of a Data Type which defines what kind of input the property holds. Each Data Type references a Property Editor and can be configured in the Settings section of the Backoffice. A Property Editor can be anything from a basic number to something more complex like an image-cropper. It is possible to have multiple Data Types with different settings that still uses the same Property Editor.

Relation Types

In this section, you can establish two-way relationships for querying both parent-to-children and children-to-parent connections.

Log Viewer

The log viewer is a view where you can browse all log entries for your project. You can filter on warnings, errors or critical Log Types to name a few.

Languages

In the Languages section you can manage your language variants. Depending on what plan you have chosen you will be able to setup multiple languages on your Heartcore project.

Headless

The headless dashboard has some information about your Heartcore project. Depending on what plan you are on, you will have access to more languages and user groups.

The dashboard shows you:

  • What plan you are on

  • How many available languages you have

  • How many user groups you have

From the Headless tree you can browse and explore the REST API endpoints as well as create and manage your Webhooks.

Users

In this section you can manage all the users that are currently working on the project. Users are not to be confused with Members. Members are people who have a login to your website's frontend. Users can be developers, content creators, and so on, who have access to the backoffice.

You can segment your users into different User Groups. You can add Users to existing Groups or create your own custom User Groups. How many of these groups you can create depends on the plan your project is on.

Members

The Members section is where you manage your members who are able to log into your projects frontend. You can create Member Groups for management if you have multiple types of memberships.

Forms

In this section you can create and manage your Umbraco Forms.

API Documentation

Documentation for Umbraco Heartcore REST APIs

This page contains documentation for the available API endpoints for Umbraco Heartcore. It includes endpoints for the GraphQL API as well as for the REST API which is divided into two main areas: Content Delivery and Content Management.

The Preview API is the read-only Content and Media that you would retrieve to show the draft content in your apps, websites, or other platforms. The API is available on https://preview.umbraco.io. The Preview API is always protected and requires an Api-Key. The endpoints are the same as the Content Delivery API.

REST API Standard

System level properties

The properties in the REST API, which starts with an underscore, are system level properties. That means that they are standard Umbraco properties, which cannot be changed via the API. This includes properties like _id, _url, _createDate, _updateDate, _creatorName, _writerName, _level and _hasChildren. These are all defined by Umbraco when Content is created or updated.

The properties _links and _embedded are both part of the HAL specification and are implemented in the REST API accordingly.

API Browser

In the Settings section in the Umbraco Backoffice, there is a Headless tree. From there you can use the API Browser to interact with both the Content Delivery and Content Management APIs.

It is recommended to use this browser to explore the JSON output for all the different endpoints documented under the Content Delivery and Content Management API sections.

Common API Features

Both the Content Delivery and the Content Management APIs share common points of configuration for access, versioning, culture and authentication/authorization, which are highlighted below.

API Access

In order to access the data for your Umbraco Heartcore project you need to provide a project identifier (Project Alias) via a HTTP Header or a Querystring parameter.

The Project Alias is a HTTP friendly version of the Project Name under your Umbraco Cloud account.

Access via Umb-Project-Alias header

Access via Query String parameter

Versioning

All API requests need to specify the API version they target. If no version is specified, the latest version of the API is used, which will break clients when a new version of the API is released.

Access via an api-version header

Access via Query String parameter

Access via Content negotiation

Authentication and Authorization

By default the Content Delivery API is not protected, it can be enabled through the backoffice. The Content Management API is always protected and requires either an API key or a bearer token.

Since both API keys and bearer tokens are created for a specific user their permissions can be set on that user in the backoffice.

API Keys

API keys can be managed for a user through the backoffice.

Access via the Authorization header

When using the Authorization header the API key must be passed in as the username and the password must be left empty. The value must be base64 encoded e.g. base64(api-key:)

Access via an Api-Key header

Bearer token

The endpoints implement OAuth 2.0.

A bearer token can be created by posting to https://api.umbraco.io/oauth/token and supplying a username and password for a backoffice user. This corresponds to a user logging into the backoffice and is thus only meant to be used for the Content Management API.

It can be used by passing it to the Authorization header.

Member authentication

A member login can be used to access the Content Delivery API if it's protected. Members will only have access to Content Delivery Network (CDN) endpoints and cannot be used to access the Content Management API.

Content can be restricted further by using the Public Access feature in Umbraco to only allow access for specific Members or Member Groups.

Do note that you will need an API key header if the Content Delivery API cdn.umbraco.io is set to protected via the backoffice.

Member Bearer token

The endpoints implements OAuth 2.0.

A bearer token can be created by posting to https://cdn.umbraco.io/member/oauth/token and supplying a username and password for a member.

It can be used by passing it to the Authorization header.

Webhooks

Webhooks give you the ability to send information about events in Heartcore to external systems. They work by sending an HTTP POST request to a configured endpoint, with information about the event in the request body.

Uses

Webhooks can keep other systems in-sync with content from Heartcore without having to poll it for changes.

One common use case is building static websites. By adding a webhook, you can inform your chosen static site builder when content changes so that it can re-generate static assets on demand.

Creating a webhook

Webhooks are managed from a dashboard in the settings section of the backoffice.

  1. Go to the Settings section.

  2. Expand the Headless folder in the Settings tree.

  3. Click Create Webhook.

  4. The Add webhook menu opens on the right side.

  5. Enter the URL that the webhook should call.

  6. Select the Event for which the webhook should be triggered.

Selecting the Content Type is the initial step. This field is not mandatory.

  1. Click Create.

Once the webhook has been created you can manage it from the dashboard.

To temporarily pause/disable the webhook, click on Edit and toggle the Enabled field.

Webhook Configuraiton

Below is an overview of the webhook configuration options.

  • Url

    The URL that Heartcore will send a POST request to when conditions are met.

  • Events

    Backoffice or Management API action(s) that will cause the webhook request to be sent.

  • Content Type (optional)

    Restrict the webhook to firing only if one of these content or media types were affected by one of the selected events.

  • Enabled

    Toggle the webhook on or off. While disabled, no requests will be sent.

  • Headers

    Configure custom HTTP headers to be sent with the request. May be useful for e.g. identifying the source of a request or for authorization.

Webhook behaviour specifics

Retries

When a webhook is triggered, if it fails to be processed by the endpoint Heartcore attempts to re-deliver it up to 9 more times.

  • The endpoint returned a non HTTP-compliant response

  • The endpoint returned an HTTP response with any status code other than a successful one (HTTP 200 - 299)

  • The endpoint failed to respond within a timeout period

Redelivery

Webhooks are guaranteed to be delivered at least once. I.e. even for a webhook that is delivered successfully, in some situations that hook may be re-delivered.

Your webhook endpoints should thus be capable of handling multiple deliveries. Ideally they are idempotent.

Unresponsive endpoints

If an endpoint is slow or unresponsive, then webhook delivery may be briefly paused to that endpoint. No messages will be dropped (unless the retry count has been exceeded), but messages will be rescheduled for delivery a short time later. This gives the endpoint room to recover from traffic spikes.

Outgoing IP addresses

Webhooks will be fired from either of the two static IP addresses listed below.

When your endpoint refers to a service behind a firewall, you may need some additional firewall configuration. You should ensure that HTTP traffic from these addresses is allowed to pass through the firewall:

Or if your firewall needs a Classless Inter-Domain Routing (CIDR) Range: 20.86.53.156/31

To learn more about querying, visit our .

The Graphql playground supports . To access Persisted queries you have to go to the and click the persisted queries tab

In this article you will get an overview of the Preview functionality in Umbraco Heartcore and how to use it with our.

The Preview API is always protected, this means it requires an API Key with Browse Node permission to be able to access it. If you don't already have an API Key ready, head over to to learn how to create one.

The Preview feature is currently only available on the .

The Preview API is available on https://preview.umbraco.io and its endpoints are identical to the, meaning that you can swap the url out if you don't use one of our Client Libraries.

If you are using theyou set preview: true, set an apiKey as shown below, this switches all of the client.delivery functions to use the Preview API instead of the Content Delivery API.

For the you'll create a new instance of the Umbraco.Headless.Client.Net.Delivery.ContentPreviewService. It's based on the IContentDeliveryService interface, which the ContentDeliveryService also implements.

In addition you are able to set the Content Delivery API to either Public or Private. If the API is private, you must have an to fetch content from it.

API Browser: In the API Browser you can test your API endpoints. Learn more about this in the .

Webhooks: You can create and manage Webhooks for content actions. Learn more about how this is setup in the.

For each user on your project you can generate a unique API key. This key will be used to access the Content Management API, and can be revoked at any time. Learn more about the API Keys in the

can be used to query the read-only Content that you would normally retrieve to show the published content in your apps, websites, or other platforms. The API is available on https://graphql.umbraco.io. This API is available on Trial projects as well as Starter and Professional Plans.

is a read-only Content and Media API that you would normally retrieve to show the published content in your apps, websites or other platforms. The API is available on https://cdn.umbraco.io.

can be used to Create, Read, Update and Delete Content, Media, Languages, Relations, Members, and the associated types using Umbraco Backoffice user credentials or API Keys. The API is available on https://api.umbraco.io.

The REST APIs are based on the .

API versioning is handled by .

This feature is currently not available when using

Select Webhooks.

Choose a Content Type you wish the webhook to be triggered on.

API documentation for GraphQL
Client Libraries
Backoffice Users and API Keys
Standard Plan
Content Delivery API
Node JS Client
.NET Client
persisted Graphql queries
GraphQL Playground
GET https://cdn.umbraco.io/content
Umb-Project-Alias: project-alias
GET https://cdn.umbraco.io/content?Umb-Project-Alias=project-alias
GET https://cdn.umbraco.io/content
api-version: 2
GET https://cdn.umbraco.io/content?api-version=2
GET https://cdn.umbraco.io/content
Accept: application/json+hal;v=2
GET https://api.umbraco.io/
Authorization: Basic {base64-encoded-string}
GET https://api.umbraco.io/
Api-Key: {api-key}
POST https://api.umbraco.io/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=password&username={username}&password={password}
GET https://api.umbraco.io/
Authorization: Bearer {token}
POST https://cdn.umbraco.io/member/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=password&username={username}&password={password}
GET https://cdn.umbraco.io/
Authorization: Bearer {token}
Authentication and Authorization
20.86.53.156
20.86.53.157
assigned API key
API Browser article
Webhooks article
Backoffice users and API keys article.
The GraphQL API
The Content Delivery API
The Content Management API
HAL Standard
ASP.NET API Versioning
External Login Providers.

Content and media transfer / restore

While structure changes are deployed between environments using the Cloud Portal, content and media transfers and restores are handled through the Umbraco Backoffice.

In order to be able to transfer/restore content and media, you need to make sure that the environments you're transferring between are in sync.

Another difference between the two steps, is that content and media can be restored against the left-to-right flow. This means that when you have a lot of content on a Live environment, it is possible to restore all this content on a Development and/or Staging environment.

The screenshot above is from the Content section on a Development environment. Right-click the Content tree to open the menu as shown in the screenshot.

Queue for transfer gives you the option to queue all content in the Content tree for transfer to the next environment (Staging or Live). It is also possible to right-click single nodes in the content structure in order to only queue some of it for transfer.

Restore gives you the option to restore all content from environments right of the current environment. In some cases you might not want to restore all content as once, in which case you should use the Partial restore option instead. Partial restore can be found by right-clicking a node in the content tree.

Content Delivery

Documentation for Heartcore Content Delivery APIs

This is the read-only API for delivering published content and media to any app, website, device or platform.

It’s worth noting that the JSON output for both Content and Media vary depending on how a given ContentType or MediaType is defined.

Cultures

Specific to Content in the Content Delivery API.

To request content in a specific language, a culture parameter can be specified. When no culture is specified its treated as invariant and the default language will be returned.

Access via an Accept-Language header

GET https://cdn.umbraco.io/content
Accept-Language: en-US

Acces via a Query String parameter

GET https://cdn.umbraco.io/content?culture=en-US

Content endpoints for retrieving specific content by ID or URL. It is also possible to retrieve children, descendants and ancestors structured according to the Content tree structure.

Media endpoints for retrieving specific media by id. It is also possible getting children of a media folder structured according to the Media tree structure.

Learn more about how to do that, in the article.

Structure deployments
Content endpoints
Media endpoints

Redirect API

This is the read-only API for delivering redirects, caused by moving or renaming content in the Umbraco backoffice, to any app, website, device, or platform.

Cultures

To request redirects in a specific language, a culture parameter can be specified. When no culture is specified it's treated as invariant and the default language will be returned.

Access via an Accept-Language header

GET https://cdn.umbraco.io/redirect
Accept-Language: en-US

Access via a Query String parameter

GET https://cdn.umbraco.io/redirect?culture=en-US

Common Headers

Accept-Language: {culture}
Api-Version: 2.3
Umb-Project-Alias: {project-alias}

Errors

If an error occurs, you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

400

AmbiguousCulture

The following cultures were requested: {cultures}. At most, only a single culture may be specified. Please update the intended culture and retry the request.

400

LanguageForCultureNotFound

Could not find a language for culture {culture}.

401

Unauthorized

Authorization has been denied for this request.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "LanguageForCultureNotFound",
    "message": "Could not find a language for culture en-GB."
  }
}

Get all redirects

Get all redirect URLs.

The key is the URL of the content and the values are the URLs redirecting to the content.

URL: /redirect

Method: GET

Query Strings

?page={integer=1}
?pageSize={integer=10}

The maximum page size is 1000.

Success Response

Code: 200

Content Example:

{
    "redirects": {
        "/root5/": [
            "/root4",
            "/root3",
            "/root2",
            "/root"
        ],
        "/root5/child/": [
            "/root4/child",
            "/root3/child",
            "/root2/child",
            "/root/child"
        ]
    },
    "_totalItems": 2,
    "_totalPages": 1,
    "_page": 1,
    "_pageSize": 10,
    "_links": {
        "self": {
            "href": "https://cdn.umbraco.io/redirect?page=1&pageSize=10"
        }
    }
}

Get content by redirect URL

Get the destination URL and redirect URLs for a given path.

URL: /redirect/redirecturl?url={url}

Method: GET

Success Response

Code: 200

Content Example:

{
    "url": "/home",
    "redirectUrls": [
        "/home-redirect-example-1",
        "/home-redirect-example-2"
    ]
}

Media Types

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Get all Media Types

Get a list of all available Media Types.

URL: /media/type

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Get by alias

Get a specific Media Type by its alias.

URL: /media/type/{alias}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Umbraco Forms

BASE URL: https://api.umbraco.io

API version: 2.1

Table of Contents

Common Headers

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occurs you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Field types

The field types gets mapped to a more machine friendly name

Get forms

Gets all forms.

URL: /forms

Method: GET

Permissions required : Access to Forms section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Get by ID

Get a specific form by its ID.

URL: /forms/{id}

Method: GET

Permissions required : Access to Forms section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Submit entry

Submit form entries for a specific Form - this is what you would use when a form is submitted from your presentation layer.

URL: /forms/{id}/entries

Method: POST

Permissions required : Access to Forms section of the Umbraco Backoffice

Request

The JSON property names are the form field alias

Success Response

Code: 202

Content

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Authentication

Authentication is required for this API. This means that you must supply a Bearer Token via an Authorization header. Alternatively, you can supply an API Key via an Authorization or Api-Key header.

Permissions

In addition to the specific permissions listed under each endpoint, all requests requires:

  • Access to the Content Section of the Umbraco Backoffice and

  • That the content being accessed is beneath the users start node configured in Umbraco

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Get root content

Get all content at the root of the tree, which the authorized user has access to according to the 'Start node'-permissions.

URL: /content

Method: GET

Permissions required : Browse Node

Success Response

Code: 200

Content Example:

Get by id

Get specific content item by GUID ID. Includes all language variations.

URL: /content/{id}

Method: GET

Permissions required : Browse Node

Success Response

Code: 200

Content Example:

Get children

Get a list of children (content items) by parent GUID ID. Includes all language variations per content item.

URL: /content/{id}/children

Method: GET

Query Strings

Permissions required : Browse Node

Success Response

Code: 200

Content Example:

Create content

Create a new content item with one or more language variations.

All newly created content will be DRAFT by default. If you want to publish it you will need to issue a publish request as well.

URL: /content

Method: POST

Permissions required : Create

Request

In this example only one language exists, so the properties are marked with $invariant in the create request. If multiple languages exists the culture for each of the languages would be defined for each of the properties - example: "name": { "en-US": "Another one", "da-DK": "Endnu en" }.

Success Response

Code: 201

Content Example:

Create content with files

Create a new content item with one or more language variations and files.

When content contains an upload field it is possible to send a file along with the request to create new content. This is done by sending a multi-part request with the JSON body and the file.

If the content item doesn't include files then you can send a standard reqeust with a JSON payload to create a new content item.

All newly created content will be DRAFT by default. If you want to publish it you will need to issue a publish request as well.

URL: /content

Method: POST

Header: Content-Type: multipart/form-data; boundary=MultipartBoundry

Permissions required : Create

Request

The request must contain a field named content that contains the content JSON.

For the files being uploaded the field names must be in the format propertyName.culture. An example could be when the content has an upload property with the name fileUpload and the file is being uploaded to the en-US lanugage. In that case the field name should be fileUpload.en-US.

The property must also be includud in the content JSON and the value shoud be the filename.

Success Response

Code: 201

Content Example:

Update content

Updates an existing content item that has one or more language variations.

URL: /content/{id}

Method: PUT

Permissions required : Update

Request

In this example only one language exists, so the properties are marked with $invariant. If multiple languages existed the culture for each of the languages would be defined for each of the properties. Ie.: "name": { "en-US": "Another one", "da-DK": "Endnu en" }.

Success Response

Code: 200

Content Example:

Publish content

Publish specific content item with all language variations or for a specific language.

URL: /content/{id}/publish

Method: PUT

Query Strings

Permissions required : Publish

Success Response

Code: 200

Content Example:

Unpublish content

Unpublish specific content item with all language variations or for a specific language.

URL: /content/{id}/unpublish

Method: PUT

Query Strings

Permissions required : Unpublish

Success Response

Code: 200

Content Example:

Delete content

Delete a specific content item with all its language variations.

URL: /content/{id}

Method: DELETE

Permissions required : Delete

Success Response

Code: 200

Content Example:

DELETE https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7

Content Types

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Authentication

Authentication is required for this API. You must supply a Bearer Token via an Authorization header or an API Key through an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Get all Content Types

Get a list of all available Content Types.

URL: /content/type

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Get by alias

Get a specific Content Type by its alias.

URL: /content/type/{alias}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Content Management

Documentation for Heartcore Content Management APIs

This is the management API for creating, updating and deleting content, media, languages, relations, members and member groups. It also allows you to retrieve content drafts as well as Content Types, Media Types and Member Types.

Common for the Content Management API is that you must be authenticated and authorized when performing any action against the endpoints listed below. This means that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Content endpoints for retrieving, creating, updating and deleting.

Content Type endpoints for retrieving all available and specific content types. We also expose endpoints for publishing and unpublishing content.

Media endpoints for retrieving, creating, updating and deleting.

Media Type endpoints for retrieving all available and specific media types.

Language endpoints for retrieving, creating, updating and deleting.

Member endpoints for retrieving, creating, updating and deleting. We also expose endpoints for adding a member to member group and removing a member group from a member.

Member Group endpoints for retrieving, creating and deleting.

Member Type endpoints for retrieving all available and specific member types.

Relation endpoints for retrieving, creating and deleting.

Relation Type endpoints for retrieving specific relation types.

Umbraco Forms endpoints for retrieving and submitting forms.

API Browser

With the built-in API browser that ships with all Umbraco Heartcore projects, you are able to test how your data is outputted and formatted before connecting to your website or application. You can test the API endpoints and see which JSON is outputted with each call.

This article will cover how to use the API Browser in order to reap all the benefits of the feature. The API Browser can be used for both the Content Delivery API and the Content Management API.

The API Browser is located in the Settings section of the Umbraco backoffice. Expand the Headless dashboard in the Settings tree, and select "API Browser".

The user interface

Using the API Browser you can browse through the output for the various API endpoints. This is done from a UI, where on the left side you are able to explore the endpoints and on the right side you are able to inspect the output.

In the top-right corner you can switch between browsing in the Content Delivery or the Content Management API.

Explorer

The first thing you'll notice on the API browser, is an already defined URL. This is to define which area of the API you will be browsing; https://cdn.umbraco.io for the Content Delivery API and https://api.umbraco.io for the Content Management API.

You can also use the this field to manually add query strings to the URL and search the API endpoints that way.

The URL will be updated automatically as you browse the API using the links in the bottom of the Explorer section.

In the Custom Request Headers you can define which headers to use when browsing the API endpoints. The umb-project-alias header will have been added for you already, and in the content section the Accept-Language is also set by default.

The Properties will show you all the available properties on the object / piece of data that you are calling through the API.

Below the properties, is a section with a list of Links. These are links that you can use to make various GET requests from the endpoint you are already using.

The final section in the explorer is the Embedded resources. Here you can see the properties for each embedded resource on the endpoint you are calling, as well as links to continue browser the API based on each of those resources.

Inspector

In the right side, you'll find the inspector section. While exploring the API, you will see that information is being posted in the Response header and the Response Body boxes.

The first box, the Response Header, will show you the status of the API endpoint you are currently browsing and tell you which headers is included in the response.

In the Response Body box the raw JSON data will be output based on the API endpoint you're calling.

Status Code
Error Code
Message

The availability of Umbraco Forms depend on the plan. See the for an overview of which plans includes Forms.

Status Code
Error Code
Message
Name
Alias
Value

Status Code
Error Code
Message

If a property uses a multinode treepicker editor, the value should be a comma-separated list of Umbraco UDI Identifiers. In the example below, the UDI Identifiers are referencing content items. To learn more see the documentation.

When content contains an upload field it is possible to send a file along with the request to update content. This is done by sending a multi-part request with the json body and the file, see for an example. If the content item doesn't include files then you can send a standard reqeust with a JSON payload to update the content item.

If a property uses a multinode treepicker editor, the value should be a comma-separated list of Umbraco UDI Identifiers. In the example below, the UDI Identifiers are referencing content items. To learn more see the documentation.

Status Code
Error Code
Message

Api-Version: 2
Umb-Project-Alias: {project-alias}

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Media Type with alias '{alias}' could not be found.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}
{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/type"
        },
        "root": {
            "href": "https://api.umbraco.io/media/type"
        },
        "mediatypes": [
            {
                "href": "https://api.umbraco.io/media/type/Folder"
            },
            {
                "href": "https://api.umbraco.io/media/type/Image"
            },
            {
                "href": "https://api.umbraco.io/media/type/File"
            }
        ]
    },
    "_embedded": {
        "mediatypes": [
            {
                "alias": "Folder",
                "compositions": [],
                "groups": [],
                "name": "Folder",
                "_createDate": "2019-09-20T12:07:43.973Z",
                "_id": "f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d",
                "_updateDate": "2019-09-20T12:07:43.973Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/type/Folder"
                    }
                }
            },
            {
                "alias": "Image",
                "compositions": [],
                "groups": [
                    {
                        "name": "Image",
                        "sortOrder": 1,
                        "properties": [
                            {
                                "alias": "umbracoFile",
                                "label": "Upload image",
                                "propertyEditorAlias": "Umbraco.ImageCropper",
                                "sortOrder": 0,
                                "validation": {
                                    "required": true
                                }
                            },
                            {
                                "alias": "umbracoWidth",
                                "description": "in pixels",
                                "label": "Width",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "alias": "umbracoHeight",
                                "description": "in pixels",
                                "label": "Height",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "alias": "umbracoBytes",
                                "description": "in bytes",
                                "label": "Size",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 3,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "alias": "umbracoExtension",
                                "label": "Type",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 4,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "Image",
                "_createDate": "2019-09-20T12:07:43.973Z",
                "_id": "cc07b313-0843-4aa8-bbda-871c8da728c8",
                "_updateDate": "2019-09-20T12:07:43.973Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                }
            },
            {
                "alias": "File",
                "compositions": [],
                "groups": [
                    {
                        "name": "File",
                        "sortOrder": 1,
                        "properties": [
                            {
                                "alias": "umbracoFile",
                                "label": "Upload file",
                                "propertyEditorAlias": "Umbraco.UploadField",
                                "sortOrder": 0,
                                "validation": {
                                    "required": true
                                }
                            },
                            {
                                "alias": "umbracoExtension",
                                "label": "Type",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "alias": "umbracoBytes",
                                "description": "in bytes",
                                "label": "Size",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "File",
                "_createDate": "2019-09-20T12:07:43.973Z",
                "_id": "4c52d8ab-54e6-40cd-999c-7a5f24903e4d",
                "_updateDate": "2019-09-20T12:07:43.973Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/type/File"
                    }
                }
            }
        ]
    }
}
{
    "alias": "Image",
    "compositions": [],
    "groups": [
        {
            "name": "Image",
            "sortOrder": 1,
            "properties": [
                {
                    "alias": "umbracoFile",
                    "label": "Upload image",
                    "propertyEditorAlias": "Umbraco.ImageCropper",
                    "sortOrder": 0,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "alias": "umbracoWidth",
                    "description": "in pixels",
                    "label": "Width",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 1,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "alias": "umbracoHeight",
                    "description": "in pixels",
                    "label": "Height",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 2,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "alias": "umbracoBytes",
                    "description": "in bytes",
                    "label": "Size",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 3,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "alias": "umbracoExtension",
                    "label": "Type",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 4,
                    "validation": {
                        "required": false
                    }
                }
            ]
        }
    ],
    "name": "Image",
    "_createDate": "2019-09-20T12:07:43.973Z",
    "_id": "cc07b313-0843-4aa8-bbda-871c8da728c8",
    "_updateDate": "2019-09-20T12:07:43.973Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/type/Image"
        }
    }
}
Api-Version: 2.1
Umb-Project-Alias: {project-alias}

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Form with id '{id}' could not be found.

422

ValidationFailed

Validation error.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}
{
  "_links": {
    "self": {
      "href": "/api/forms"
    },
    "forms": {
      "href": "/api/forms/2edaf583-cf66-4d57-930c-f0772c3d1c52"
    }
  },
  "_embedded": {
    "forms": [
      {
        "_id": "2edaf583-cf66-4d57-930c-f0772c3d1c52",
        "indicator": "*",
        "name": "Contact",
        "nextLabel": "Next",
        "previousLabel": "Previous",
        "submitLabel": "Submit",
        "disableDefaultStylesheet": false,
        "fieldIndicationType": "MARK_MANDATORY_FIELDS",
        "hideFieldValidation": false,
        "messageOnSubmit": "Thank you",
        "showValidationSummary": false,
        "pages": [
          {
            "fieldsets": [
              {
                "columns": [
                  {
                    "width": 12,
                    "fields": [
                      {
                        "caption": "Name",
                        "alias": "name",
                        "required": true,
                        "requiredErrorMessage": "Please provide a value for Name",
                        "settings": {
                          "placeholder": "John Smith",
                          "defaultValue": ""
                        },
                        "type": "text"
                      },
                      {
                        "caption": "Email",
                        "alias": "email",
                        "required": true,
                        "requiredErrorMessage": "Please provide a value for Email",
                        "settings": {
                          "placeholder": "johnsmith@example.org",
                          "defaultValue": "",
                          "pattern": "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+",
                          "patternInvalidErrorMessage": "Please enter a valid email address"
                        },
                        "type": "text"
                      },
                      {
                        "caption": "Message",
                        "alias": "message",
                        "required": false,
                        "requiredErrorMessage": "Please provide a value for Message",
                        "settings": {
                          "defaultValue": "",
                          "placeholder": ""
                        },
                        "type": "textarea"
                      },
                      {
                        "caption": "Consent for storing submitted data",
                        "alias": "dataConsent",
                        "required": true,
                        "requiredErrorMessage": "Consent is required to store and process the data in this form.",
                        "settings": {
                          "acceptCopy": "Yes, I give permission to store and process my data"
                        },
                        "type": "dataConsent"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ],
        "_links": {
          "self": {
            "href": "/api/forms/2edaf583-cf66-4d57-930c-f0772c3d1c52"
          }
        }
      }
    ]
  }
}
{
  "_id": "2edaf583-cf66-4d57-930c-f0772c3d1c52",
  "indicator": "*",
  "name": "Contact",
  "nextLabel": "Next",
  "previousLabel": "Previous",
  "submitLabel": "Submit",
  "disableDefaultStylesheet": false,
  "fieldIndicationType": "MARK_MANDATORY_FIELDS",
  "hideFieldValidation": false,
  "messageOnSubmit": "Thank you",
  "showValidationSummary": false,
  "pages": [
    {
      "fieldsets": [
        {
          "columns": [
            {
              "width": 12,
              "fields": [
                {
                  "caption": "Name",
                  "alias": "name",
                  "required": true,
                  "requiredErrorMessage": "Please provide a value for Name",
                  "settings": {
                    "placeholder": "John Smith",
                    "defaultValue": ""
                  },
                  "type": "text"
                },
                {
                  "caption": "Email",
                  "alias": "email",
                  "required": true,
                  "requiredErrorMessage": "Please provide a value for Email",
                  "settings": {
                    "placeholder": "johnsmith@example.org",
                    "defaultValue": "",
                    "pattern": "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+",
                    "patternInvalidErrorMessage": "Please enter a valid email address"
                  },
                  "type": "text"
                },
                {
                  "caption": "Message",
                  "alias": "message",
                  "required": false,
                  "requiredErrorMessage": "Please provide a value for Message",
                  "settings": {
                    "defaultValue": "",
                    "placeholder": ""
                  },
                  "type": "textarea"
                },
                {
                  "caption": "Consent for storing submitted data",
                  "alias": "dataConsent",
                  "required": true,
                  "requiredErrorMessage": "Consent is required to store and process the data in this form.",
                  "settings": {
                    "acceptCopy": "Yes, I give permission to store and process my data"
                  },
                  "type": "dataConsent"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "_links": {
    "self": {
      "href": "/api/forms/2edaf583-cf66-4d57-930c-f0772c3d1c52"
    }
  }
}
{
  "name": "Jonh Smith",
  "email": "johnsmith@example.org",
  "dataConsent": "on"
}
Api-Version: 2
Umb-Project-Alias: {project-alias}

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Content with id '{id}' could not be found.

422

ValidationFailed

Validation error occured when trying to save or update the content item.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Forbidden",
    "message": "Authorization has been denied for this request."
  }
}
{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content"
        },
        "content": [
            {
                "href": "https://api.umbraco.io/content/{id}",
                "templated": true
            },
            {
                "href": "https://api.umbraco.io/content/6eb240ce-8f78-4467-ab51-68918cde2866"
            }
        ],
        "children": {
            "href": "https://api.umbraco.io/content/{id}/children{?page,pageSize}",
            "templated": true
        },
        "publish": {
            "href": "https://api.umbraco.io/content/{id}/publish{?culture}",
            "templated": true
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/{id}/unpublish{?culture}",
            "templated": true
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/{alias}",
            "templated": true
        }
    },
    "_embedded": {
        "content": [
            {
                "_currentVersionState": {
                    "$invariant": "PUBLISHED"
                },
                "name": {
                    "$invariant": "Home"
                },
                "_updateDate": {
                    "$invariant": "2019-10-07T07:58:48.477Z"
                },
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-10-07T07:45:21.363Z",
                "_id": "6eb240ce-8f78-4467-ab51-68918cde2866",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/6eb240ce-8f78-4467-ab51-68918cde2866"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/content/6eb240ce-8f78-4467-ab51-68918cde2866/children"
                    },
                    "publish": {
                        "href": "https://api.umbraco.io/content/6eb240ce-8f78-4467-ab51-68918cde2866/publish"
                    },
                    "unpublish": {
                        "href": "https://api.umbraco.io/content/6eb240ce-8f78-4467-ab51-68918cde2866/unpublish"
                    },
                    "contenttype": {
                        "href": "https://api.umbraco.io/content/type/home"
                    }
                },
                "contentTypeAlias": "home",
                "sortOrder": 4,
                "heroHeader": {
                    "$invariant": "Umbraco Demo"
                },
                "heroDescription": {
                    "$invariant": "Moonfish, steelhead, lamprey southern flounder tadpole fish sculpin bigeye, blue-redstripe danio collared dogfish. Smalleye squaretail goldfish arowana butterflyfish pipefish wolf-herring jewel tetra, shiner; gibberfish red velvetfish. Thornyhead yellowfin pike threadsail ayu cutlassfish."
                },
                "heroCTACaption": {
                    "$invariant": "Check our products"
                },
                "heroCTALink": {
                    "$invariant": "umb://document/082333be34b14c2d81a6be92640094fc"
                },
                "bodyText": {
                    "$invariant": null
                },
                "footerHeader": {
                    "$invariant": "Umbraco Demo"
                },
                "footerDescription": {
                    "$invariant": "Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Vivamus suscipit tortor eget felis porttitor volutpat"
                },
                "footerCTACaption": {
                    "$invariant": "Read All on the Blog"
                },
                "footerCTALink": {
                    "$invariant": "umb://document/8007e923e62a4ac1a33fcaf3052582f4"
                },
                "footerAddress": {
                    "$invariant": "Umbraco HQ - Unicorn Square - Haubergsvej 1 - 5000 Odense C - Denmark - +45 70 26 11 62"
                },
                "heroBackgroundImage": {
                    "$invariant": "umb://media/76966940c9ba471686cef3854a7f5bd6"
                },
                "font": {
                    "$invariant": "serif"
                },
                "colorTheme": {
                    "$invariant": "earth"
                },
                "sitename": {
                    "$invariant": "Umbraco Sample Site"
                },
                "logo": {
                    "$invariant": ""
                }
            }
        ]
    }
}
{
    "_currentVersionState": {
        "$invariant": "PUBLISHED"
    },
    "name": {
        "$invariant": "Unicorn"
    },
    "_updateDate": {
        "$invariant": "2019-10-07T11:50:56.5Z"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:50:34.48Z",
    "_id": "3de82763-c4bb-4bca-8f79-7b211b3ffffa",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/3de82763-c4bb-4bca-8f79-7b211b3ffffa"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/3de82763-c4bb-4bca-8f79-7b211b3ffffa/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/3de82763-c4bb-4bca-8f79-7b211b3ffffa/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/3de82763-c4bb-4bca-8f79-7b211b3ffffa/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/product"
        }
    },
    "contentTypeAlias": "product",
    "parentId": "082333be-34b1-4c2d-81a6-be92640094fc",
    "sortOrder": 0,
    "productName": {
        "$invariant": "Unicorn"
    },
    "price": {
        "$invariant": "249"
    },
    "category": {
        "$invariant": [
            "animals"
        ]
    },
    "description": {
        "$invariant": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta."
    },
    "sku": {
        "$invariant": "UMB-UNICORN"
    },
    "photos": {
        "$invariant": "umb://media/8199c666b05c4527b857b99bee2e0616"
    },
    "features": {
        "$invariant": ""
    },
    "bodyText": {
        "$invariant": null
    }
}
?page={integer=1}
?pageSize={integer=10}
{
    "_totalItems": 3,
    "_totalPages": 1,
    "_page": 1,
    "_pageSize": 10,
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/8007e923-e62a-4ac1-a33f-caf3052582f4/children?page=1"
        },
        "content": [
            {
                "href": "https://api.umbraco.io/content/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5"
            },
            {
                "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
            },
            {
                "href": "https://api.umbraco.io/content/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31"
            }
        ]
    },
    "_embedded": {
        "content": [
            {
                "_currentVersionState": {
                    "$invariant": "PUBLISHED"
                },
                "name": {
                    "$invariant": "This will be great"
                },
                "_updateDate": {
                    "$invariant": "2019-10-07T11:52:31.143Z"
                },
                "_hasChildren": false,
                "_level": 3,
                "_createDate": "2019-10-07T11:52:31.143Z",
                "_id": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/content/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5/children"
                    },
                    "publish": {
                        "href": "https://api.umbraco.io/content/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5/publish"
                    },
                    "unpublish": {
                        "href": "https://api.umbraco.io/content/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5/unpublish"
                    },
                    "contenttype": {
                        "href": "https://api.umbraco.io/content/type/blogpost"
                    }
                },
                "contentTypeAlias": "blogpost",
                "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
                "sortOrder": 0,
                "seoMetaDescription": {
                    "$invariant": ""
                },
                "keywords": {
                    "$invariant": []
                },
                "umbNaviHide": {
                    "$invariant": "0"
                },
                "pageTitle": {
                    "$invariant": "This will be great"
                },
                "categories": {
                    "$invariant": [
                        "great",
                        "umbraco"
                    ]
                },
                "excerpt": {
                    "$invariant": "Proin eget tortor risus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Vivamus magna justo, lacinia eget consectetur sed"
                },
                "bodyText": {
                    "$invariant": null
                }
            },
            {
                "_currentVersionState": {
                    "$invariant": "PUBLISHED"
                },
                "name": {
                    "$invariant": "Another one"
                },
                "_updateDate": {
                    "$invariant": "2019-10-07T11:53:09.653Z"
                },
                "_hasChildren": false,
                "_level": 3,
                "_createDate": "2019-10-07T11:53:09.653Z",
                "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
                    },
                    "publish": {
                        "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
                    },
                    "unpublish": {
                        "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
                    },
                    "contenttype": {
                        "href": "https://api.umbraco.io/content/type/blogpost"
                    }
                },
                "contentTypeAlias": "blogpost",
                "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
                "sortOrder": 0,
                "seoMetaDescription": {
                    "$invariant": ""
                },
                "keywords": {
                    "$invariant": []
                },
                "umbNaviHide": {
                    "$invariant": "0"
                },
                "pageTitle": {
                    "$invariant": "Another one"
                },
                "categories": {
                    "$invariant": [
                        "cg16",
                        "codegarden",
                        "umbraco"
                    ]
                },
                "excerpt": {
                    "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
                },
                "bodyText": {
                    "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
                }
            },
            {
                "_currentVersionState": {
                    "$invariant": "PUBLISHED"
                },
                "name": {
                    "$invariant": "My Blog Post"
                },
                "_updateDate": {
                    "$invariant": "2019-10-07T11:54:00.657Z"
                },
                "_hasChildren": false,
                "_level": 3,
                "_createDate": "2019-10-07T11:54:00.657Z",
                "_id": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/content/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31/children"
                    },
                    "publish": {
                        "href": "https://api.umbraco.io/content/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31/publish"
                    },
                    "unpublish": {
                        "href": "https://api.umbraco.io/content/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31/unpublish"
                    },
                    "contenttype": {
                        "href": "https://api.umbraco.io/content/type/blogpost"
                    }
                },
                "contentTypeAlias": "blogpost",
                "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
                "sortOrder": 0,
                "seoMetaDescription": {
                    "$invariant": ""
                },
                "keywords": {
                    "$invariant": []
                },
                "umbNaviHide": {
                    "$invariant": "0"
                },
                "pageTitle": {
                    "$invariant": "My Blog Post"
                },
                "categories": {
                    "$invariant": [
                        "demo",
                        "umbraco",
                        "starterkit",
                        "lorem ipsum"
                    ]
                },
                "excerpt": {
                    "$invariant": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quis lorem ut libero malesuada feugiat. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada."
                },
                "bodyText": {
                    "$invariant": "<div class=\"anyipsum-output\">\n<p>Bacon ipsum dolor amet alcatra pig cow sirloin. Jerky pig kielbasa, pork chop beef spare ribs sirloin. Ham hock sausage biltong meatball pastrami capicola boudin alcatra chicken. Salami kielbasa short ribs shoulder brisket tri-tip, cupim meatball pork chop capicola. Kielbasa short ribs strip steak t-bone frankfurter. Pancetta kevin salami, turducken landjaeger sausage pig.</p>\n<p>Sausage tongue doner short ribs tri-tip pork belly. Kielbasa swine bresaola salami pork short ribs ribeye jerky ground round boudin burgdoggen. Beef ribs ribeye flank biltong cupim andouille beef kielbasa meatloaf ham sausage. Pancetta chuck picanha short loin pork t-bone ball tip, boudin buffalo biltong chicken kevin.</p>\n<p>Salami cupim sirloin turducken pancetta ground round spare ribs. Ham hock capicola prosciutto salami meatball alcatra. Ribeye t-bone pancetta burgdoggen, pork chop beef ribs cupim meatball. Tail pork belly leberkas, frankfurter burgdoggen beef ribs bresaola fatback turducken flank picanha filet mignon. Pig bresaola pancetta venison cow.</p>\n<p>Ham drumstick cupim pork belly t-bone shoulder. Prosciutto flank ham filet mignon shank. Fatback shank capicola, buffalo pig bacon kevin corned beef jerky turkey pork belly venison. Pork belly drumstick beef ribs corned beef. Short loin meatloaf capicola spare ribs chuck burgdoggen. Shankle ground round cow, biltong hamburger t-bone leberkas turkey. Swine leberkas kielbasa hamburger sirloin bacon.</p>\n<p>Cow turducken buffalo alcatra filet mignon kevin pastrami tail. Jerky short loin boudin pork chop. Corned beef tri-tip picanha pork pig boudin capicola sirloin flank. Ham hock cupim prosciutto fatback.</p>\n</div>\n<div class=\"anyipsum-form-header\">Does your lorem ipsum text long for something a little meatier? Give our generator a try… it’s tasty!</div>"
                }
            }
        ]
    }
}
{
    "name": {
        "$invariant": "Another one"
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "multinodeTreePicker": {
        "$invariant": "umb://document/067c7c926709487ab01be84168b333cf,umb://document/8a4dec90cf394028a743eae0729d47ba,umb://document/5fdd887233394a3492000bbf74e3b005"
    },
    "bodyText": {
        "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
    }
}
{
    "_currentVersionState": {
        "$invariant": "DRAFT"
    },
    "name": {
        "$invariant": "Another one"
    },
    "_updateDate": {
        "$invariant": "2019-10-10T11:19:04.3988745+00:00"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:53:09.653Z",
    "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/blogpost"
        }
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "bodyText": {
        "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
    }
}
Content-Type: multipart/form-data; boundary=MultipartBoundry

--MultipartBoundry
Content-Disposition: form-data; name="content"
Content-Type: application/json

{
  "contentTypeAlias": "withUpload",
  "name": {
    "en-US": "Upload Test"
  },
  "text": { "$invariant": "Here's some text" },
  "fileUpload": { "en-US": "han-solo.png" }
}
--MultipartBoundry
Content-Disposition: form-data; name="fileUpload.en-US"
Content-Type: image/png

BINARY DATA
--MultipartBoundry--
{
  "contentTypeAlias": "withUpload",
  "_createDate": "2019-08-08T10:07:50.2777311+02:00",
  "_currentVersionState": {
    "en-US": "DRAFT",
    "da": "NOT_CREATED"
  },
  "name": {
    "en-US": "Upload Test",
    "da": null
  },
  "_updateDate": {
    "en-US": "2019-08-08T10:07:50.2828014+02:00",
    "da": null
  },
  "_hasChildren": false,
  "_id": "511a0927-3c56-4ec0-b308-1dea07753795",
  "_level": 1,
  "sortOrder": 21,
  "_links": {
    "self": {
      "href": "https://api.umbraco.io/content/511a0927-3c56-4ec0-b308-1dea07753795"
    },
    "root": {
      "href": "https://api.umbraco.io/content"
    },
    "children": {
      "href": "https://api.umbraco.io/content/511a0927-3c56-4ec0-b308-1dea07753795/children"
    }
  },
  "fileUpload": {
    "en-US": "/media/dg4gynhr/han-solo.png",
    "da": ""
  },
  "text": {
    "$invariant": "Here's some text"
  }
}
{
    "name": {
        "$invariant": "Another one"
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "multinodeTreePicker": {
        "$invariant": "umb://document/067c7c926709487ab01be84168b333cf,umb://document/8a4dec90cf394028a743eae0729d47ba,umb://document/5fdd887233394a3492000bbf74e3b005"
    },
    "bodyText": {
        "$invariant": "<p>Lorem Ipsum</p>"
    }
}
{
    "_currentVersionState": {
        "$invariant": "DRAFT"
    },
    "name": {
        "$invariant": "Another one"
    },
    "_updateDate": {
        "$invariant": "2019-10-07T11:53:09.653Z"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:53:09.653Z",
    "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
    "_deleteDate": "2019-10-10T11:19:53.6828938Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/blogpost"
        }
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "bodyText": {
        "$invariant": "<p>Lorem Ipsum</p>"
    }
}
?culture={string=en-US}
{
    "_currentVersionState": {
        "$invariant": "PUBLISHED"
    },
    "name": {
        "$invariant": "Another one"
    },
    "_updateDate": {
        "$invariant": "2019-10-10T11:19:04.3988745+00:00"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:53:09.653Z",
    "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/blogpost"
        }
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "bodyText": {
        "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
    }
}
?culture={string=en-US}
{
    "_currentVersionState": {
        "$invariant": "DRAFT"
    },
    "name": {
        "$invariant": "Another one"
    },
    "_updateDate": {
        "$invariant": "2019-10-10T11:15:38.5964706+00:00"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:53:09.653Z",
    "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/blogpost"
        }
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "bodyText": {
        "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
    }
}
{
    "_currentVersionState": {
        "$invariant": "PUBLISHED"
    },
    "name": {
        "$invariant": "Another one"
    },
    "_updateDate": {
        "$invariant": "2019-10-07T11:53:09.653Z"
    },
    "_hasChildren": false,
    "_level": 3,
    "_createDate": "2019-10-07T11:53:09.653Z",
    "_id": "041067a0-74f5-4d03-92af-40c3c0aa13e7",
    "_deleteDate": "2019-10-10T11:19:53.6828938Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7"
        },
        "root": {
            "href": "https://api.umbraco.io/content"
        },
        "children": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/children"
        },
        "publish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/publish"
        },
        "unpublish": {
            "href": "https://api.umbraco.io/content/041067a0-74f5-4d03-92af-40c3c0aa13e7/unpublish"
        },
        "contenttype": {
            "href": "https://api.umbraco.io/content/type/blogpost"
        }
    },
    "contentTypeAlias": "blogpost",
    "parentId": "8007e923-e62a-4ac1-a33f-caf3052582f4",
    "sortOrder": 0,
    "seoMetaDescription": {
        "$invariant": ""
    },
    "keywords": {
        "$invariant": []
    },
    "umbNaviHide": {
        "$invariant": "0"
    },
    "pageTitle": {
        "$invariant": "Another one"
    },
    "categories": {
        "$invariant": [
            "cg16",
            "codegarden",
            "umbraco"
        ]
    },
    "excerpt": {
        "$invariant": "Donec sollicitudin molestie malesuada. Vivamus suscipit tortor eget felis porttitor volutpat. Sed porttitor lectus nibh."
    },
    "bodyText": {
        "$invariant": "<p>Donec sollicitudin molestie malesuada. Proin eget tortor risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Nulla porttitor accumsan tincidunt. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada.</p>\n<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus. Donec rutrum congue leo eget malesuada. Nulla porttitor accumsan tincidunt. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Sed porttitor lectus nibh.</p>\n<p>Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Donec rutrum congue leo eget malesuada. Donec rutrum congue leo eget malesuada. Sed porttitor lectus nibh. Nulla quis lorem ut libero malesuada feugiat.</p>"
    }
}
Api-Version: 2
Umb-Project-Alias: {project-alias}

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Content Type with alias '{alias}' could not be found.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Forbidden",
    "message": "Authorization has been denied for this request."
  }
}
{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/type"
        },
        "contenttypes": [
            {
                "href": "https://api.umbraco.io/content/type/contentBase"
            },
            {
                "href": "https://api.umbraco.io/content/type/feature"
            },
            {
                "href": "https://api.umbraco.io/content/type/navigationBase"
            },
            {
                "href": "https://api.umbraco.io/content/type/home"
            },
            {
                "href": "https://api.umbraco.io/content/type/blog"
            },
            {
                "href": "https://api.umbraco.io/content/type/blogpost"
            },
            {
                "href": "https://api.umbraco.io/content/type/products"
            },
            {
                "href": "https://api.umbraco.io/content/type/product"
            }
        ]
    },
    "_embedded": {
        "contenttypes": [
            {
                "allowCultureVariant": false,
                "alias": "blog",
                "compositions": [
                    "contentBase",
                    "navigationBase"
                ],
                "groups": [
                    {
                        "name": "Content",
                        "sortOrder": 10,
                        "properties": [
                            {
                                "allowCultureVariant": false,
                                "alias": "pageTitle",
                                "label": "Page Title",
                                "propertyEditorAlias": "Umbraco.TextBox",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "bodyText",
                                "configuration": {
                                    "editor": null,
                                    "blocks": null,
                                    "useLiveEditing": false,
                                    "overlaySize": null,
                                    "hideLabel": false,
                                    "mediaParentId": null,
                                    "ignoreUserStartNodes": false
                                },
                                "label": "Content",
                                "propertyEditorAlias": "Umbraco.TinyMCE",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    },
                    {
                        "name": "Navigation & SEO",
                        "sortOrder": 20,
                        "properties": [
                            {
                                "allowCultureVariant": false,
                                "alias": "seoMetaDescription",
                                "label": "Description",
                                "propertyEditorAlias": "Umbraco.TextArea",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "keywords",
                                "configuration": {
                                    "group": "default",
                                    "storageType": "Json",
                                    "Delimiter": "\u0000"
                                },
                                "label": "Keywords",
                                "propertyEditorAlias": "Umbraco.Tags",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "umbNaviHide",
                                "configuration": {
                                    "default": false,
                                    "showLabels": false,
                                    "labelOn": null,
                                    "labelOff": null
                                },
                                "label": "Hide in Navigation",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    },
                    {
                        "name": "Settings",
                        "sortOrder": 0,
                        "properties": [
                            {
                                "allowCultureVariant": false,
                                "alias": "howManyPostsShouldBeShown",
                                "configuration": {
                                    "enableRange": false,
                                    "initVal1": 10.0,
                                    "initVal2": 0.0,
                                    "minVal": 1.0,
                                    "maxVal": 50.0,
                                    "step": 1.0
                                },
                                "label": "How many posts should be shown?",
                                "propertyEditorAlias": "Umbraco.Slider",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "disqusShortname",
                                "description": "To use comments, you'll need to sign up for Disqus and enter your shortname here (more info: https://help.disqus.com/customer/portal/articles/472097-universal-embed-code)",
                                "label": "Disqus Shortname",
                                "propertyEditorAlias": "Umbraco.TextBox",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "Blog",
                "_createDate": "2019-10-04T11:04:28.35Z",
                "_id": "558f0270-76dc-4b81-bd4b-0687eecce904",
                "_updateDate": "2019-10-04T11:04:28.35Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/type/blog"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content/type"
                    }
                }
            },
            {
                "allowCultureVariant": false,
                "alias": "blogpost",
                "compositions": [
                    "navigationBase"
                ],
                "groups": [
                    {
                        "name": "Navigation & SEO",
                        "sortOrder": 20,
                        "properties": [
                            {
                                "allowCultureVariant": false,
                                "alias": "seoMetaDescription",
                                "label": "Description",
                                "propertyEditorAlias": "Umbraco.TextArea",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "keywords",
                                "configuration": {
                                    "group": "default",
                                    "storageType": "Json",
                                    "Delimiter": "\u0000"
                                },
                                "label": "Keywords",
                                "propertyEditorAlias": "Umbraco.Tags",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "umbNaviHide",
                                "configuration": {
                                    "default": false,
                                    "showLabels": false,
                                    "labelOn": null,
                                    "labelOff": null
                                },
                                "label": "Hide in Navigation",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    },
                    {
                        "name": "Content",
                        "sortOrder": 0,
                        "properties": [
                            {
                                "allowCultureVariant": false,
                                "alias": "pageTitle",
                                "label": "Page Title",
                                "propertyEditorAlias": "Umbraco.TextBox",
                                "sortOrder": 0,
                                "validation": {
                                    "required": true
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "categories",
                                "configuration": {
                                    "group": "default",
                                    "storageType": "Json",
                                    "Delimiter": "\u0000"
                                },
                                "label": "Categories (tags)",
                                "propertyEditorAlias": "Umbraco.Tags",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "excerpt",
                                "label": "Excerpt",
                                "propertyEditorAlias": "Umbraco.TextArea",
                                "sortOrder": 2,
                                "validation": {
                                    "required": true
                                }
                            },
                            {
                                "allowCultureVariant": false,
                                "alias": "bodyText",
                                "configuration": {
                                    "editor": null,
                                    "blocks": null,
                                    "useLiveEditing": false,
                                    "overlaySize": null,
                                    "hideLabel": false,
                                    "mediaParentId": null,
                                    "ignoreUserStartNodes": false
                                },
                                "label": "Content",
                                "propertyEditorAlias": "Umbraco.TinyMCE",
                                "sortOrder": 3,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "Blogpost",
                "_createDate": "2019-10-04T11:10:04.247Z",
                "_id": "5cb405d5-cb5e-4408-8117-f0ac51fcf524",
                "_updateDate": "2019-10-04T11:10:04.247Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/content/type/blogpost"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/content/type"
                    }
                }
            }
        ]
    }
}
{
    "allowCultureVariant": false,
    "alias": "home",
    "compositions": [],
    "groups": [
        {
            "name": "Hero",
            "sortOrder": 0,
            "properties": [
                {
                    "allowCultureVariant": false,
                    "alias": "heroHeader",
                    "description": "This is the main headline for the hero area on the Homepage",
                    "label": "Header",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 0,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "heroDescription",
                    "label": "Description",
                    "propertyEditorAlias": "Umbraco.TextArea",
                    "sortOrder": 1,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "heroCTACaption",
                    "label": "Call to Action Caption",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 2,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "heroCTALink",
                    "label": "Call to Action Link",
                    "propertyEditorAlias": "Umbraco.ContentPicker",
                    "sortOrder": 3,
                    "validation": {
                        "required": false
                    }
                }
            ]
        },
        {
            "name": "Content",
            "sortOrder": 1,
            "properties": [
                {
                    "allowCultureVariant": false,
                    "alias": "bodyText",
                    "label": "Content",
                    "propertyEditorAlias": "Umbraco.TinyMCE",
                    "sortOrder": 0,
                    "validation": {
                        "required": false
                    }
                }
            ]
        },
        {
            "name": "Footer",
            "sortOrder": 2,
            "properties": [
                {
                    "allowCultureVariant": false,
                    "alias": "footerHeader",
                    "label": "Header",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 0,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "footerDescription",
                    "label": "Description",
                    "propertyEditorAlias": "Umbraco.TextArea",
                    "sortOrder": 1,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "footerCTACaption",
                    "description": "Caption on the Call To Action Button",
                    "label": "Call to Action Caption",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 2,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "footerCTALink",
                    "label": "Call to Action Link",
                    "propertyEditorAlias": "Umbraco.ContentPicker",
                    "sortOrder": 3,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "footerAddress",
                    "label": "Address",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 4,
                    "validation": {
                        "required": true
                    }
                }
            ]
        },
        {
            "name": "Design",
            "sortOrder": 3,
            "properties": [
                {
                    "allowCultureVariant": false,
                    "alias": "heroBackgroundImage",
                    "configuration": {
                        "filter": null,
                        "multiple": false,
                        "validationLimit": {
                        "min": 0,
                        "max": 1
                        },
                        "startNodeId": null,
                        "enableLocalFocalPoint": false,
                        "crops": null,
                        "ignoreUserStartNodes": false
                    },
                    "description": "Spice up the homepage by adding a beautiful photo that relates to your business",
                    "label": "Hero Background",
                    "propertyEditorAlias": "Umbraco.MediaPicker3",
                    "sortOrder": 0,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "font",
                    "configuration": {
                        "items": {
                            "1": {
                                "value": "Serif",
                                "sortOrder": 1
                            },
                            "2": {
                                "value": "Sans-serif",
                                "sortOrder": 2
                            }
                        }
                    },
                    "label": "Font",
                    "propertyEditorAlias": "Umbraco.RadioButtonList",
                    "sortOrder": 1,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "colorTheme",
                    "configuration": {
                        "items": {
                            "1": {
                                "value": "Red",
                                "sortOrder": 1
                            },
                            "2": {
                                "value": "Blue",
                                "sortOrder": 2
                            },
                            "3": {
                                "value": "Green",
                                "sortOrder": 3
                            }
                        }
                    },
                    "label": "Color Theme",
                    "propertyEditorAlias": "Umbraco.RadioButtonList",
                    "sortOrder": 2,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "sitename",
                    "description": "Used on the homepage as well as the title and social cards",
                    "label": "Sitename",
                    "propertyEditorAlias": "Umbraco.TextBox",
                    "sortOrder": 3,
                    "validation": {
                        "required": true
                    }
                },
                {
                    "allowCultureVariant": false,
                    "alias": "logo",
                    "configuration": {
                        "filter": null,
                        "multiple": false,
                        "validationLimit": {
                        "min": 0,
                        "max": 1
                        },
                        "startNodeId": null,
                        "enableLocalFocalPoint": false,
                        "crops": null,
                        "ignoreUserStartNodes": false
                    },
                    "description": "Optional. If you add a logo it'll be used in the upper left corner instead of the site name. Make sure to use a transparent logo for best results",
                    "label": "Logo",
                    "propertyEditorAlias": "Umbraco.MediaPicker3",
                    "sortOrder": 4,
                    "validation": {
                        "required": false
                    }
                }
            ]
        }
    ],
    "name": "Home",
    "_createDate": "2019-10-04T10:54:53.297Z",
    "_id": "0a87cb29-ba6e-4520-8ce6-85e70d89e539",
    "_updateDate": "2019-10-04T10:54:53.297Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/content/type/home"
        },
        "root": {
            "href": "https://api.umbraco.io/content/type"
        }
    }
}
Pricing & Features
UDI Identifiers
UDI Identifiers
Content endpoints
Content Type endpoints
Media endpoints
Media Type endpoints
Language endpoints
Member endpoints
Member Group endpoints
Member Type endpoints
Relation endpoints
Relation Type endpoints
Umbraco Forms endpoints
Common Headers
Authentication
Errors
Get all Media Types
Get by alias
Common Headers
Authentication
Errors
Fields types
Get forms
Get by id
Submit entry
Common Headers
Authentication
Permissions
Errors
Get Root Content
Get By Id
Get Children
Create Content
Create Content with Files
Update Content
Publish Content
Unpublish Content
Delete Content
Create content with files
Common Headers
Authentication
Errors
Get all Content Types
Get by alias
GraphQL Filter and Ordering Documentation

Checkbox

checkbox

string("on") / boolean

Date

date

Data Consent

dataConsent

string("on") / boolean

Dropdown

dropdown

string

Hidden

hidden

string

Long Answer

textarea

string

Multiple Choice

checkboxList

string

Password

password

string

Recaptcha2

recaptcha2

string(reCaptcha response)

Short Answer

text

string

Single Choice

radio

string

Title And Description

titleAndDescription

readonly

GraphQL API

Documentation for Umbraco Heartcore GraphQL API

The GraphQL API can be accessed on https://graphql.umbraco.io, it accepts POST requests with the content type application/json. The body must be JSON and contain a query field with the query as a string and an optional variables field containing the variables.

{
  "query": "query($url: String) { content(url: $url) { name } }",
  "variables": {
    "url": "/"
  }
}

API Access

In order to access the data for your Umbraco Heartcore project you need to provide a project identifier (Project Alias) via an HTTP Header or a Querystring parameter.

The Project Alias is an HTTP friendly version of the Project Name under your Umbraco Cloud account.

Access via Umb-Project-Alias header

POST https://graphql.umbraco.io/
Umb-Project-Alias: {project-alias}

Authorization

By default the GraphQL API is not protected. This can be enabled through the Backoffice, where API keys for each user in the Backoffice is also managed.

To access the GraphQL API the user must have access to the Content section and have the Browse Node permission.

Access via an Api-Key header

POST https://graphql.umbraco.io/
Api-Key: {api-key}

Preview

The GraphQL API supports fetching draft content, this can be done by passing a preview argument to the root query fields.

Fetching draft content requires an API Key to be passed with the request.

query {
  content(preview: true) {
    name
  }
}

Persisted queries

{
  "extensions": {
    "persistedQuery": {
      "alias": "{Alias}"
    }
  }
}

The persisted queries also support variables

{
  "extensions": {
    "persistedQuery": {
      "alias": "{Alias}"
    }
  },
  "variables": {
    "url": "/"
  }
}

Information on how the GraphQL schema is generated, reserved names and built-in custom types.

A list of all the built-in Umbraco Property Editors and their GraphQL types.

Documentation on how to filter and order collections with the GraphQL API.

Member Groups

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Member Group with name '{name}' could not be found.

422

ValidationFailed

Validation error occured when trying to save or update the member group.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}

Get all

Get all Member Groups.

URL: /member/group

Method: GET

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
  "_links": {
    "self": {
      "href": "/api/member/group"
    },
    "membergroups": {
      "href": "/api/member/group/Club%20Blue%20Members",
      "href": "/api/member/group/Elite%20Shoppers%20Group"
    }
  },
  "_embedded": {
    "membergroups": [
      {
        "name": "Club Blue Members",
        "_createDate": "2019-10-10T12:02:50.83Z",
        "_id": "15a1a854-596c-4b72-b462-769015a6b0eb",
        "_updateDate": "0001-01-01T00:00:00Z",
        "_links": {
          "self": {
            "href": "/api/member/group/Club%20Blue%20Members"
          }
        }
      },
      {
        "name": "Elite Shoppers Group",
        "_createDate": "2019-10-10T12:09:58.5982624Z",
        "_id": "1ae62150-e54c-4fd7-aabe-9ad46d1b7109",
        "_updateDate": "0001-01-01T00:00:00Z",
        "_links": {
          "self": {
            "href": "/api/member/group/Elite%20Shoppers%20Group"
          }
        }
      }
    ]
  }
}

Get by name

Get a specific Member Group by its name.

URL: /member/group/{name}

Method: GET

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
  "name": "Club Blue Members",
  "_createDate": "2019-10-10T12:02:50.83Z",
  "_id": "15a1a854-596c-4b72-b462-769015a6b0eb",
  "_updateDate": "0001-01-01T00:00:00Z",
  "_links": {
    "self": {
    "href": "/api/member/group/Club%20Blue%20Members"
    }
  }
}

Create member group

Create a new Member Group.

URL: /member/group

Method: POST

Permissions required : Access to Member section of the Umbraco Backoffice

Request

{
  "name": "Elite Shoppers Group"
}

Success Response

Code: 201

Content Example:

{
  "name": "Elite Shoppers Group",
  "_createDate": "2019-10-10T12:09:58.5982624Z",
  "_id": "1ae62150-e54c-4fd7-aabe-9ad46d1b7109",
  "_updateDate": "2019-10-10T12:09:58.5982624Z",
  "_links": {
    "self": {
    "href": "/api/member/group/Elite%20Shoppers%20Group"
    }
  }
}

Delete member group

Delete an existing Member Group.

URL: /member/group/{name}

Method: DELETE

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

DELETE https://api.umbraco.io/member/group/Elite%20Shoppers%20Group

{
  "name": "Elite Shoppers Group",
  "_createDate": "2019-10-10T12:09:58.597Z",
  "_id": "1ae62150-e54c-4fd7-aabe-9ad46d1b7109",
  "_updateDate": "0001-01-01T00:00:00Z",
  "_deleteDate": "2019-10-10T12:10:45.0657415Z",
  "_links": {
    "self": {
    "href": "/api/member/group/Elite%20Shoppers%20Group"
    }
  }
}

Relation Types

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Relation Type with alias '{alias}' could not be found.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}

Get all relation types

Get a list of all available relation types.

URL: /relation/type

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/type"
        },
        "relationtypes": [
            {
                "href": "https://api.umbraco.io/relation/type/relateDocumentOnCopy"
            },
            {
                "href": "https://api.umbraco.io/relation/type/relateParentDocumentOnDelete"
            },
            {
                "href": "https://api.umbraco.io/relation/type/relateParentMediaFolderOnDelete"
            }
        ]
    },
    "_embedded": {
        "relationtypes": [
            {
                "name": "Relate Document On Copy",
                "alias": "relateDocumentOnCopy",
                "isBidirectional": true,
                "parentObjectType": "DOCUMENT",
                "childObjectType": "DOCUMENT",
                "_createDate": "0001-01-01T00:00:00Z",
                "_id": "4cbeb612-e689-3563-b755-bf3ede295433",
                "_updateDate": "0001-01-01T00:00:00Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/type/relateDocumentOnCopy"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/relation/type"
                    }
                }
            },
            {
                "name": "Relate Parent Document On Delete",
                "alias": "relateParentDocumentOnDelete",
                "isBidirectional": false,
                "parentObjectType": "DOCUMENT",
                "childObjectType": "DOCUMENT",
                "_createDate": "0001-01-01T00:00:00Z",
                "_id": "0cc3507c-66ab-3091-8913-3d998148e423",
                "_updateDate": "0001-01-01T00:00:00Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/type/relateParentDocumentOnDelete"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/relation/type"
                    }
                }
            },
            {
                "name": "Relate Parent Media Folder On Delete",
                "alias": "relateParentMediaFolderOnDelete",
                "isBidirectional": false,
                "parentObjectType": "MEDIA",
                "childObjectType": "MEDIA",
                "_createDate": "0001-01-01T00:00:00Z",
                "_id": "8307994f-faf2-3844-bab9-72d34514edf2",
                "_updateDate": "0001-01-01T00:00:00Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/type/relateParentMediaFolderOnDelete"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/relation/type"
                    }
                }
            }
        ]
    }
}

Get by alias

Get a specific Relation Type by its alias.

URL: /relation/type/{alias}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "name": "Relate Document On Copy",
    "alias": "relateDocumentOnCopy",
    "isBidirectional": true,
    "parentObjectType": "DOCUMENT",
    "childObjectType": "DOCUMENT",
    "_createDate": "0001-01-01T00:00:00Z",
    "_id": "4cbeb612-e689-3563-b755-bf3ede295433",
    "_updateDate": "0001-01-01T00:00:00Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/type/relateDocumentOnCopy"
        },
        "root": {
            "href": "https://api.umbraco.io/relation/type"
        }
    }
}

Relations

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Relation with id '{id}' could not be found.

422

ValidationFailed

Validation error occured when trying to save or update the relation.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}

Get by id

Get a specific relation by its integer ID.

URL: /relation/{id}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_id": 4,
    "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
    "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
    "relationTypeAlias": "relateDocumentOnCopy",
    "comment": "Testing relations for relateDocumentOnCopy",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/4"
        }
    }
}

Get by relation type alias

Get a list of relations by their Relation Type alias.

URL: /relation/{alias}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/parent/"
        },
        "relations": {
            "href": "https://api.umbraco.io/relation/4"
        }
    },
    "_embedded": {
        "relations": [
            {
                "_id": 4,
                "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
                "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
                "relationTypeAlias": "relateDocumentOnCopy",
                "comment": "Testing relations for relateDocumentOnCopy",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/4"
                    }
                }
            }
        ]
    }
}

Get by parent id

Get a list of relations by their parents GUID ID.

URL: /relation/parent/{id}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/parent/af3e08fc-fb90-4c78-b11c-c1a0cf43bd31"
        },
        "relations": {
            "href": "https://api.umbraco.io/relation/4"
        }
    },
    "_embedded": {
        "relations": [
            {
                "_id": 4,
                "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
                "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
                "relationTypeAlias": "relateDocumentOnCopy",
                "comment": "Testing relations for relateDocumentOnCopy",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/4"
                    }
                }
            }
        ]
    }
}

Get by child id

Get a list of relations by their childs GUID ID.

URL: /relation/child/{id}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/child/e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5"
        },
        "relations": {
            "href": "https://api.umbraco.io/relation/4"
        }
    },
    "_embedded": {
        "relations": [
            {
                "_id": 4,
                "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
                "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
                "relationTypeAlias": "relateDocumentOnCopy",
                "comment": "Testing relations for relateDocumentOnCopy",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/relation/4"
                    }
                }
            }
        ]
    }
}

Create relation

Create a new relation.

URL: /relation/

Method: POST

Permissions required : Access to Settings section of the Umbraco Backoffice

Request

{
    "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
    "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
    "relationTypeAlias": "relateDocumentOnCopy",
    "comment": "Testing relations for relateDocumentOnCopy"
}

Success Response

Code: 201

Content Example:

{
    "_id": 4,
    "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
    "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
    "relationTypeAlias": "relateDocumentOnCopy",
    "comment": "Testing relations for relateDocumentOnCopy",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/4"
        }
    }
}

Delete relation

Delete a relation by its integer ID.

URL: /relation/{id}

Method: DELETE

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

DELETE https://api.umbraco.io/relation/4

{
    "_id": 4,
    "parentId": "af3e08fc-fb90-4c78-b11c-c1a0cf43bd31",
    "childId": "e0c5f0e5-c1f0-4422-9ac0-6dbb536e8eb5",
    "relationTypeAlias": "relateDocumentOnCopy",
    "comment": "Testing relations for relateDocumentOnCopy",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/relation/4"
        }
    }
}

Member Types

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Member Type with alias '{alias}' could not be found.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}

Get all member types

Get a list of all available member types.

URL: /member/type

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/type"
        },
        "membertypes": [
            {
                "href": "https://api.umbraco.io/member/type/Member"
            },
            {
                "href": "https://api.umbraco.io/member/type/shopMembers"
            }
        ]
    },
    "_embedded": {
        "membertypes": [
            {
                "alias": "Member",
                "compositions": [],
                "groups": [
                    {
                        "name": "Membership",
                        "sortOrder": 1,
                        "properties": [
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberComments",
                                "label": "Comments",
                                "propertyEditorAlias": "Umbraco.TextArea",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberFailedPasswordAttempts",
                                "label": "Failed Password Attempts",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberApproved",
                                "label": "Is Approved",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLockedOut",
                                "label": "Is Locked Out",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 3,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastLockoutDate",
                                "label": "Last Lockout Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 4,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastLogin",
                                "label": "Last Login Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 5,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastPasswordChangeDate",
                                "label": "Last Password Change Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 6,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "Member",
                "_createDate": "2019-09-20T12:07:43.987Z",
                "_id": "d59be02f-1df9-4228-aa1e-01917d806cda",
                "_updateDate": "2019-09-20T12:07:43.987Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/member/type/Member"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/member/type"
                    }
                }
            },
            {
                "alias": "shopMembers",
                "compositions": [],
                "groups": [
                    {
                        "name": "Shop Details",
                        "sortOrder": 0,
                        "properties": [
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": true,
                                "alias": "favouriteProduct",
                                "label": "Favourite Product",
                                "propertyEditorAlias": "Umbraco.TextBox",
                                "sortOrder": 0,
                                "validation": {
                                    "required": true
                                }
                            }
                        ]
                    },
                    {
                        "name": "Membership",
                        "sortOrder": 1,
                        "properties": [
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberComments",
                                "label": "Comments",
                                "propertyEditorAlias": "Umbraco.TextArea",
                                "sortOrder": 0,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberFailedPasswordAttempts",
                                "label": "Failed Password Attempts",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 1,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberApproved",
                                "label": "Is Approved",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 2,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLockedOut",
                                "label": "Is Locked Out",
                                "propertyEditorAlias": "Umbraco.TrueFalse",
                                "sortOrder": 3,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastLockoutDate",
                                "label": "Last Lockout Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 4,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastLogin",
                                "label": "Last Login Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 5,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberLastPasswordChangeDate",
                                "label": "Last Password Change Date",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 6,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberPasswordRetrievalAnswer",
                                "label": "Password Answer",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 7,
                                "validation": {
                                    "required": false
                                }
                            },
                            {
                                "isSensitive": false,
                                "memberCanEdit": false,
                                "memberCanView": false,
                                "alias": "umbracoMemberPasswordRetrievalQuestion",
                                "label": "Password Question",
                                "propertyEditorAlias": "Umbraco.Label",
                                "sortOrder": 8,
                                "validation": {
                                    "required": false
                                }
                            }
                        ]
                    }
                ],
                "name": "Shop Members",
                "_createDate": "2019-10-10T12:07:17.37Z",
                "_id": "ff345c85-dd87-49f2-a1de-ab7a23e54aea",
                "_updateDate": "2019-10-10T12:07:17.37Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/member/type/shopMembers"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/member/type"
                    }
                }
            }
        ]
    }
}

Get by alias

Get a specific member type by its alias.

URL: /member/type/{alias}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "alias": "Member",
    "compositions": [],
    "groups": [
        {
            "name": "Membership",
            "sortOrder": 1,
            "properties": [
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberComments",
                    "label": "Comments",
                    "propertyEditorAlias": "Umbraco.TextArea",
                    "sortOrder": 0,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberFailedPasswordAttempts",
                    "label": "Failed Password Attempts",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 1,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberApproved",
                    "label": "Is Approved",
                    "propertyEditorAlias": "Umbraco.TrueFalse",
                    "sortOrder": 2,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberLockedOut",
                    "label": "Is Locked Out",
                    "propertyEditorAlias": "Umbraco.TrueFalse",
                    "sortOrder": 3,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberLastLockoutDate",
                    "label": "Last Lockout Date",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 4,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberLastLogin",
                    "label": "Last Login Date",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 5,
                    "validation": {
                        "required": false
                    }
                },
                {
                    "isSensitive": false,
                    "memberCanEdit": false,
                    "memberCanView": false,
                    "alias": "umbracoMemberLastPasswordChangeDate",
                    "label": "Last Password Change Date",
                    "propertyEditorAlias": "Umbraco.Label",
                    "sortOrder": 6,
                    "validation": {
                        "required": false
                    }
                }
            ]
        }
    ],
    "name": "Member",
    "_createDate": "2019-09-20T12:07:43.987Z",
    "_id": "d59be02f-1df9-4228-aa1e-01917d806cda",
    "_updateDate": "2019-09-20T12:07:43.987Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/type/Member"
        },
        "root": {
            "href": "https://api.umbraco.io/member/type"
        }
    }
}

Content

BASE URL: https://cdn.umbraco.io

Table of Contents

Common Headers

Accept-Language: {culture}
Api-Version: 2
Umb-Project-Alias: {project-alias}

Depth

The depth querystring parameter controls how many levels of referenced Content or Media items that is included in the result.

Lets say a Content item have a Multi Node Tree Picker and one of the Content items that can be picked have a Media Picker. In this case, if the level is set to 1 the returned data will contain the referenced Content items, but their Media property will be null. To include the Media property (which is at level 2) the depth parameter should be 2 or higher.

The lowest supported depth value is 0 and the highest is 5.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

400

AmbiguousCulture

The following cultures were requested: {cultures}. At most, only a single culture may be specified. Please update the intended culture and retry the request.

400

LanguageForCultureNotFound

Could not find a language for culture {culture}.

401

Unauthorized

Authorization has been denied for this request.

404

NotFound

Published content with id '{id}' and culture '{culture}' could not be found.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "LanguageForCultureNotFound",
    "message": "Could not find a language for culture en-GB."
  }
}

Get root content

Gets all published content at the root of the tree.

URL: /content

Method: GET

Query Strings

?hyperlinks={boolean=true}
?contentType={string}

Success Response

Code: 200

Content Example:

{
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content"
    },
    "content": [
      {
        "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62"
      }
    ]
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/people/",
        "_urls": {
            "en-us": "/people/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": true,
        "_level": 1,
        "_createDate": "2019-06-17T13:46:24.543Z",
        "_id": "e8ad9b65-cff6-4952-ac5b-efe56a60db62",
        "_updateDate": "2019-06-17T13:46:54.97Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62"
          }
        },
        "contentTypeAlias": "people",
        "name": "People",
        "sortOrder": 1,
        "seoMetaDescription": "",
        "keywords": [],
        "umbracoNavihide": false,
        "pageTitle": "Nice crazy people",
        "featuredPeople": null
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/",
        "_urls": {
            "en-us": "/products/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": true,
        "_level": 1,
        "_createDate": "2019-06-17T13:46:24.093Z",
        "_id": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "_updateDate": "2019-09-17T14:43:14.827Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "products",
        "name": "Products",
        "sortOrder": 3,
        "seoMetaDescription": "",
        "keywords": [],
        "umbracoNavihide": false,
        "pageTitle": "Our Gorgeous Selection",
        "defaultCurrency": "€",
        "featuredProducts": [
          {
            "_creatorName": "Rasmus",
            "_url": "/products/biker-jacket/",
            "_writerName": "Rasmus",
            "_hasChildren": false,
            "_level": 2,
            "_createDate": "2019-06-17T13:46:24.497Z",
            "_id": "262beb70-53a6-49b8-9e98-cfde2e85a78e",
            "_updateDate": "2019-09-16T11:25:44.433Z",
            "_links": null,
            "contentTypeAlias": "product",
            "name": "Biker Jacket",
            "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
            "sortOrder": 7,
            "productName": "Biker Jacket",
            "price": 199.0,
            "description": "Donec rutrum congue leo eget malesuada. Vivamus suscipit tortor eget felis porttitor volutpat.",
            "sku": "UMB-BIKER-JACKET",
            "photos": null,
            "features": [
              {
                "contentTypeAlias": "feature",
                "featureName": "Free shipping",
                "featureDetails": "Isn't that awesome - you only pay for the product"
              },
              {
                "contentTypeAlias": "feature",
                "featureName": "1 Day return policy",
                "featureDetails": "You'll need to make up your mind fast"
              },
              {
                "contentTypeAlias": "feature",
                "featureName": "100 Years warranty",
                "featureDetails": "But if you're satisfied it'll last a lifetime"
              }
            ]
          },
          {
            "_creatorName": "Rasmus",
            "_url": "/products/tattoo/",
            "_urls": {
                "en-us": "/products/tattoo/"
            },
            "_writerName": "Rasmus",
            "_hasChildren": false,
            "_level": 2,
            "_createDate": "2019-06-17T13:46:24.14Z",
            "_id": "df1eb830-411b-4d41-a343-3917b76d533c",
            "_updateDate": "2019-06-26T22:11:05.727Z",
            "_links": null,
            "contentTypeAlias": "product",
            "name": "Tattoo",
            "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
            "sortOrder": 0,
            "productName": "Tattoo",
            "price": 499.0,
            "description": "Cras ultricies ligula sed magna dictum porta.",
            "sku": "UMB-TATTOO",
            "photos": null,
            "features": []
          },
          {
            "_creatorName": "Rasmus",
            "_url": "/products/unicorn/",
            "_urls": {
                "en-us": "/products/unicorn/"
            },
            "_writerName": "Rasmus",
            "_hasChildren": false,
            "_level": 2,
            "_createDate": "2019-06-17T13:46:24.187Z",
            "_id": "4e96411a-b8e1-435f-9322-2faee30ef5f2",
            "_updateDate": "2019-06-26T22:11:05.803Z",
            "_links": null,
            "contentTypeAlias": "product",
            "name": "Unicorn",
            "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
            "sortOrder": 1,
            "productName": "Unicorn",
            "price": 249.0,
            "description": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta.",
            "sku": "UMB-UNICORN",
            "photos": null,
            "features": []
          }
        ]
      }
    ]
  }
}

Get by id

Get a single published content by its ID.

URL: /content/{id}

Method: GET

Query Strings

?hyperlinks={boolean=true}
?depth={integer=1}

Success Response

Code: 200

Content Example:

{
  "_creatorName": "Rasmus",
  "_url": "/products/",
  "_urls": {
    "en-us": "/products/"
  },
  "_writerName": "Rasmus",
  "_hasChildren": true,
  "_level": 1,
  "_createDate": "2019-06-17T13:46:24.093Z",
  "_id": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
  "_updateDate": "2019-09-17T14:43:14.827Z",
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
    },
    "featuredproducts": [
      {
        "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e",
        "title": "Biker Jacket"
      },
      {
        "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c",
        "title": "Tattoo"
      },
      {
        "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2",
        "title": "Unicorn"
      }
    ],
    "root": {
      "href": "https://cdn.umbraco.io/content"
    },
    "children": {
      "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324/children"
    },
    "ancestors": {
      "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324/ancestors"
    },
    "descendants": {
      "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324/descendants"
    },
    "parent": {
      "href": "https://cdn.umbraco.io/content"
    }
  },
  "contentTypeAlias": "products",
  "name": "Products",
  "sortOrder": 3,
  "seoMetaDescription": "",
  "keywords": [],
  "umbracoNavihide": false,
  "pageTitle": "Our Gorgeous Selection",
  "defaultCurrency": "€",
  "featuredProducts": [
    {
      "_creatorName": "Rasmus",
      "_url": "/products/biker-jacket/",
      "_urls": {
        "en-us": "/products/biker-jacket/"
      },
      "_writerName": "Rasmus",
      "_hasChildren": false,
      "_level": 2,
      "_createDate": "2019-06-17T13:46:24.497Z",
      "_id": "262beb70-53a6-49b8-9e98-cfde2e85a78e",
      "_updateDate": "2019-09-16T11:25:44.433Z",
      "_links": {
        "photos": {
          "href": "https://cdn.umbraco.io/media/55514845-b8bd-487c-b370-9724852fd6bb",
          "title": "Biker Jacket"
        }
      },
      "contentTypeAlias": "product",
      "name": "Biker Jacket",
      "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
      "sortOrder": 7,
      "productName": "Biker Jacket",
      "price": 199.0,
      "description": "Donec rutrum congue leo eget malesuada. Vivamus suscipit tortor eget felis porttitor volutpat.",
      "sku": "UMB-BIKER-JACKET",
      "photos": null,
      "features": [
        {
          "contentTypeAlias": "feature",
          "featureName": "Free shipping",
          "featureDetails": "Isn't that awesome - you only pay for the product"
        },
        {
          "contentTypeAlias": "feature",
          "featureName": "1 Day return policy",
          "featureDetails": "You'll need to make up your mind fast"
        },
        {
          "contentTypeAlias": "feature",
          "featureName": "100 Years warranty",
          "featureDetails": "But if you're satisfied it'll last a lifetime"
        }
      ]
    },
    {
      "_creatorName": "Rasmus",
      "_url": "/products/tattoo/",
      "_urls": {
        "en-us": "/products/tattoo/"
      },
      "_writerName": "Rasmus",
      "_hasChildren": false,
      "_level": 2,
      "_createDate": "2019-06-17T13:46:24.14Z",
      "_id": "df1eb830-411b-4d41-a343-3917b76d533c",
      "_updateDate": "2019-06-26T22:11:05.727Z",
      "_links": {
        "photos": {
          "href": "https://cdn.umbraco.io/media/20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
          "title": "Tattoo"
        }
      },
      "contentTypeAlias": "product",
      "name": "Tattoo",
      "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
      "sortOrder": 0,
      "productName": "Tattoo",
      "price": 499.0,
      "description": "Cras ultricies ligula sed magna dictum porta.",
      "sku": "UMB-TATTOO",
      "photos": null,
      "features": []
    },
    {
      "_creatorName": "Rasmus",
      "_url": "/products/unicorn/",
      "_urls": {
        "en-us": "/products/unicorn/"
      },
      "_writerName": "Rasmus",
      "_hasChildren": false,
      "_level": 2,
      "_createDate": "2019-06-17T13:46:24.187Z",
      "_id": "4e96411a-b8e1-435f-9322-2faee30ef5f2",
      "_updateDate": "2019-06-26T22:11:05.803Z",
      "_links": {
        "photos": {
          "href": "https://cdn.umbraco.io/media/1bc5280b-8658-4027-89d9-58e2576e469b",
          "title": "Unicorn"
        }
      },
      "contentTypeAlias": "product",
      "name": "Unicorn",
      "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
      "sortOrder": 1,
      "productName": "Unicorn",
      "price": 249.0,
      "description": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta.",
      "sku": "UMB-UNICORN",
      "photos": null,
      "features": []
    }
  ]
}

Get by URL

Get a single published content by its URL.

URL: /content/url?url={url}

Method: GET

Query Strings

?hyperlinks={boolean=true}
?depth={integer=1}

Success Response

Code: 200

Content Example:

{
  "_creatorName": "Rasmus",
  "_url": "/people/",
  "_urls": {
    "en-us": "/people/"
  },
  "_writerName": "Rasmus",
  "_hasChildren": true,
  "_level": 1,
  "_createDate": "2019-06-17T13:46:24.543Z",
  "_id": "e8ad9b65-cff6-4952-ac5b-efe56a60db62",
  "_updateDate": "2019-06-17T13:46:54.97Z",
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62"
    }
  },
  "contentTypeAlias": "people",
  "name": "People",
  "sortOrder": 1,
  "seoMetaDescription": "",
  "keywords": [],
  "umbracoNavihide": false,
  "pageTitle": "Nice crazy people",
  "featuredPeople": null
}

Get by type

Get content by its Content Type.

Use the Content Type alias to filter all returned content to that specific type.

Example: GET /content/type?contentType=product gets all content based on the product Content Type.

URL: /content/type?contentType={string}

Method: GET

Query Strings

?hyperlinks={boolean=true}
?page={integer=1}
?pageSize={integer=10}

Success Response

Code: 200

Content Example:

{
  "_totalItems": 3,
  "_totalPages": 1,
  "_page": 1,
  "_pageSize": 10,
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/type?contentType=product&page=1&pageSize=10"
    },
    "page": {
      "href": "https://cdn.umbraco.io/content/type{?contentType,page,pageSize}",
      "templated": true
    },
    "root": {
      "href": "https://cdn.umbraco.io/content{?contentType}",
      "templated": true
    },
    "content": [
      {
        "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
      },
      {
        "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
      },
      {
        "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
      }
    ]
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/products/tattoo/",
        "_urls": {
          "en-us": "/products/tattoo/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.14Z",
        "_id": "df1eb830-411b-4d41-a343-3917b76d533c",
        "_updateDate": "2019-06-26T22:11:05.727Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
            "title": "Tattoo"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content{?contentType}",
            "templated": true
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Tattoo",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 0,
        "productName": "Tattoo",
        "price": 499.0,
        "description": "Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-TATTOO",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.503Z",
          "_id": "20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
          "_updateDate": "2019-06-17T13:46:42.503Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Tattoo",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 683,
          "umbracoHeight": 1024,
          "umbracoBytes": 258796,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/unicorn/",
        "_urls": {
          "en-us": "/products/unicorn/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.187Z",
        "_id": "4e96411a-b8e1-435f-9322-2faee30ef5f2",
        "_updateDate": "2019-06-26T22:11:05.803Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/1bc5280b-8658-4027-89d9-58e2576e469b",
            "title": "Unicorn"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content{?contentType}",
            "templated": true
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Unicorn",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 1,
        "productName": "Unicorn",
        "price": 249.0,
        "description": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-UNICORN",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.64Z",
          "_id": "1bc5280b-8658-4027-89d9-58e2576e469b",
          "_updateDate": "2019-06-17T13:46:42.64Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Unicorn",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1067,
          "umbracoHeight": 1600,
          "umbracoBytes": 367954,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/ping-pong-ball/",
        "_urls": {
          "en-us": "/products/ping-pong-ball/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.247Z",
        "_id": "d390a562-107d-4f02-8df7-57aa86bad752",
        "_updateDate": "2019-06-26T22:11:05.847Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/c09ec77f-08e3-466a-ac58-c979befd3cd6",
            "title": "Ping Pong Ball"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content{?contentType}",
            "templated": true
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Ping Pong Ball",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 2,
        "productName": "Ping Pong Ball",
        "price": 2.0,
        "description": "Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-PINGPONG",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.767Z",
          "_id": "c09ec77f-08e3-466a-ac58-c979befd3cd6",
          "_updateDate": "2019-06-17T13:46:42.767Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Ping Pong Ball",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1024,
          "umbracoHeight": 683,
          "umbracoBytes": 205417,
          "umbracoExtension": "jpg"
        },
        "features": []
      }
    ]
  }
}

Get ancestors

Get ancestors of a single published content.

URL: /content/{id}/ancestors

Method: GET

Query Strings

?hyperlinks={boolean=true}
?contentType={string}

Success Response

Code: 200

Content Example:

{
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/4f0b7052-d854-43b5-bb7c-6c82af4d96d1/ancestors"
    },
    "content": [
      {
        "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62"
      },
      {
        "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee"
      }
    ]
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/home/people/",
        "_urls": {
          "en-us": "/home/people/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": true,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.543Z",
        "_id": "e8ad9b65-cff6-4952-ac5b-efe56a60db62",
        "_updateDate": "2019-06-17T13:46:54.97Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/e8ad9b65-cff6-4952-ac5b-efe56a60db62/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee"
          }
        },
        "contentTypeAlias": "people",
        "name": "People",
        "parentId": "32ded4f8-191a-418e-a4c9-0dabceba90ee",
        "sortOrder": 0,
        "seoMetaDescription": "",
        "keywords": [],
        "umbracoNavihide": false,
        "pageTitle": "Nice crazy people",
        "featuredPeople": null
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/home/",
        "_urls": {
          "en-us": "/home/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": true,
        "_level": 1,
        "_createDate": "2019-06-17T13:46:24.012Z",
        "_id": "32ded4f8-191a-418e-a4c9-0dabceba90ee",
        "_updateDate": "2019-06-17T13:46:24.012Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/32ded4f8-191a-418e-a4c9-0dabceba90ee/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content"
          }
        },
        "contentTypeAlias": "home",
        "name": "Home",
        "sortOrder": 4
      }
    ]
  }
}

Get children

Get children of a single published content.

URL: /content/{id}/children

Method: GET

Query Strings

?hyperlinks={boolean=true}
?contentType={string}
?page={integer=1}
?pageSize={integer=10}

Success Response

Code: 200

Content Example:

{
  "_totalItems": 3,
  "_totalPages": 1,
  "_page": 1,
  "_pageSize": 10,
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324/children?page=1"
    },
    "page": {
      "href": "https://cdn.umbraco.io/content/{id}/children{?page,pageSize}",
      "templated": true
    },
    "root": {
      "href": "https://cdn.umbraco.io/content"
    },
    "content": [
      {
        "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
      },
      {
        "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
      },
      {
        "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
      }
    ]
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/products/tattoo/",
        "_urls": {
          "en-us": "/products/tattoo/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.14Z",
        "_id": "df1eb830-411b-4d41-a343-3917b76d533c",
        "_updateDate": "2019-06-26T22:11:05.727Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
            "title": "Tattoo"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Tattoo",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 0,
        "productName": "Tattoo",
        "price": 499.0,
        "description": "Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-TATTOO",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.503Z",
          "_id": "20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
          "_updateDate": "2019-06-17T13:46:42.503Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Tattoo",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 683,
          "umbracoHeight": 1024,
          "umbracoBytes": 258796,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/unicorn/",
        "_urls": {
          "en-us": "/products/unicorn/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.187Z",
        "_id": "4e96411a-b8e1-435f-9322-2faee30ef5f2",
        "_updateDate": "2019-06-26T22:11:05.803Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/1bc5280b-8658-4027-89d9-58e2576e469b",
            "title": "Unicorn"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Unicorn",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 1,
        "productName": "Unicorn",
        "price": 249.0,
        "description": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-UNICORN",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.64Z",
          "_id": "1bc5280b-8658-4027-89d9-58e2576e469b",
          "_updateDate": "2019-06-17T13:46:42.64Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Unicorn",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1067,
          "umbracoHeight": 1600,
          "umbracoBytes": 367954,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/ping-pong-ball/",
        "_urls": {
          "en-us": "/products/ping-pong-ball/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.247Z",
        "_id": "d390a562-107d-4f02-8df7-57aa86bad752",
        "_updateDate": "2019-06-26T22:11:05.847Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/c09ec77f-08e3-466a-ac58-c979befd3cd6",
            "title": "Ping Pong Ball"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Ping Pong Ball",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 2,
        "productName": "Ping Pong Ball",
        "price": 2.0,
        "description": "Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-PINGPONG",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.767Z",
          "_id": "c09ec77f-08e3-466a-ac58-c979befd3cd6",
          "_updateDate": "2019-06-17T13:46:42.767Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Ping Pong Ball",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1024,
          "umbracoHeight": 683,
          "umbracoBytes": 205417,
          "umbracoExtension": "jpg"
        },
        "features": []
      }
    ]
  }
}

Get descendants

Get descendants of a single published content.

URL: /content/{id}/descendants

Method: GET

Query Strings

?hyperlinks={boolean=true}
?contentType={string}
?page={integer=1}
?pageSize={integer=10}

Success Response

Code: 200

Content Example:

{
  "_totalItems": 3,
  "_totalPages": 1,
  "_page": 1,
  "_pageSize": 10,
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324/descendants?page=1"
    },
    "page": {
      "href": "https://cdn.umbraco.io/content/{id}/descendants{?page,pageSize}",
      "templated": true
    },
    "root": {
      "href": "https://cdn.umbraco.io/content"
    },
    "content": [
      {
        "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
      },
      {
        "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
      },
      {
        "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
      }
    ]
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/products/tattoo/",
        "_urls": {
          "en-us": "/products/tattoo/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.14Z",
        "_id": "df1eb830-411b-4d41-a343-3917b76d533c",
        "_updateDate": "2019-06-26T22:11:05.727Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
            "title": "Tattoo"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/df1eb830-411b-4d41-a343-3917b76d533c/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Tattoo",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 0,
        "productName": "Tattoo",
        "price": 499.0,
        "description": "Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-TATTOO",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.503Z",
          "_id": "20e3a8ff-ad1b-4fe9-b48c-b8461c46d2d0",
          "_updateDate": "2019-06-17T13:46:42.503Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Tattoo",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/20e3a8ffad1b4fe9b48cb8461c46d2d0/00000006000000000000000000000000/7371127652_e01b6ab56f_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 683,
          "umbracoHeight": 1024,
          "umbracoBytes": 258796,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/unicorn/",
        "_urls": {
          "en-us": "/products/unicorn/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.187Z",
        "_id": "4e96411a-b8e1-435f-9322-2faee30ef5f2",
        "_updateDate": "2019-06-26T22:11:05.803Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/1bc5280b-8658-4027-89d9-58e2576e469b",
            "title": "Unicorn"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/4e96411a-b8e1-435f-9322-2faee30ef5f2/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Unicorn",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 1,
        "productName": "Unicorn",
        "price": 249.0,
        "description": "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-UNICORN",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.64Z",
          "_id": "1bc5280b-8658-4027-89d9-58e2576e469b",
          "_updateDate": "2019-06-17T13:46:42.64Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Unicorn",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/1bc5280b8658402789d958e2576e469b/00000006000000000000000000000000/14272036539_469ca21d5c_h.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1067,
          "umbracoHeight": 1600,
          "umbracoBytes": 367954,
          "umbracoExtension": "jpg"
        },
        "features": []
      },
      {
        "_creatorName": "Rasmus",
        "_url": "/products/ping-pong-ball/",
        "_urls": {
          "en-us": "/products/ping-pong-ball/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.247Z",
        "_id": "d390a562-107d-4f02-8df7-57aa86bad752",
        "_updateDate": "2019-06-26T22:11:05.847Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/c09ec77f-08e3-466a-ac58-c979befd3cd6",
            "title": "Ping Pong Ball"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/d390a562-107d-4f02-8df7-57aa86bad752/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Ping Pong Ball",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 2,
        "productName": "Ping Pong Ball",
        "price": 2.0,
        "description": "Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ultricies ligula sed magna dictum porta.",
        "sku": "UMB-PINGPONG",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.767Z",
          "_id": "c09ec77f-08e3-466a-ac58-c979befd3cd6",
          "_updateDate": "2019-06-17T13:46:42.767Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Ping Pong Ball",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/c09ec77f08e3466aac58c979befd3cd6/00000006000000000000000000000000/5852022211_9028df67c0_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 1024,
          "umbracoHeight": 683,
          "umbracoBytes": 205417,
          "umbracoExtension": "jpg"
        },
        "features": []
      }
    ]
  }
}

Content Filter

Get content filtered by property values and optionally content type.

This endpoint can be used for advanced filtering of content based on the value of specific properties. You can choose to filter on one or more properties by their alias and a value. The matching criteria include whether the property contains or is like the passed-in value.

Say you have a property with an alias called "title" and you want all content, which contains the word "world". The payload you post to the /content/filter endpoint would be as shown below.

{
  "contentTypeAlias": "",
  "properties": [{
    "alias": "title",
    "value": "world",
    "match": "CONTAINS"
  }]
}

Setting the above properties to "hello world" results in content with a "title" property containing either "hello" or "world" as values.

If you want the value of a property to match on both "page" and "pages" then you could use like with a payload as shown below.

{
  "contentTypeAlias": "",
  "properties": [{
    "alias": "title",
    "value": "page",
    "match": "LIKE"
  }]
}

Filtering is performed on individual content items, indicating that content matching is not conducted on related content or media.

URL: /content/filter

Method: POST

Query Strings

?hyperlinks={boolean=true}
?page={integer=1}
?pageSize={integer=10}

Headers

This endpoint is available from API-Version: 2.1. Specify the header as shown below when using the REST API.

Api-Version: 2.1
Umb-Project-Alias: {project-alias}

Request

In this example, we perform a filter with criteria for a "productName"-property containing the value "Jacket" and a "description"-property containing the value "Vivamus". Additionally, the Document Type should have the alias "product."

At least one object with alias, value and match in the properties array is required. The contentTypeAlias is optional and the match property can be either CONTAINS or LIKE.

{
  "contentTypeAlias": "product",
  "properties": [{
    "alias": "productName",
    "value": "Jacket",
    "match": "CONTAINS"
  },
  {
    "alias": "description",
    "value": "Vivamus",
    "match": "CONTAINS"
  }]
}

Success Response

Code: 200

Content Example:

{
  "_totalItems": 1,
  "_totalPages": 1,
  "_page": 1,
  "_pageSize": 10,
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/filter?page=1&pageSize=10"
    },
    "page": {
      "href": "https://cdn.umbraco.io/content/filter{?page,pageSize}",
      "templated": true
    },
    "root": {
      "href": "https://cdn.umbraco.io/content{?contentType}"
    },
    "content": {
      "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e"
    }
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/products/biker-jacket/",
        "_urls": {
          "en-us": "/products/biker-jacket/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.497Z",
        "_id": "262beb70-53a6-49b8-9e98-cfde2e85a78e",
        "_updateDate": "2019-09-16T11:25:44.433Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/55514845-b8bd-487c-b370-9724852fd6bb",
            "title": "Biker Jacket"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Biker Jacket",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 7,
        "productName": "Biker Jacket",
        "price": 199.0,
        "description": "Donec rutrum congue leo eget malesuada. Vivamus suscipit tortor eget felis porttitor volutpat.",
        "sku": "UMB-BIKER-JACKET",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/55514845b8bd487cb3709724852fd6bb/00000006000000000000000000000000/4730684907_8a7f8759cb_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.377Z",
          "_id": "55514845-b8bd-487c-b370-9724852fd6bb",
          "_updateDate": "2019-06-17T13:46:42.377Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Biker Jacket",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/55514845b8bd487cb3709724852fd6bb/00000006000000000000000000000000/4730684907_8a7f8759cb_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 680,
          "umbracoHeight": 1024,
          "umbracoBytes": 224349,
          "umbracoExtension": "jpg"
        },
        "features": [
          {
            "contentTypeAlias": "feature",
            "featureName": "Free shipping",
            "featureDetails": "Isn't that awesome - you only pay for the product"
          },
          {
            "contentTypeAlias": "feature",
            "featureName": "1 Day return policy",
            "featureDetails": "You'll need to make up your mind fast"
          },
          {
            "contentTypeAlias": "feature",
            "featureName": "100 Years warranty",
            "featureDetails": "But if you're satisfied it'll last a lifetime"
          }
        ]
      }
    ]
  }
}

Search

Search for published content by keyword.

URL: /content/search?term={string}

Method: GET

Query Strings

?hyperlinks={boolean=true}
?page={integer=1}
?pageSize={integer=10}

Success Response

Code: 200

Content Example:

{
  "_totalItems": 1,
  "_totalPages": 1,
  "_page": 1,
  "_pageSize": 10,
  "_links": {
    "self": {
      "href": "https://cdn.umbraco.io/content/search?term=jacket&page=1&pageSize=10"
    },
    "page": {
      "href": "https://cdn.umbraco.io/content/search{?term,page,pageSize}",
      "templated": true
    },
    "root": {
      "href": "https://cdn.umbraco.io/content"
    },
    "content": {
      "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e"
    }
  },
  "_embedded": {
    "content": [
      {
        "_creatorName": "Rasmus",
        "_url": "/products/biker-jacket/",
        "_urls": {
          "en-us": "/products/biker-jacket/"
        },
        "_writerName": "Rasmus",
        "_hasChildren": false,
        "_level": 2,
        "_createDate": "2019-06-17T13:46:24.497Z",
        "_id": "262beb70-53a6-49b8-9e98-cfde2e85a78e",
        "_updateDate": "2019-09-16T11:25:44.433Z",
        "_links": {
          "self": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e"
          },
          "photos": {
            "href": "https://cdn.umbraco.io/media/55514845-b8bd-487c-b370-9724852fd6bb",
            "title": "Biker Jacket"
          },
          "root": {
            "href": "https://cdn.umbraco.io/content"
          },
          "children": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/children"
          },
          "ancestors": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/ancestors"
          },
          "descendants": {
            "href": "https://cdn.umbraco.io/content/262beb70-53a6-49b8-9e98-cfde2e85a78e/descendants"
          },
          "parent": {
            "href": "https://cdn.umbraco.io/content/ec4aafcc-0c25-4f25-a8fe-705bfae1d324"
          }
        },
        "contentTypeAlias": "product",
        "name": "Biker Jacket",
        "parentId": "ec4aafcc-0c25-4f25-a8fe-705bfae1d324",
        "sortOrder": 7,
        "productName": "Biker Jacket",
        "price": 199.0,
        "description": "Donec rutrum congue leo eget malesuada. Vivamus suscipit tortor eget felis porttitor volutpat.",
        "sku": "UMB-BIKER-JACKET",
        "photos": {
          "_creatorName": "Rasmus",
          "_url": "https://media.umbraco.io/my-headless-site/media/55514845b8bd487cb3709724852fd6bb/00000006000000000000000000000000/4730684907_8a7f8759cb_b.jpg",
          "_writerName": "Rasmus",
          "_hasChildren": false,
          "_level": 2,
          "_createDate": "2019-06-17T13:46:42.377Z",
          "_id": "55514845-b8bd-487c-b370-9724852fd6bb",
          "_updateDate": "2019-06-17T13:46:42.377Z",
          "_links": null,
          "mediaTypeAlias": "Image",
          "name": "Biker Jacket",
          "parentId": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
          "sortOrder": 0,
          "umbracoFile": {
            "src": "/media/55514845b8bd487cb3709724852fd6bb/00000006000000000000000000000000/4730684907_8a7f8759cb_b.jpg",
            "focalPoint": null,
            "crops": null
          },
          "umbracoWidth": 680,
          "umbracoHeight": 1024,
          "umbracoBytes": 224349,
          "umbracoExtension": "jpg"
        },
        "features": [
          {
            "contentTypeAlias": "feature",
            "featureName": "Free shipping",
            "featureDetails": "Isn't that awesome - you only pay for the product"
          },
          {
            "contentTypeAlias": "feature",
            "featureName": "1 Day return policy",
            "featureDetails": "You'll need to make up your mind fast"
          },
          {
            "contentTypeAlias": "feature",
            "featureName": "100 Years warranty",
            "featureDetails": "But if you're satisfied it'll last a lifetime"
          }
        ]
      }
    ]
  }
}

Schema Generation

Documentation for Umbraco Heartcore GraphQL schema generation

The GraphQL schema is generated from the Content Types upon creation, and it is generated when a Content Type or a Data Type is changed.

The type name is the Content Type's alias in Pascal Case, e.g. if a Content Type has an alias of product it's GraphQL type name would be Product.

Table of Contents

Types

The types generated depends on how the Content Types are configured.

interface NavigationBase {
  seoMetaDescription: String
  umbracoNavihide: Boolean
}
type Feature implements Element {
  contentTypeAlias: String!
  featureName: String
  featureDescription: String
}
type Product implements Content & NavigationBase {
  ancestors(...): ContentConnection!
  category: [String]
  children(...): ContentConnection!
  contentTypeAlias: String!
  createDate: DateTime!
  descendants(...): ContentConnection!
  description: String
  features: [Element]
  id: ID!
  level: Int!
  name: String
  parent: Content
  photos: Media
  price: Decimal
  productName: String
  sku: String
  sortOrder: Int!
  seoMetaDescription: String
  umbracoNavihide: Boolean
  updateDate: DateTime
  url: String
}

A Connection and an Edge type will also be generated, these are used when quering Content of a specific type.

type ProductConnection {
  edges: [ProductEdge]
  pageInfo: PageInfo
}

type ProductEdge {
  cursor: String!
  node: Product
}

Fields

type Product implements Content & NavigationBase {
  ...
  productName(culture: String): String
  ...
}

Root Query

The Query type is the entry to the GraphQL API. By default it contains two fields, one to get a single Content item by ID or url and one to get all Content.

type Query {
  """
  Get Content by its unique identifier or url. Either id or url must be specified but not both.
  """
  content(
    """
    The unique identifier of the content.
    """
    id: ID,
    """
    The url of the content.
    """
    url: String,
    """
    The culture to fetch the content in. If empty the default culture will be used.
    """
    culture: String
    """
    Specifies if draft content should be returned. Requires the request to be authenticated.
    """
    preview: Boolean
  ): Content
  """
  Get all Content.
  """
  allContent(
    """
    Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
    """
    first: Int,
    """
    Only look at connected edges with cursors greater than the value of `after`.
    """
    after: String,
    """
    Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
    """
    last: Int,
    """
    Only look at connected edges with cursors smaller than the value of `before`.
    """
    before: String,
    """
    The culture to fetch the value in. If empty the default culture will be used.
    """
    culture: String,
    """
    Specifies if draft content should be returned. Requires the request to be authenticated.
    """
    preview: Boolean
    """
    Filter the returned data.
    """
    where: ContentFilterInput,
    """
    Sort the returned data.
    """
    orderBy: [ContentOrderByInput]
  ): ContentConnection!
}

For each Document Type that is not used as a Composition or marked as an Element Type, two fields will be generated on the Query type. One for getting a single Content item by either it's ID or url and a field for getting all Content of that specific type.

type Query {
  ...
  allProduct(first: Int, after: String, last: Int, before: String, culture: String, preview: Boolean, where: ProductFilterInput, orderBy: [ProductOrderByInput]): ProductConnection!
  product(culture: String, id: ID, url: String, preview: Boolean): Product
  ...
}

Reserved Type Names and Property Aliases

GraphQL requires that type names are unique. If a Content Type will collide with one of the reserved names the type will be excluded from generation.

The same applies to Properties. If a Property alias is a reserved one it will also be excluded from generation.

Reserved Type Names

List of reserved type names, these cannot be used as an alias for Content Types.

The GraphQL type name is the Content Type alias converted to Pascal Case.

  • BigInt

  • BlockGrid

  • BlockGridArea

  • BlockGridItem

  • BlockListItem

  • Byte

  • Content

  • Date

  • DateTime

  • DateTimeOffset

  • Decimal

  • DecimalRange

  • Element

  • Guid

  • HTML

  • ImageCropAnchor

  • ImageCropFormat

  • ImageCropMode

  • ImageCropper

  • ImageCropperCrop

  • ImageCropperCropCoordinates

  • ImageCropperFocalPoint

  • ImageCropRatioMode

  • JSON

  • Link

  • LinkType

  • Long

  • Media

  • MediaConnection

  • MediaEdge

  • Milliseconds

  • OurUmbracoGMaps

  • OurUmbracoGMapsAddress

  • OurUmbracoGMapsCoordinate

  • OurUmbracoGMapsMapConfig

  • OurUmbracoGMapsMapType

  • PageInfo

  • PickedColor

  • Query

  • SByte

  • Seconds

  • Short

  • UInt

  • ULong

  • Uri

  • UShort

Reserved Element Type Property Names

List of reserved Element Type Property names, these cannot be used as a Property alias on an Element Type.

  • contentTypeAlias

Reserved Content Type Property Names

List of reserved Content Type Property names, these cannot be used as a Property alias on a Content Type.

  • ancestors

  • children

  • contentTypeAlias

  • createDate

  • descendants

  • id

  • level

  • name

  • parent

  • content

  • parentId

  • sortOrder

  • updateDate

  • url

Reserved Media Type Property Names

List of reserved Media Type Property names, these cannot be used as a Property alias on a Media Type.

  • ancestors

  • children

  • createDate

  • descendants

  • id

  • level

  • mediaTypeAlias

  • name

  • parent

  • sortOrder

  • updateDate

  • url

Built-in Custom Types

The Umbraco Heartcore GraphQL schema contains some default types, below you can find a list of these types.

Block Grid

type BlockGrid {
    """
    Items in the grid.
    """
    items: [BlockGridItem]!

    """
    Number of columns in the grid.
    """
    gridColumns: Int!
}

Query

{
  contentPage {
    blocks {
      gridColumns
    }
  }
}

Output

{
  "data": {
    "contentPage": {
      "blocks": {
        "gridColumns": 12
      }
    }
  }
}

Block Grid Area

type BlockGridArea {
    """
    Name of the area.
    """
    alias: String!

    """
    Items in the area.
    """
    items: [BlockGridItem]!

    """
    Number of rows spanned by the area.
    """
    rowSpan: Int!

    """
    Number of columns spanned by the area.
    """
    columnSpan: Int!
}

Query

{
  contentPage {
    blocks {
      items {
        areas: {
          alias
          columnSpan
          items {
            title
          }
        }
      }
    }
  }
}

Output

{
  "data": {
    "contentPage": {
      "blocks": {
        "items": [{
          "areas": [{
            "alias": "mainArea",
            "columnSpan": 12,
            "items": [{
              "title": "Essential Heartcore Tips: Volume 4"
            }]
          }]
        }]
      }
    }
  }
}

Block Grid Item

type BlockGridItem {
    """
    The content.
    """
    content: Element!

    """
    The settings.
    """
    settings: Element

    """
    Number of rows spanned by the item.
    """
    rowSpan: Int!

    """
    Number of columns spanned by the item.
    """
    columSpan: Int!

    """
    Number of columns in child areas.
    """
    areaGridColumns: Int!

    """
    Number of columns in child areas.
    """
    areas: [BlockGridArea]
}

Query

{
  contentPage {
    blocks {
      items: {
        content: {
          title
        }
        settings: {
          openLinkInNewTab
        }
        rowSpan
        columnSpan
      }
    }
  }
}

Output

{
  "data": {
    "contentPage": {
      "blocks": {
        "items": [{
          "content": {
            "title": "Essential Heartcore Tips: Volume 7"
          },
          "settings": {
            "openLinkInNewTab": false
          },
          "rowSpan": 1,
          "columnSpan": 4
        }]
      }
    }
  }
}

Block List Item

type BlockListItem {
    """
    The content.
    """
    content: Element!

    """
    The settings.
    """
    settings: Element
}

Query

{
  textPage {
    elements {
      content {
        title
      }
      settings {
        showLargeImage
      }
    }
  }
}

Output:

{
  "data": {
    "textPage": {
      "elements": [{
        "content": {
          "title": "Why use Umbraco Heartcore?"
        },
        "settings" {
          "showLargeImage": true
        }
      }]
    }
  }
}

Decimal Range

# Represents a range of decimals.
type DecimalRange {
  """
  Maximum value of the range.
  """
  maximum: Decimal!
  """
  Minimum value of the range.
  """
  minimum: Decimal!
}

Query:

{
  product {
    durability {
      minimum
      maximum
    }
  }
}

Output:

{
  "data": {
    "product": {
      "durability": {
        "minimum": 7,
        "maximum": 10
      }
    }
  }
}

HTML

"""
A string containing HTML code.
"""
scalar HTML

Query:

{
  product {
    description
  }
}

Output:

{
  "data": {
    "product": {
      "description": "<p>A nice leather jacket.</p>"
    }
  }
}

Image Cropper

type ImageCropper {
  """
  The predefined crops.
  """
  crops: [ImageCropperCrop]!
  """
  The image url with crop parameters.
  """
  cropUrl(
    """
    The crop alias.
    """
    alias: String
    """
    Change background color of the image.
    """
    backgroundColor: String
    """
    The width of the output image.
    """
    width: Int
    """
    The height of the output image.
    """
    height: Int
    """
    Quality percentage of the output image.
    """
    quality: Int
    """
    The image crop mode.
    """
    cropMode: ImageCropMode
    """
    The image crop anchor.
    """
    cropAnchor: ImageCropAnchor
    """
    Use a dimension as a ratio.
    """
    ratioMode: ImageCropRatioMode
    """
    The format of the output image.
    """
    format: ImageCropFormat
    """
    Use focal point to generate an output image using the focal point instead of the predefined crop if there is one.
    """
    preferFocalPoint: Boolean = false
    """
    If the image should be upscaled to requested dimensions.
    """
    upscale: Boolean = false
  ): String
  """
  The focal point position.
  """
  focalPoint: ImageCropperFocalPoint!
  """
  The focal point url template.
   """
  focalPointUrlTemplate: String!
  """
  The image url.
  """
  url: String!
}

Query:

{
  product {
    photo {
      cropUrl(width: 1980, height: 430)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=center&mode=crop&width=1980&height=430&upscale=false"
      }
    }
  }
}

Image Crop Anchor

enum ImageCropAnchor {
  """
  Anchors the position of the image to the bottom of it's bounding container.
  """
  BOTTOM
  """
  Anchors the position of the image to the bottom left side of it's bounding container.
  """
  BOTTOM_LEFT
  """
  Anchors the position of the image to the bottom right side of it's bounding container.
  """
  BOTTOM_RIGHT
  """
  Anchors the position of the image to the center of it's bounding container.
  """
  CENTER
  """
  Anchors the position of the image to the left of it's bounding container.
  """
  LEFT
  """
  Anchors the position of the image to the right of it's bounding container.
  """
  RIGHT
  """
  Anchors the position of the image to the top of it's bounding container.
  """
  TOP
  """
  Anchors the position of the image to the top left side of it's bounding container.
  """
  TOP_LEFT
  """
  Anchors the position of the image to the top right side of it's bounding container.
  """
  TOP_RIGHT
}

Query:

{
  product {
    photo {
      cropUrl(width:1980, height: 430, cropAnchor: TOP_LEFT)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=topleft&mode=crop&width=1980&height=430&upscale=false"
      }
    }
  }
}

Image Crop Format

enum ImageCropFormat {
  PNG
  JPG
  GIF
  WEBP
}

Query:

{
  product {
    photo {
      cropUrl(width:1980, height: 430, format: WEBP)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=center&mode=crop&width=1980&height=430&upscale=false&format=webp"
      }
    }
  }
}

Image Crop Mode

enum ImageCropMode {
  """
  When upscaling an image the image pixels themselves are not resized, rather the image is padded to fit the given dimensions.
  """
  BOX_PAD
  """
  Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is cropped to match the new aspect ratio.
  """
  CROP
  """
  Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is resized to the maximum possible value in each direction while maintaining the original aspect ratio.
  """
  MAX
  """
  Resizes the image until the shortest side reaches the set given dimension. This will maintain the aspect ratio of the original image. Upscaling is disabled in this mode and the original image will be returned if attempted.
  """
  MIN
  """
  Passing a single dimension will automatically preserve the aspect ratio of the original image. If the requested aspect ratio is different then the image will be padded to fit.
  """
  PAD
  """
  Resizes the image to the given dimensions. If the set dimensions do not match the aspect ratio of the original image then the output is stretched to match the new aspect ratio.
  """
  STRETCH
}

Query:

{
  product {
    photo {
      cropUrl(width:1980, height: 430, cropMode: PAD)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=center&mode=pad&width=1980&height=430&upscale=false"
      }
    }
  }
}

Image Crop Ratio Mode

enum ImageCropRatioMode {
  """
  Calculate the image ratio based on the height.
  """
  HEIGHT
  """
  Calculate the image ratio based on the width.
  """
  WIDTH
}

Query:

{
  product {
    photo {
      cropUrl(width:1980, height: 430, ratioMode: WIDTH)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=center&mode=crop&height=430&widthratio=4.6046511627906976744186046512&upscale=false"
      }
    }
  }
}

Image Cropper Crop

type ImageCropperCrop {
  """
  The crop alias.
  """
  alias: String!
  """
  The crop coordinates.
  """
  coordinates: ImageCropperCropCoordinates
  """
  The crop height.
  """
  height: Int!
  """
  The crop width.
  """
  width: Int!
}

Query:

{
  product {
    photo {
      crops {
        alias
        height
        width
      }
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "crops": {
          "alias": "Hero",
          "height": 600,
          "width": 1580
        }
      }
    }
  }
}

Image Cropper Crop Coordinates

type ImageCropperCropCoordinates {
  x1: Decimal!
  x2: Decimal!
  y1: Decimal!
  y2: Decimal!
}

Query:

{
  product {
    photo {
      crops {
        coordinates {
          x1
          x2
          y1
          y2
        }
      }
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "crops": {
          "coordinates": {
            "x1": 0.08901424149934925,
            "x2": 0.055992598445931165,
            "y1": 0.3183501211863771,
            "y2": 0.4660414375419126
          }
        }
      }
    }
  }
}

Image Cropper Focal Point

type ImageCropperFocalPoint {
  """
  The left position.
  """
  left: Decimal!
  """
  The top position.
  """
  top: Decimal!
}

Query:

{
  product {
    photo {
      focalPoint {
        left
        top
      }
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "focalPoint": {
          "left": 0.5,
          "top": 0.5
        }
      }
    }
  }
}

JSON

"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON

Query:

{
  product {
    data
  }
}

Output:

{
  "data": {
    "product": {
      "data": {
        "size": "100x100x100 mm",
        "weight": "300 g"
      }
    }
  }
}

Link

type Link {
  """
  The name of the Link.
  """
  name: String!
  """
  The link target.
  """
  target: String
  """
  The link type.
  """
  type: LintType!
  """
  The link udi if type is CONTENT or MEDIA.
  """
  udi: String
  """
  The url.
  """
  url: String!
}

Query:

{
  product {
    link {
      name
      target
      type
      udi
      url
    }
  }
}

Output:

{
  "data": {
    "product": {
      "link": {
        "name": "Umbraco",
        "target": "_blank",
        "type": "EXTERNAL",
        "udi": null,
        "url": "https://umbraco.com/"
      }
    }
  }
}

Link Type

enum LintType {
  """
  The link is a Content link.
  """
  CONTENT
  """
  The link is an external link.
  """
  EXTERNAL
  """
  The link is a media link.
  """
  MEDIA
}

Query:

{
  product {
    link {
      type
    }
  }
}

Output:

{
  "data": {
    "product": {
      "link": {
        "type": "CONTENT"
      }
    }
  }
}

Media With Crops

type MediaWithCrops {
  """
  The predefined crops.
  """
  crops: [ImageCropperCrop]!
  """
  The image url with crop parameters.
  """
  cropUrl(
    """
    The crop alias.
    """
    alias: String
    """
    Change background color of the image.
    """
    backgroundColor: String
    """
    The width of the output image.
    """
    width: Int
    """
    The height of the output image.
    """
    height: Int
    """
    Quality percentage of the output image.
    """
    quality: Int
    """
    The image crop mode.
    """
    cropMode: ImageCropMode
    """
    The image crop anchor.
    """
    cropAnchor: ImageCropAnchor
    """
    Use a dimension as a ratio.
    """
    ratioMode: ImageCropRatioMode
    """
    The format of the output image.
    """
    format: ImageCropFormat
    """
    Use focal point to generate an output image using the focal point instead of the predefined crop if there is one.
    """
    preferFocalPoint: Boolean = false
    """
    If the image should be upscaled to requested dimensions.
    """
    upscale: Boolean = false
  ): String
  """
  The focal point position.
  """
  focalPoint: ImageCropperFocalPoint!
  """
  The focal point url template.
  """
  focalPointUrlTemplate: String!
  """
  The media
  """
  media: Media!
  """
  The image url.
  """
  url: String!
}

Query:

{
  product {
    photo {
      cropUrl(width: 1980, height: 430)
    }
  }
}

Output:

{
  "data": {
    "product": {
      "photo": {
        "cropUrl": "https://media.umbraco.io/demo-headless/8d76d2e84a24637/new-color-umbraco-stickers-1.jpg?anchor=center&mode=crop&width=1980&height=430&upscale=false"
      }
    }
  }
}

Our Umbraco GMaps

type OurUmbracoGMaps {
  address: OurUmbracoGMapsAddress
  mapconfig: OurUmbracoGMapsMapConfig
}

Query:

{
  frontpage {
    location {
      address {
        coordinates {
          lat
          lng
        }
      }
      mapconfig {
        zoom
      }
    }
  }
}

Output:

{
  "data": {
    "frontpage": {
      "location": {
        "address": {
          "lat": 55.4063759,
          "lng": 10.3887197
        },
        "mapconfig": {
          "zoom": 19
        }
      }
    }
  }
}

Our Umbraco GMaps Address

type OurUmbracoGMapsAddress {
  coordinates: OurUmbracoGMapsCoordinate
}

Query:

{
  frontpage {
    location {
      address {
        coordinates {
          lat
          lng
        }
      }
    }
  }
}

Output:

{
  "data": {
    "frontpage": {
      "location": {
        "address": {
          "lat": 55.4063759,
          "lng": 10.3887197
        }
      }
    }
  }
}

Our Umbraco GMaps Config

type OurUmbracoGMapsMapConfig {
  apikey: String
  zoom: Int
  centerCoordinates: OurUmbracoGMapsCoordinate
  maptype: OurUmbracoGMapsMapType
  mapstyle: JSON
}

Query:

{
  frontpage {
    location {
      mapconfig {
        apikey
        zoom
        centerCoordinates {
          lat
          lng
        }
        maptype
      }
    }
  }
}

Output:

{
  "data": {
    "frontpage": {
      "location": {
        "mapconfig": {
          "apikey": "my-api-key",
          "zoom": 19,
          "centerCoordinates": {
            "lat": 55.4063759,
            "lng": 10.3887197
          },
          "maptype": "satellite"
        }
      }
    }
  }
}

Our Umbraco GMaps Coordinate

type OurUmbracoGMapsCoordinate {
  coordinates: String
  lat: Decimal
  lng: Decimal
  isEmpty: Boolean
}

Query:

{
  frontpage {
    location {
      address {
        coordinates {
          coordinates
          lat
          lng
          isEmpty
        }
      }
    }
  }
}

Output:

{
  "data": {
    "frontpage": {
      "location": {
        "address": {
          "coordinates": "55.4063759,10.3887197",
          "lat": 55.4063759,
          "lng": 10.3887197,
          "isEmpty": false
        }
      }
    }
  }
}

Our Umbraco GMaps Map Type

enum OurUmbracoGMapsMapType {
  roadmap
  satellite
  hybrid
  terrain
  styled_map
}

Page Info

"""
Information about pagination in a connection.
"""
type PageInfo {
  """
  When paginating forwards, the cursor to continue.
  """
  endCursor: String
  """
  When paginating forwards, are there more items?
  """
  hasNextPage: Boolean!
  """
  When paginating backwards, are there more items?
  """
  hasPreviousPage: Boolean!
  """
  When paginating backwards, the cursor to continue.
  """
  startCursor: String
}

Query:

{
  allProduct(first: 2) {
    pageInfo {
      endCursor
      hasNextPage
      hasPreviousPage
      startCursor
    }
  }
}

Output:

{
  "data": {
    "allProduct": {
      "pageInfo": {
        "endCursor": "eyJ0cmVlUGF0aCI6WzYsMV19",
        "hasNextPage": true,
        "hasPreviousPage": false,
        "startCursor": "eyJ0cmVlUGF0aCI6WzYsMF19"
      }}
    }
  }
}

Picked Color

type PickedColor {
  """
  The color.
  """
  color: String!
  """
  The label.
  """
  label: String!
}

Query:

{
  product {
    color
  }
}

Output:

{
  "data": {
    "product": {
      "color": {
        "color": "ff0000",
        "label": "Red"
      }
    }
  }
}

Element

interface Element {
  """
  The Content Type alias.
  """
  contentTypeAlias: String!
}

Query:

{
  product {
    features {
      contentTypeAlias
    }
  }
}

Output:

{
  "data": {
    "product": {
      "features": {
        "contentTypeAlias": "feature"
      }
    }
  }
}

Content

interface Content {
    """
    The ancestors.
    """
    ancestors(
        """
        Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
        """
        first: Int,
        """
        Only look at connected edges with cursors greater than the value of `after`.
        """
        after: String,
        """
        Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
        """
        last: Int,
        """
        Only look at connected edges with cursors smaller than the value of `before`.
        """
        before: String
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
        """
        Filter the returned data.
        """
        where: ContentFilterInput,
        """
        Sort the returned data.
        """
        orderBy: [ContentOrderByInput],
    ): ContentConnection!
    """
    The children.
    """
    children(
        """
        Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
        """
        first: Int,
        """
        Only look at connected edges with cursors greater than the value of `after`.
        """
        after: String,
        """
        Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
        """
        last: Int,
        """
        Only look at connected edges with cursors smaller than the value of `before`.
        """
        before: String
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
        """
        Filter the returned data.
        """
        where: ContentFilterInput,
        """
        Sort the returned data.
        """
        orderBy: [ContentOrderByInput],
    ): ContentConnection!
    """
    The Content Type alias.
    """
    contentTypeAlias: String!
    """
    The create date.
    """
    createDate: DateTime!
    """
    The descendants.
    """
    descendants(
        """
        Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
        """
        first: Int,
        """
        Only look at connected edges with cursors greater than the value of `after`.
        """
        after: String,
        """
        Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
        """
        last: Int,
        """
        Only look at connected edges with cursors smaller than the value of `before`.
        """
        before: String
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
        """
        Filter the returned data.
        """
        where: ContentFilterInput,
        """
        Sort the returned data.
        """
        orderBy: [ContentOrderByInput],
    ): ContentConnection!
    """
    The unique identifier.
    """
    id: ID!
    """
    The level.
    """
    level: Int!
    """
    The name.
    """
    name(
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
    ): String
    """
    The parent Content, can be null if content is at root.
    """
    parent(
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
    ): Content
    """
    The sort order.
    """
    sortOrder: Int!
    """
    The update date.
    """
    updateDate(
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
    ): DateTime
    """
    The url.
    """
    url(
        """
        The culture to fetch the value in. If empty the contents culture will be used.
        """
        culture: String
    ): String
}

Content Connection

"""
A connection from an object to a list of objects of type `Content`.
"""
type ContentConnection {
  """
  A list of all of the objects returned in the connection.
  This is a convenience field provided for quickly exploring the API;
  rather than querying for \"{ edges { node } }\" when no edge data is needed, this field can be used instead.
  Note that when clients like Relay need to fetch the \"cursor\" field on the edge to enable efficient pagination,
  this shortcut cannot be used, "and the full \"{ edges { node } } \" version should be used instead.
  """
  items: [Content]!
  """
  A list of edges.
  """
  edges: [ContentEdge]!
  """
  Information to aid in pagination.
  """
  pageInfo: PageInfo!
}

Content Edge

"""
An edge in a connection from an object to another object of type `Content`
"""
type ContentEdge {
  """
  A cursor for use in pagination.
  """
  cursor: String!
  """
  The item at the end of the edge.
  """
  node: Content
}

Media

interface Media {
  """
  The ancestors.
  """
  ancestors(
      """
      Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
      """
      first: Int,
      """
      Only look at connected edges with cursors greater than the value of `after`.
      """
      after: String,
      """
      Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
      """
      last: Int,
      """
      Only look at connected edges with cursors smaller than the value of `before`.
      """
      before: String
  ): MediaConnection!
  """
  The children.
  """
  children(
    """
    Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
    """
    first: Int,
    """
    Only look at connected edges with cursors greater than the value of `after`.
    """
    after: String,
    """
    Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
    """
    last: Int,
    """
    Only look at connected edges with cursors smaller than the value of `before`.
    """
    before: String
  ): MediaConnection!
  """
  The create date.
  """
  createDate: DateTime!
  """
  The descendants.
  """
  descendants(
    """
    Specifies the number of edges to return starting from `after` or the first entry if `after` is not specified.
    """
    first: Int,
    """
    Only look at connected edges with cursors greater than the value of `after`.
    """
    after: String,
    """
    Specifies the number of edges to return counting reversely from `before`, or the last entry if `before` is not specified.
    """
    last: Int,
    """
    Only look at connected edges with cursors smaller than the value of `before`.
    """
    before: String
  ): MediaConnection!
  """
  The unique identifier.
  """
  id: ID!
  """
  The level.
  """
  level: Int!
  """
  The Media Type alias
  """
  mediaTypeAlias: String!
  """
  The name.
  """
  name: String!
  """
  The parent Content, can be null if content is at root.
  """
  parent: Media
  """
  The sort order.
  """
  sortOrder: Int!
  """
  The update date.
  """
  updateDate: DateTime
  """
  The url.
  """
  url(
    """
    Change the background color of the image.
    """
    backgroundColor: String,
    """
    The width of the output image.
    """
    width: Int,
    """
    The height of the output image.
    """
    height: Int,
    """
    Quality percentage of the output image.
    """
    quality: Int,
    """
    The image crop mode.
    """
    cropMode: ImageCropMode,
    """
    The image crop anchor.
    """
    cropAnchor: ImageCropAnchor,
    """
    Use a dimension as a ratio.
    """
    ratioMode: ImageCropRatioMode,
    """
    If the image should be upscaled to requested dimensions.
    """
    upscale: Boolean = false,
    """
    Change the format of the output image.
    """
    format: ImageCropFormat
  ): String
}

Media Connection

"""
A connection from an object to a list of objects of type `Media`.
"""
type MediaConnection {
  """
  A list of all of the objects returned in the connection.
  This is a convenience field provided for quickly exploring the API;
  rather than querying for \"{ edges { node } }\" when no edge data is needed, this field can be used instead.
  Note that when clients like Relay need to fetch the \"cursor\" field on the edge to enable efficient pagination,
  this shortcut cannot be used, "and the full \"{ edges { node } } \" version should be used instead.
  """
  items: [Media]!
  """
  A list of edges.
  """
  edges: [MediaEdge]!
  """
  Information to aid in pagination.
  """
  pageInfo: PageInfo!
}

Media Edge

"""
An edge in a connection from an object to another object of type `Media`
"""
type MediaEdge {
  """
  A cursor for use in pagination.
  """
  cursor: String!
  """
  The item at the end of the edge.
  """
  node: Media
}

Filtering

For all Document Types a FilterInput type is generated. The name is the type name postfixed by FilterInput e.g. given a type named Product the name will be ProductFilterInput.

Default Filter Fields

To filter the allContent field, ancestors, children and descendants connections the ContentFilterInput is used.

All filter inputs for Content Types will also have the default fields.

"""
A filter input for the type `Content`.
"""
input ContentFilterInput {
  """
  All of the filters must match.
  """
  AND: [ContentFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ContentFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ContentFilterInput]
  """
  Field must equal value.
  """
  contentTypeAlias: String
  """
  Field must match any of the values.
  """
  contentTypeAlias_any: [String]
  """
  Field must start with the value.
  """
  contentTypeAlias_starts_with: String
  """
  Field must end with the value.
  """
  contentTypeAlias_ends_with: String
  """
  Field must contain the value.
  """
  contentTypeAlias_contains: String
  """
  Field must equal value.
  """
  createDate: DateTime
  """
  Field must be greater than the value.
  """
  createDate_gt: DateTime
  """
  Field must be greater than or equal the value.
  """
  createDate_gte: DateTime
  """
  Field must be less than the value.
  """
  createDate_lt: DateTime
  """
  Field must be less than or equal the value.
  """
  createDate_lte: DateTime
  """
  Field must equal value.
  """
  id: ID
  """
  Field must match any of the values.
  """
  id_any: [ID]
  """
  Field must equal value.
  """
  level: Int
  """
  Field must be greater than the value.
  """
  level_gt: Int
  """
  Field must be greater than or equal the value.
  """
  level_gte: Int
  """
  Field must be less than the value.
  """
  level_lt: Int
  """
  Field must be less than or equal the value.
  """
  level_lte: Int
  """
  Field must match any of the values.
  """
  level_any: [Int]
  """
  Field must equal value.
  """
  name: String
  """
  Field must match any of the values.
  """
  name_any: [String]
  """
  Field must start with the value.
  """
  name_starts_with: String
  """
  Field must end with the value.
  """
  name_ends_with: String
  """
  Field must contain the value.
  """
  name_contains: String
  """
  Field must equal value.
  """
  sortOrder: Int
  """
  Field must be greater than the value.
  """
  sortOrder_gt: Int
  """
  Field must be greater than or equal the value.
  """
  sortOrder_gte: Int
  """
  Field must be less than the value.
  """
  sortOrder_lt: Int
  """
  Field must be less than or equal the value.
  """
  sortOrder_lte: Int
  """
  Field must match any of the values.
  """
  sortOrder_any: [Int]
  """
  Field must equal value.
  """
  updateDate: DateTime
  """
  Field must be greater than the value.
  """
  updateDate_gt: DateTime
  """
  Field must be greater than or equal the value.
  """
  updateDate_gte: DateTime
  """
  Field must be less than the value.
  """
  updateDate_lt: DateTime
  """
  Field must be less than or equal the value.
  """
  updateDate_lte: DateTime
}

Filtering is possible only on non-complex Property Editors like Text Area and Label. Filtering on more complex types like Content Picker and Multi-node Tree Picker has to be done client-side.

Strings

For fields returning String the following filter fields are generated.

Given the following type:

Product implements Content {
...
  sku: String
...
}

The following type will be generated, incl. the fields from the ContentFilterInput.

"""
A filter input for the type `Product`.
"""
input ProductFilterInput {
  """
  All of the filters must match.
  """
  AND: [ProductFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ProductFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ProductFilterInput]
...
  """
  Field must equal value.
  """
  sku: String
  """
  Field must match any of the values.
  """
  sku_any: [String]
  """
  Field must start with the value.
  """
  sku_starts_with: String
  """
  Field must end with the value.
  """
  sku_ends_with: String
  """
  Field must contain the value.
  """
  sku_contains: String
...
}

Ints

For fields returning Int or Decimal the following filters are generated.

The type is either Int or Decimal depending on the output type.

Given the following type:

Product implements Content {
...
  price: Decimal
...
}

The following type will be generated, incl. the fields from the ContentFilterInput.

"""
A filter input for the type `Product`.
"""
input ProductFilterInput {
  """
  All of the filters must match.
  """
  AND: [ProductFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ProductFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ProductFilterInput]
...
  """
  Field must equal value.
  """
  price: Decimal
  """
  Field must be greater than the value.
  """
  price_gt: Decimal
  """
  Field must be greater than or equal to the value.
  """
  price_gte: Decimal
  """
  Field must be less than the value.
  """
  price_lt: Decimal
  """
  Field must be less than or equal to the value.
  """
  price_lte: Decimal
  """
  Field must match any of the values.
  """
  price_any: [Decimal]
...
}

Boolean

For types returning Boolean the following filters are generated.

Given the following type:

Product implements Content {
...
  purchase: Boolean
...
}

The following type will be generated, incl. the fields from the ContentFilterInput.

"""
A filter input for the type `Product`.
"""
input ProductFilterInput {
  """
  All of the filters must match.
  """
  AND: [ProductFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ProductFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ProductFilterInput]
....
  # Field must equal value.
  purchase: Boolean
...
}

Content

Dates

For types returning DateTime the following filters are generated.

Given the following type:

Product implements Content {
  availableDate: DateTime
...
}

The following type will be generated, incl. the fields from the ContentFilterInput.

"""
A filter input for the type `Product`.
"""
input ProductFilterInput {
  """
  All of the filters must match.
  """
  AND: [ProductFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ProductFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ProductFilterInput]
...
  """
  Field must equal value.
  """
  availableDate: DateTime
  """
  Field must be greater than the value.
  """
  availableDate_gt: DateTime
  """
  Field must be greater than or equal to the value.
  """
  availableDate_gte: DateTime
  """
  Field must be less than the value.
  """
  availableDate_lt: DateTime
  """
  Field must be less than or equal to the value.
  """
  availableDate_lte: DateTime
...
}

Media

For types returning Media the MediaFilterInput is used.

"""
A filter input for the type `Media`.
"""
input MediaFilterInput {
  """
  All of the filters must match.
  """
  AND: [MediaFilterInput]
  """
  Some of the filters must match.
  """
  OR: [MediaFilterInput]
  """
  None of the filters must match.
  """
  NOT: [MediaFilterInput]
  """
  Field must equal value.
  """
  mediaTypeAlias: String
  """
  Field must match any of the values.
  """
  mediaTypeAlias_any: [String]
  """
  Field must start with the value.
  """
  mediaTypeAlias_starts_with: String
  """
  Field must end with the value.
  """
  mediaTypeAlias_ends_with: String
  """
  Field must contain the value.
  """
  mediaTypeAlias_contains: String
  """
  Field must equal value.
  """
  createDate: DateTime
  """
  Field must be greater than the value.
  """
  createDate_gt: DateTime
  """
  Field must be greater than or equal the value.
  """
  createDate_gte: DateTime
  """
  Field must be less than the value.
  """
  createDate_lt: DateTime
  """
  Field must be less than or equal the value.
  """
  createDate_lte: DateTime
  """
  Field must equal value.
  """
  id: ID
  """
  Field must match any of the values.
  """
  id_any: [ID]
  """
  Field must equal value.
  """
  level: Int
  """
  Field must be greater than the value.
  """
  level_gt: Int
  """
  Field must be greater than or equal the value.
  """
  level_gte: Int
  """
  Field must be less than the value.
  """
  level_lt: Int
  """
  Field must be less than or equal the value.
  """
  level_lte: Int
  """
  Field must match any of the values.
  """
  level_any: [Int]
  """
  Field must equal value.
  """
  name: String
  """
  Field must match any of the values.
  """
  name_any: [String]
  """
  Field must start with the value.
  """
  name_starts_with: String
  """
  Field must end with the value.
  """
  name_ends_with: String
  """
  Field must contain the value.
  """
  name_contains: String
  """
  Field must equal value.
  """
  sortOrder: Int
  """
  Field must be greater than the value.
  """
  sortOrder_gt: Int
  """
  Field must be greater than or equal the value.
  """
  sortOrder_gte: Int
  """
  Field must be less than the value.
  """
  sortOrder_lt: Int
  """
  Field must be less than or equal the value.
  """
  sortOrder_lte: Int
  """
  Field must match any of the values.
  """
  sortOrder_any: [Int]
  """
  Field must equal value.
  """
  updateDate: DateTime
  """
  Field must be greater than the value.
  """
  updateDate_gt: DateTime
  """
  Field must be greater than or equal the value.
  """
  updateDate_gte: DateTime
  """
  Field must be less than the value.
  """
  updateDate_lt: DateTime
  """
  Field must be less than or equal the value.
  """
  updateDate_lte: DateTime
}

Lists

For types returning [Decimal], [Int] or [String] the following filters are generated.

The type is [Decimal], [Int] or [String] depending on the output type

Given the following type:

Product implements Content {
...
  tags: [String]
...
}

The following type will be generated, incl. the fields from the ContentFilterInput.

# A filter input for the type `Product`.
input ProductFilterInput {
  """
  All of the filters must match.
  """
  AND: [ProductFilterInput]
  """
  Some of the filters must match.
  """
  OR: [ProductFilterInput]
  """
  None of the filters must match.
  """
  NOT: [ProductFilterInput]
...
  """
  Field must match all of the values.
  """
  tags_all: [String]
  """
  Field must match any of the values.
  """
  tags_some: [String]
...
}

Ordering

The result can be ordered by specifying a value for the orderBy argument.

An OrderBy type is generated for all Document Types. The name is the type name postfixed by OrderByInput e.g. given a type named Product the name will be ProductOrderByInput.

Fields returning DateTime, Decimal, Boolean, Int or String can be used to order by.

Default OrderBy Fields

To filter the allContent field, ancestors, children and descendants connections the ContentOrderBy is used.

All order by inputs for Content Types will also have the default fields.

``"""
An order input for the type `Content`.
"""
enum ContentOrderByInput {
  """
  Order by `contentTypeAlias` in ascending order.
  """
  contentTypeAlias_ASC
  """
  Order by `contentTypeAlias` in descending order.
  """
  contentTypeAlias_DESC
  """
  Order by `createDate` in ascending order.
  """
  createDate_ASC
  """
  Order by `createDate` in descending order.
  """
  createDate_DESC
  """
  Order by `level` in ascending order.
  """
  level_ASC
  """
  Order by `level` in descending order.
  """
  level_DESC
  """
  Order by `name` in ascending order.
  """
  name_ASC
  """
  Order by `name` in descending order.
  """
  name_DESC
  """
  Order by `path` in ascending order.
  """
  path_ASC
  """
  Order by `path` in descending order.
  """
  path_DESC
  """
  Order by `sortOrder` in ascending order.
  """
  sortOrder_ASC
  """
  Order by `sortOrder` in descending order.
  """
  sortOrder_DESC
  """
  Order by `updateDate` in ascending order.
  """
  updateDate_ASC
  """
  Order by `updateDate` in descending order.
  """
  updateDate_DESC
}`

### Custom OrderBy Fields

Given the following type:

```graphql
Product implements Content {
...
  price: Decimal
  sku: String
...
}

The following type will be generated, incl. the fields from the ContentOrderByInput.

"""
An order by input for the type `Product`.
"""
enum ProductOrderByInput {
...
  """
  Order by `price` in ascending order.
  """
  price_ASC
  """
  Order by `price` in descending order.
  """
  price_DESC
  """
  Order by `sku` in ascending order.
  """
  sku_ASC
  # Order by `sku` in descending order.
  sku_DESC
...
}

Default ordering

If you don't specify any order the data returned will be ordered by the path they appear in, in the Umbraco Backoffice tree.

Property Editors

Documentation for Umbraco Heartcore GraphQL property editors and their types

Supported Property Editors

Below is a list of all the supported built-in Umbraco Property Editors and their GraphQL types. The type may depend on the configuration of the specific Property Editor.

[Contentment] Data List

Editor Alias: Umbraco.Community.Contentment.DataList

List editor: Checkbox List or Tags GraphQL Type: [String] Can be used for filtering: true

Other editors configured with Multiple selection: true GraphQL Type: [String] Can be used for filtering: true

Other editors and configuration: true GraphQL Type: String Can be used for filtering: true

Checkbox

Editor Alias: Umbraco.TrueFalse GraphQL Type: Boolean Can be used for filtering: true

Checkbox list

Editor Alias: Umbraco.CheckBoxList GraphQL Type: [String] Can be used for filtering: false

Color Picker

Editor Alias: Umbraco.ColorPicker

Include labels?: false GraphQL Type: String Can be used for filtering: true

Content Picker
Date/Time

Editor Alias: Umbraco.DateTime GraphQL Type: DateTime Can be used for filtering: true

Decimal

Editor Alias: Umbraco.Decimal GraphQL Type: Decimal Can be used for filtering: true

Dropdown

Editor Alias: Umbraco.DropDown.Flexible GraphQL Type: [String] Can be used for filtering: true

Email address

Editor Alias: Umbraco.EmailAddress GraphQL Type: String Can be used for filtering: true

File upload

Editor Alias: Umbraco.UploadField GraphQL Type: String Can be used for filtering: true

Form Picker
Google Maps Single Marker
Grid layout
Image Cropper
Label

Editor Alias: Umbraco.Label GraphQL Type: String Can be used for filtering: true

Markdown Editor
Media Picker

Editor Alias: Umbraco.MediaPicker3

Media Picker (legacy)

Editor Alias: Umbraco.MediaPicker

Multi Url Picker

Editor Alias: Umbraco.MultiUrlPicker

Multinode Treepicker

Editor Alias: Umbraco.MultiNodeTreePicker

Node type: Member

Note: The Member editor configuration is not supported in the Multinode Treeepicker and will not be present in the generated schema.

Nested Content
Numeric

Editor Alias: Umbraco.Integer GraphQL Type: Int Can be used for filtering: true

Radio button List

Editor Alias: Umbraco.RadioButtonList GraphQL Type: [String] Can be used for filtering: true

Repeatable textstrings

Editor Alias: Umbraco.MultipleTextstring GraphQL Type: [String] Can be used for filtering: true

Rich Text Editor
Slider

Editor Alias: Umbraco.Slider

Enable Range: false GraphQL Type Decimal Can be used for filtering: true

Tags

Editor Alias: Umbraco.Tags GraphQL Type: [String] Can be used for filtering: true

Textarea

Editor Alias: Umbraco.TextArea GraphQL Type: String Can be used for filtering: true

Textbox

Editor Alias: Umbraco.TextBox GraphQL Type: String Can be used for filtering: true

Unsupported Editors

Below is a list of property editors which is not supported in GraphQL and will not be present in the generated schema.

List view

Editor Alias: Umbraco.ListView

Member Picker

Editor Alias: Umbraco.MemberPicker

Member Group Picker

Editor Alias: Umbraco.MemberGroupPicker

User Picker

Editor Alias: Umbraco.UserPicker

Versions and updates

Umbraco Heartcore is a software as a service (SaaS) offering, that eliminates upgrade concerns. All maintenance related to the CMS, its features, and APIs is handled by Umbraco HQ.

We follow semver in terms of versioning, which means you can be sure that existing APIs will continue to work as expected without breaking. If a breaking change is required then the major version will be incremented, but the previous major version will continue to work.

For API calls, it's advisable to employ the api-version header to indicate the API version you intend to use. If no version is specified the latest version of the API will be used.

Be aware that the client library releases will have certain features available. The Forms API is unavailable in the initial release (1.0) of the .NET Core client library, for instance. This was made available in the 1.1 version of the client library.

Using the Forms API

In this article you can learn more about how to use the Forms API for retrieving form definitions and submitting form entries.

Using the Forms API requires the use of a Bearer Token or an API-Key. A bearer token makes sense when working server side or in some kind of middleware whereas on the client side an API-Key might be a better fit. When using an API-Key on the client side we recommend that you create a "Forms-only" usergroup, so you do not expose any Content Management capabilities on the client side where not intentional.

Usage

In the Forms section of the Umbraco backoffice you will find the Forms Builder, which allows you to create forms by adding Fields, Placeholder texts, Validation and Conditions.

The purpose of this article is not to describe the Forms functionality itself, but to show how to use the APIs which are available for Umbraco Heartcore projects.

Before you continue with the rest of this article we recommend that you have at least one Form available that can be used for examples below. Here we will use a form with a Name field, an Email field and the Data Consent field, which is standard for all new Forms.

Retrieving a Form

Retrieving a Form using the REST API

The API for Forms lives under the Content Management API, so a Bearer token or an API-Key is required to call all the Forms related endpoints.

For this example we will call https://api.umbraco.io/forms which lists all available forms. From here you can find a specific form to retrieve in order to get the definition for that form. This is useful when you want to expose a specific form in a specific part of your presentation layer.

Getting a specific form is done by issuing a GET request to https://api.umbraco.io/forms/{id:guid}

Required headers include umb-project-alias and Api-Key or a Bearer Token via an Authorization header.

The JSON output for one specific form would look something like this:

{
    "_id": "0134604b-f583-4ebc-a3b6-c26ce0f1a11b",
    "indicator": "*",
    "name": "Contact Us",
    "nextLabel": "Next",
    "previousLabel": "Previous",
    "submitLabel": "Submit",
    "disableDefaultStylesheet": false,
    "fieldIndicationType": "MARK_MANDATORY_FIELDS",
    "hideFieldValidation": false,
    "invalidErrorMessage": "Please provide a valid value for {0}",
    "messageOnSubmit": "0",
    "requiredErrorMessage": "Please provide a value for {0}",
    "showValidationSummary": false,
    "pages": [
        {
            "caption": "Contact details",
            "fieldsets": [
                {
                    "columns": [
                        {
                            "width": 12,
                            "fields": [
                                {
                                    "caption": "Name",
                                    "alias": "name",
                                    "containsSensitiveData": false,
                                    "required": true,
                                    "requiredErrorMessage": "Please enter your name",
                                    "settings": {
                                        "defaultValue": "",
                                        "placeholder": "Full name",
                                        "patternInvalidErrorMessage": "Please provide a valid value for Name"
                                    },
                                    "preValues": [],
                                    "type": "text"
                                },
                                {
                                    "caption": "Email",
                                    "alias": "email",
                                    "containsSensitiveData": false,
                                    "required": true,
                                    "requiredErrorMessage": "Please enter a valid email",
                                    "settings": {
                                        "placeholder": "Your email address",
                                        "defaultValue": "",
                                        "pattern": "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+",
                                        "patternInvalidErrorMessage": "Please provide a valid value for Email"
                                    },
                                    "preValues": [],
                                    "type": "text"
                                },
                                {
                                    "caption": "Consent for storing submitted data",
                                    "alias": "dataConsent",
                                    "containsSensitiveData": false,
                                    "required": true,
                                    "requiredErrorMessage": "Consent is required to store and process the data in this form.",
                                    "settings": {
                                        "acceptCopy": "Yes, I give permission to store and process my data",
                                        "patternInvalidErrorMessage": "Please provide a valid value for Consent for storing submitted data"
                                    },
                                    "type": "consent"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/forms/0134604b-f583-4ebc-a3b6-c26ce0f1a11b"
        }
    }
}

Notice that the layout of properties correspond to the Forms builder in the backoffice. The various properties available for the form itself and for each of the fields is something you can use to build up the look and feel of the form in your presentation layer.

Retrieving a Form using the .NET Core Client Library

First step is to install it through NuGet:

> Install-Package Umbraco.Headless.Client.Net

When using the library you need the Content Management part in order to work with Forms. Create a new instance of the ContentManagementService and pass in the name of your Umbraco Heartcore project and either username + password of a backoffice user or an API-Key. In the example below we use an API-Key when retrieving all available form definitions:

var managementService = new ContentManagementService("project-alias", "api-key-value");
var forms = await managementService.Forms.GetAll();

If you want to retrieve a specific form you can use the GetById method along with a GUID ID as shown below:

var managementService = new ContentManagementService("project-alias", "api-key-value");
var contactForm = await managementService.Forms.GetById(new Guid("0134604b-f583-4ebc-a3b6-c26ce0f1a11b"));

Retrieving a Form using the NodeJS Client Library

First step is to install it through npm:

> npm install --save @umbraco/headless-client

First we need to import and create a new instance of the Client, to use the forms api you need to pass in the project alias and set an API-Key.

import { Client } from '@umbraco/headless-client'

const client = new Client({
  projectAlias: 'project-alias'
})

client.setAPIKey('api-key-value')

To retrieve all forms we need to use the forms service on the management API as shown below.

const forms = await client.management.forms.all()

To retrieve a single form by ID you can use the byId method with the form ID.

const form = await client.management.forms.byId('0134604b-f583-4ebc-a3b6-c26ce0f1a11b')

Posting a Form entry

Posting a Form entry using the REST API

When a form is filled out we need to post the entered values to the entries endpoint of the Forms API.

In order to submit the entered values you send a POST request to https://api.umbraco.io/forms/{id:guid}/entries where the ID represents the specific form to post the entry to.

Required headers include umb-project-alias and Api-Key or a Bearer Token via an Authorization header. The payload is a key value object with the alias of the fields and the values entered in the form.

Below is an example of the payload body when sending an entry back to the form retrieved in the previous section.

{
  "name": "John Smith",
  "email": "johnsmith@example.org",
  "dataConsent": "on"
}

Please keep in mind that the dataConsent property is required to have the value on or true when present on a form - anything else will result in validation error.

If you added validation on the email field to ensure that the entered value is in fact a valid email address, then this validation will also be enforced through the API. Try to send the payload above with a value that is not a valid email address to see the validation response you get back.

Posting a Form entry using the .NET Core Client Library

Continuing on the previous .NET Core example we can also post entries to a form using the library.

Given that the form contains a Name, Email and Data Content field we can submit a form entry as follows:

var entry = new Dictionary<string, object>
             {
                 {"name", "John Smith"},
                 {"email", "johnsmith@example.org"},
                 {"dataConsent", true}
             };

var managementService = new ContentManagementService("project-alias", "api-key-value");
await managementService.Forms.SubmitEntry(new Guid("0134604b-f583-4ebc-a3b6-c26ce0f1a11b"), entry);

Please note that if validation fails an exception is thrown. The validation configured for each of the fields is validated by Umbraco Forms on the server side.

Posting a Form entry using the NodeJS Client Library

Continuing on the previous NodeJS example we can also post entries to a form using the library.

Given that the form contains a Name, Email and Data Content field we can submit a form entry as follows:

const entry = {
  "name": "John Smith",
  "email": "johnsmith@example.org",
  "dataConsent": "on"
}

await client.management.forms.submitEntry('0134604b-f583-4ebc-a3b6-c26ce0f1a11b', entry)

Please note that if validation fails an error is thrown. The validation configured for each of the fields is validated by Umbraco Forms on the server side.

Building a project from scratch

A guide to building an Umbraco Heartcore project

In this article you can learn how to get started with your Umbraco Heartcore project.

It will cover everything you need to know, in order to create your first piece of content in the Umbraco backoffice.

This guide will assume that you have already set up an Umbraco Heartcore project without any content.

Introduction

When you log in to the Umbraco Backoffice, the first thing you will see is the Content section. This is where you will be creating content for your Umbraco Heartcore project. However, it will not be possible to create any content yet, as we will first need to define the content we are going to be creating.

Content in Umbraco is based on Document Types which will define what type of data we can put into our content. A Document Type consists of a set of Properties - also called fields. A Property is made up of a Data Type which is a custom configuration of a Property Editor. Umbraco comes with a set of Property Editors, including a Text Area, a Date Picker, a picker for media items and many more.

As we go through this tutorial and start building the content for our Umbraco Heartcore project, you will learn more about each of these concepts and how they all work together.

New to Umbraco?

If you are new to Umbraco, we recommend that you take the Backoffice Tour we've created! You can find it by selecting the question mark in the top-right corner.

Overview of tutorial

In this tutorial we will cover the following topic:

  • Creating a basic Document Type

  • Adding and defining properties

  • Creating a Document Type Collection

  • Setting permissions on Document Types

  • Creating content

Creating a basic Document Type

Document Types are managed from the Settings section in the Umbraco backoffice.

In order to get started with our first Document Type, follow these steps:

  1. Right-click on the Document Types folder and choose + Create....

    • Or select the three ellipses on the right, when hovering the folder.

  2. Choose the first option: Document Type.

  3. Give the new Document Type a name like Home Page.

  4. Save the Document Type by selecting the green Save button in the bottom-right corner.

We have now created our first Document Type. It's currently a blank slate, and in the next section, we will start adding groups and properties. This way we are able to add different types of data to our content.

Adding and defining properties

Before we can start adding properties to the Document Type, we need to add a Group.

Property Groups

Groups are a way to group certain properties together. It can help content editors getting an overview of content nodes with many properties.

Groups also serves as a way to navigate a content node in the Content section.

  1. Select Add Group in the middle of the Document Type editor area.

  2. Give the group a name like Content.

Now, let's add our first property to the Document Type.

  1. Select Add Property.

  2. In the Property Settings dialog, we'll start by giving the Property a name: Heading.

  3. (Optional) Give the Property a description

  4. Select Add Editor

Select Editor

In this dialog you choose which editor to add to the Property. The editor you choose defines the type of data that can be added to the property.

Create New lets you create your own Data Types based on the editors in Umbraco. Use existing provides you with the option to select on the pre-defined Data Types.

  1. Use the search field to find and select the pre-defined Textstring Data Type.

  2. Submit the Property settings

We have now added the first Property to our Document Type.

Following the same steps, let's add a few more properties to the Content group:

Name
Property Settings

Intro Text

Textarea Data Type

PromoImage

Media Picker Data Type

Media Picker

This editor lets you upload or select an existing media item from the Media section and add it to your content.

With these properties added our Document Type now looks something like this:

Remember to save the Document Type by selecting the green Save button in the bottom-right corner.

This is a very simplified version of a Document Type, and you are welcome to add more groups and properties.

Creating a Document Type Collection

So far, we've created a single Document Type with some text fields and a media picker. Before we start creating the actual content, we are going to add a few more Document Types, to allow for more variation in our Content section.

We will now expand on our site by adding a Document Type Collection.

  1. Right-click on the Document Types folder and choose + Create....

    • Or select the three ellipses on the right, when hovering the folder.

  2. Choose the second option: Document Type Collection....

Document Type Collections

When working with content you might want to be able to relate certain types of nodes to each other. This could be articles you would like to nest under a News section, or it could be a Blog where it should be possible to create blog posts.

The Document Type Collection allows you to create 2 Document Types in one go, and at the same time, they will be given a parent/child relationship.

Example: Parent Document Type: News Area Item Document Type: News Article

In the Content section, you will with this setup be able to create a News Area content node, and then create your News Articles under that node.

For our Umbraco Heartcore project, we will want it to be possible to create blog posts under a blog area.

  1. Name the Parent Document Type Blog Area.

  2. Name the Child Document Type Blog Post.

  3. Select Create to setup the two Document Types.

Once the Document Types have been created you will be redirected to the Item Document Type - in our case the Blog Post.

Following the steps outlined earlier in this tutorial, add a Content group and the following properties to both the Blog Post and the Blog Area Document Types.

Blog Post

Name
Property Settings

SubTitle

Textstring Data Type

MainContent

Richtext Editor Data Type

Blog Area

Name
Property Settings

BlogDescription

Textarea Data Type

We should now have the three following Document Types in our Document Types tree:

Setting permissions on Document Types

The final thing we need to do before we start creating content is to check that our Document Types have the correct permissions.

  1. Select the Home Page Document Type in the tree.

  2. Navigate to the Permissions tab in the top-right corner.

  3. We will want to allow that Home Page Document Type can be used to create content at root level, so make sure the Allow as root is checked.

  4. Next to Allowed child node types select Add child, and in the dialog select our Blog Area Document Type.

    • Doing this, will allow us to create content of the Blog Area type under our Home Page.

  5. Save the Document Type.

With the permissions set, we are now ready to start working on the content for the Umbraco Heartcore project.

Creating content

In this next step of the tutorial, we will start creating content. The content we're going to create will be defined by the Document Types we've created, and you will see how the choices we've made impact the editing experience one we start working with the content.

  1. Go to the Content section.

  2. Right-click on the Content tree and choose + Create....

    • Or select the three ellipses on the right, when hovering the Content tree.

We now have the option to create a content item based on our Home Page Document Type.

  1. Select the Home Page.

  2. Give the content item a name: Welcome to Umbraco Heartcore.

  3. Add some text to both the Heading and the Intro text properties.

  4. To choose an image for the PromoImage property, select the plus-sign.

  5. In the dialog, you can do either of the following the choose an image:

    • Select the Upload button to choose an image from your file explorer or

    • Drag an image directly into the dialog.

  6. Once you've chosen an image, select it from the dialog and select the green Select button at the bottom of the dialog.

Media items and images

When you add media and images to your content using the default Media Picker Data Type, the items will automatically be added to the media library you can find in the Media section of the backoffice.

Select the Media section in the top navigation bar, and you can browse all the media items that have been uploaded to the project.

  1. When you're happy with the content in the properties, select the Save and publish button in the bottom right.

So far, our Content section should look like this:

  1. Right-click the root node, Welcome to Umbraco Heartcore, and choose Create...

    • Or select the three ellipses next to the node when hovering.

  2. Select to create a Blog Area.

  3. Give it a name: Blog.

  4. (Optional) Add some text to the BlogDescription property.

  5. To start adding blog posts to our Blog, right-click the Blog node in the Content tree.

  6. Choose to Create... a new item based on the Blog Post Document Type.

  7. Give the blog post a name and add some text to the Subtitle and MainContent properties.

Rich Text Editor

The editor we chose for the MainContent property is a Rich Text Editor.

It gives us a lot of flexibility when writing text, as there are multiple formatting options.

  1. Once you're happy with how your blog post looks, select Save and publish.

  2. To go back to the Blog Area, select the arrow next to the title of the blog post

You will now get an overview of the blog posts you've created. So far we've only created one, and creating more is done by selecting the Create Blog Post button in the top-left corner.

We have now covered the very basics of how to create content in the Umbraco backoffice.

What now?

Now you have some content in your Umbraco Heartcore project that you can start using.

You can use the Umbraco Heartcore REST API endpoints to fetch this content to where you need it.

Test with the provided samples

Testing with the API Browser

In order to test how the content you've created will be formatted, when fetched through the Umbraco Heartcore REST API endpoints, you can use the API Browser in the Settings section of the backoffice.

Custom Grid Editors

Documentation for Custom Grid Editors in Umbraco Heartcore

Custom Grid Editors can be created under the Grid Editors tree in the Settings section.

The Grid Editor must export a default class inheriting from HTMLElement

For the Grid to be able to save the value the editor must contain a set value(value) function and for the editor to be able to show the stored value, it must also contain a get value() function.

The set value() is called when the editor is loaded and when the value is changed outside of the editor.

Using external libraries

When importing libraries that registers variables or functions on the global object or custom elements it's advised to create a Module Alias and import that instead. By using Module Alias when importing we can ensure that only one version of a library is imported.

A Module Alias can be configured under Headless -> Custom Editors Configuration in the Settings section.

Use a Module Alias when importing libraries to ensure only a single version of that library is loaded.

Accessing backoffice components

Using this library reduces breaking changes in the exposed API that would otherwise happen if the backoffice components were accessed directly.

Currently, the library is exposing only a few components but Feature Requests and Pull Requests are more than welcome.

The Headless backoffice Bridge has custom elements so it's advised to import using a Module Alias

JSON Schema

The default Schema looks like this:

Since it has "type": "string" the different APIs will return the stored value as a string.

If the editor stores an object we can use "type": "object" instead, now the APIs will return the value as a JSON object.

By also adding properties, the API will be more clever about how the data is returned.

For example, an image editor that stores an UDI in the url field and the alt text in the altText field like this

Could have a schema like:

Notice how there's a "format":·"uri-reference" to the url property in the schema. Combined with "type": "string" the APIs knows this is a URI and will try to parse the value stored as an UDI and if successful, return the URL of the referenced item.

Currently, the following combinations are supported:

type: string format: uri-reference value: Content or Media UDI returned: A URL to the item if exists.\

type: string format: rich-text value: Rich Text, for example from the TinyMCE editor returned: The value where all a tags with a locallink href and img tags with a data-udi attribute is replaced with the correct links to the items.\

Limitations and best practices

Currently, some functionality and components that do not work well in the preview pane. This includes integrations with the backoffice like Pickers and the Rich Text Editor. However, they still work when inserted on a page.

Related articles

Persisted Queries

Documentation for Persisted queries in Umbraco Heartcore

Persisted queries allow you to store GraphQL queries on the server. This enables clients to execute them by referencing an alias rather than sending the full query each time. this approach streamlines client-server communication and enhances security.

Why use persisted queries?

  • Reducing the payload size

    • You minimize the data transmitted over the network by sending only the alias and necessary variables. This reduction in payload size leads to faster request times and is particularly beneficial for mobile applications or environments with limited bandwidth.

  • Enhanced Security

    • Persisted queries provide improved security by ensuring that only predefined, server-stored GraphQL queries can be executed, preventing clients from running arbitrary or malicious queries.

To fully benefit from this, the content delivery API must be set to private, and GraphQL must be configured only to allow persisted queries. Without these settings in place, the security advantages of using persisted queries are not realized.

Enable Persisted queries only

In order to fully benefit from the security enhancement that comes with persisted queries you need to enable the Only allow GraphQL persisted queries setting. This can be done from the headless options section within the backoffice

Please be aware this will also disable the execution of queries in the playground.

Media

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Authentication

Auth is required for this API meaning that you must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Get root media

Get all media at the root of the tree, which the authorized user has access to according to the 'Start node'-permissions.

URL: /media

Method: GET

Permissions required : Access to Media section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Get by id

Get specific media item by its GUID ID.

URL: /media/{id}

Method: GET

Permissions required : Access to Media section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Get children

Get a list of children (media items) by their parent GUID ID.

URL: /media/{id}/children

Method: GET

Query Strings

Permissions required : Access to Media section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Create media

Create a new media item and optionally upload a file to the created item.

Media can be created by sending a POST request to the media endpoint. The request body should contain the media item properties and the file to upload. The file is sent as a multi-part request. The first MultipartBoundary contains the JSON body describing the content for the image. The second MultipartBoundary contains the file. If the media item does not contain a file you can send a regular JSON request to create the media.

The umbracoFile.src property in the first MultipartBoundary's JSON body defines the name of the file to be uploaded. The fileName in the second MultipartBoundary must match the umbracoFile.src property's value.

URL: /media

Method: POST

Header: Content-Type: multipart/form-data; boundary=MultipartBoundry

Permissions required : Access to Media section of the Umbraco Backoffice

Request

Success Response

Code: 201

Content Example:

Update media

Updates an existing media item and optionally uploads a file to the updated item.

Media would typically contain an upload field (the Image and File media types has this by default), which means it is possible to send a file along with the request to update an existing media item. This is done by sending a multi-part request with the JSON body and the file. If the media item does not contain a file you can send a regular JSON request to update the media.

URL: /media/{id}

Method: PUT

Header: Content-Type: multipart/form-data; boundary=MultipartBoundry

Permissions required : Access to Media section of the Umbraco Backoffice

Request

Success Response

Code: 200

Content Example:

Delete media

Delete a media item. This will also delete any file that is attached to the media item.

URL: /media/{id}

Method: DELETE

Permissions required : Access to Media section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

DELETE https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2

.NET Core Console Application

In this article, you can read more about the .NET Core Console Application.

We will go through the process of setting the application up and exploring what you can do with the application. We will also discuss how you can connect to your Heartcore project on Umbraco Cloud.

In order to use this console application, you will need to have the .NET Core SDK2.2. Older or newer versions will not work with the application.

Installing the Console Application

1. Using Visual Studio

Open up the Umbraco.Headless.Client.Samples.Console.sln file located at Umbraco.Headless.Client.Net\samples\Umbraco.Headless.Client.Samples.Console and press F5. This will launch the Console application.

2. Using the Command Line

By using the command line, you will need to run the following commands from the Umbraco.Headless.Client.Samples.Console folder in order to run the application.

Walkthrough of the Application

If you are connecting to a Heartcore Project with multiple environments you will have to use the alias for the Development environment.

If you do not have a project or trial you can also connect to demo-headless.

Once you have entered the alias of the project, you are presented with the following options

Examples of the fetched data

Fetching the data looks like the following.

In the example above we have fetched the Content Tree. Is shows all the Parent and Child Nodes. The Child Node is shown by an indentation.

In the next example, we have fetched the Root media.

It is showing the name of the Media items and a direct link to each of the Media items.

Client Libraries

In order for you to get started with Umbraco Heartcore we have created a set of client libraries for you to use for testing and for getting a seamless start with the product.

The client libraries provide you with a starting point where you do not need to worry about implementing the use of each API endpoint, as these have already been setup. All you need to do is connect the client library to your Umbraco Heartcore project. How this connection is made depends on the client library, but usually requires configuring a couple of parameters.

We recommend testing with these libraries if you are looking to explore the potential of Umbraco Heartcore.

Both client libraries include samples that you can connect to your Heartcore project and start testing in no time.

tip Our client libraries are open source and free to use.

Found a bug? Please let us know by using the Issue Tracker on the GitHub repositories:

A .NET client library based on .NET Standard 2.0 to support application development including Xamarin/UWP applications.

This client library includes three samples:

A Node.js client library including a Koa sample that you can hook up to your Umbraco Heartcore project for testing.

The Umbraco Cloud Portal

In this article, you will learn more about the Umbraco Cloud Portal and what options are available to you.

Umbraco Cloud Portal Overview

From here you can see a list of all your projects. If you have multiple projects, you can sort specific projects into groups.

Clicking on a project will take you to the project page where you will get an overview of your environment(s).

Manage Environments

From here, you can create multiple environments, so that you can have a Development and eventually also a Staging environment. Depending on what plan you have chosen, you will have access to one or more environments on your project.

If you want to add an environment, all you have to do is click Create Development Environment. Umbraco will create the environment for you.

When you are done, you can go back to the project overview.

Invite member

In the top-left corner, you will find the invite member option. This will allow you to quickly invite new team members to your project from a modal that pops up. This makes it very fast to invite new team members.

Settings

In the left side menu, you can find the different settings and configurations available for your Heartcore project.

Edit Team

As with the invite member option, you can add new team members to your project. It is also possible to change the roles of your team members here, provided that you have sufficient permissions. You can remove team members from this page as well as see any pending invitations you might have sent.

It is also here, that you are able to add or edit the Technical Contact information such as Name, Email, and telephone number.

When you invite a Team Member to your Heartcore project, they will automatically get access to the backoffice of the project as well.

You can add as many members to your project as you want.

Webhooks

Here you are able to set up a webhook that will gather all the information about each deployment. You can integrate webhooks with applications such as Slack. Doing so, you can get Heartcore to post a message in a chosen Slack channel after each deployment.

Usage

On the Usage page, you will find an overview that displays your usage and evaluates it against the plan limitations of your project. On the page, you will also find the top 10 for the bandwidth usage of your project. This can give you important insight into where you can optimize resource management.

Upgrade plan

Here you will be able to upgrade your trial to a plan that fits your needs.

Rename project

Here you can rename your project. All default umbraco.io hostnames will be updated to match the new name. When renaming a project you will also need to update the Umb-Project-Alias header when you are sending requests to the API, as changing the name of the project will also change the project alias.

Delete project

From this page, you can delete your project. When deleting the project your subscription will automatically be cancelled as well. Deleting the project is a permanent action.

Go to backoffice

date ()

The GraphQL API supports , running a persisted query can be done using the following payload in the Graphql request:

Persisted queries can be created within the backoffice in the

If a Content Type is inherited from or used as a it will be generated as an interface

If the Document Type is marked as an Element Type it will implement the interface

All other Content Types will implement either the or the interface, they will also implement all their Composition interfaces.

All properties on a Content Type is generated as a field on the GraphQL type. See the page for which types the editors are returning.

If a property is marked as , a culture argument is added to that field. The argument is optional and will fallback to the parent fields culture or the default culture if none is specified.

The page contains a list of all the Property Editors and which GraphQL types they return.

For types returning Content the is used.

Block Grid

Editor Alias: Umbraco.BlockGrid GraphQL Type:

Can be used for filtering: false

Block List

Editor Alias: Umbraco.BlockList GraphQL Type:

Can be used for filtering: false

Include labels?: true GraphQL Type:

Editor Alias: Umbraco.ContentPicker GraphQL Type: Can be used for filtering: true

Editor Alias: UmbracoForms.FormPicker GraphQL Type: Can be used for filtering: false

Editor Alias: Our.Umbraco.GMaps GraphQL Type: Can be used for filtering: false

The grid editor Data Type in Heartcore is deprecated and will be retired in June 2025 or thereafter. For more information read the following .

Editor Alias: Umbraco.Grid GraphQL Type: Can be used for filtering: false

Editor Alias: Umbraco.ImageCropper GraphQL Type: Can be used for filtering: false

Editor Alias: Umbraco.MarkdownEditor GraphQL Type: Can be used for filtering: false

Pick Multiple items: true GraphQL Type: Can be used for filtering: false

Pick Multiple items: false GraphQL Type: Can be used for filtering: false

Pick Multiple items: true GraphQL Type: Can be used for filtering: true

Pick Multiple items: false GraphQL Type: Can be used for filtering: true

Maximum number of items: 1 GraphQL Type: Can be used for filtering: false

Maximum number of items: not 1 GraphQL Type: Can be used for filtering: false

Node type: Content Maximum number of items: 1 GraphQL Type: Can be used for filtering: true

Node type: Content Maximum number of items: not 1 GraphQL Type: Can be used for filtering: true

Node type: Media Maximum number of items: 1 GraphQL Type: Can be used for filtering: true

Node type: Media Maximum number of items: not 1 GraphQL Type: Can be used for filtering: true

Editor Alias: Umbraco.NestedContent GraphQL Type: Can be used for filtering: false

Editor Alias: Umbraco.TinyMCE GraphQL Type: Can be used for filtering: false

Enable Range: true GraphQL Type Can be used for filtering: false

Umbraco HQ will regularly be adding new features to the CMS and new capabilities to the REST APIs. Each time new endpoints are added to the REST API the api-version will be updated to reflect the changes. API releases and versioning is handled following the .

Learn more about which versions of the API is available as well as what version each endpoint uses in the

When using our , the api-version is handled as part of the library and generally not something you need to worry about.

We recommend that you have a look at the along side this article if you haven't already seen it. The API reference has useful content around field types and possible errors.

The availability of Umbraco Forms depends on the plan. See the for an overview of which plans includes Forms.

If you want to learn the basics of 'Creating a form' before going further we recommend that you start with the .

If you are a C# developer and work with .NET you can use the in your own codebase to retrieve form definitions.

If you are a JavaScript developer and work with NodeJS you can use the in your own codebase to retrieve form definitions.

We've built a few client libraries with samples that you can use for testing. You can find them in the

You can learn more about the API Browser and how to use it in the.

The grid editor Data Type in Heartcore is deprecated and will be retired in June 2025 or thereafter. For more information read the following .

A custom Grid Editor in Heartcore is built using .

The get value() is called when the grid is saving and when the editor raises an .

External libraries can be imported by using the statement.

For example, if you want to use to create your web component it can be done like this

Accessing backoffice components like the Media Picker must be done using the .

A is used to describe how the value is stored and returned by the REST and GraphQL API.

This allows for advanced configurations where, for example, an is converted to a URL.

To make your custom editors less likely to break with future updates, do not use any of the backoffice JavaScript directly. Always use the .

If the library is missing any functionality, raise an issue on the .

Try to avoid relying on backoffice CSS-classes. Instead, it's recommended creating isolated elements using .

Status Code
Error Code
Message

Different media property editors will require different request body formats.The File Upload property editor has the file name as the value "umbracoFile": FILE_NAME, and the Image Cropper property editor expects a JSON value "umbracoFile": { "src": FILE_NAME }. To verify the JSON structure you can manually upload the media file via the backoffice and fetch the data. It can then be used for reference. (See how in the tutorial.)

Once you have cloned down the , there are two ways of running the application.

In order to use this application to its fullest, you will need a Heartcore Project on Umbraco Cloud. If you do not have a project yet, you can . It is recommended that you have a project with both content and media items.

Option A - E uses the and can be used for any Heartcore Project, which has public content.

Option F uses the . This means that an is required to run this part of the sample. This is because it will create a new folder in the Media Library and upload an image to a new Media item.

An sample site, with custom routing and controller hijacking.

A, with options using the Content Delivery and the Content Management API.

A showing how to use the .NET library to present your Umbraco Heartcore content in a Blazor application.

After you have logged into the , you are presented with the project list overview.

Clicking on the 'Go to backoffice' link will open up a new tab with the login screen for the Backoffice. If you would like to learn more, you can read our documentation for the.

ISO8601
persisted queries
Schema Generation
Property Editors
Filtering and Ordering
Composition
Property Editors
Allow varying by culture
Property Editors
blog post
ASP.NET API versioning guidelines
Umbraco Heartcore API Documentation.
Client Libraries
Forms API reference documentation
Pricing & Features
Umbraco Forms documentation section
.NET Core Client Library
NodeJS Client Library
Client Libraries section
API Browser article
GraphQL Playground
Common Headers
Authentication
Errors
Get All
Get By Name
Create member group
Delete member group
Common Headers
Authentication
Errors
Get all relation types
Get by alias
Common Headers
Authentication
Errors
Get By Id
Get by relation type alias
Get by parent id
Get by child id
Create relation
Delete relation
Common Headers
Authentication
Errors
Get all member types
Get by alias
Common Headers
Errors
Get Root Content
Get By Id
Get By Url
Get By Type
Get Ancestors
Get Children
Get Descendants
Content Filter
Search
Types
Fields
Root Query
Reserved Type Names and Property Aliases
Built-in Custom Types
Filtering
Ordering
Element
Content
Media
ContentFilterInput
BlockGrid
BlockListItem
PickedColor
Content
JSON
OurUmbracoGMaps
JSON
ImageCropper
HTML
[MediaWithCrops]
MediaWithCrops
[Media]
Media
Link
[Link]
Content
[Content]
Media
[Media]
[Element]
HTML
DecimalRange
export default class extends HTMLElement {
}
#value // private field
get value() { return this.#value }
set value(value) { this.#value = value }
import { LitElement } from 'https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js'

export default class extends LitElement {
  static properties = {
    value: { type: String }
  }
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "string"
}
{
  "url": "udi://media/45d27aa9fcb446e48ef4a07d754d9c9d",
  "altText": "An example image"
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "altText": {
      "type": "string"
    },
    "url": {
      "type": "string",
      "format": "uri-reference"
    }
  },
  "required": [
    "url"
  ]
}
Api-Version: 2
Umb-Project-Alias: {project-alias}

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Media with id '{id}' could not be found.

422

ValidationFailed

Validation error occured when trying to save or update the media item.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}
{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media"
        },
        "media": [
            {
                "href": "https://api.umbraco.io/media/{id}",
                "templated": true
            },
            {
                "href": "https://api.umbraco.io/media/7bfa2332-cf7f-4c97-941d-50f43f085b06"
            },
            {
                "href": "https://api.umbraco.io/media/bff96d2a-18a7-4d72-b788-72e2034a5514"
            },
            {
                "href": "https://api.umbraco.io/media/9924b6e9-51fd-4686-ad9a-cb59dbe9b4b1"
            }
        ],
        "children": {
            "href": "https://api.umbraco.io/media/{id}/children{?page,pageSize}",
            "templated": true
        },
        "mediatype": {
            "href": "https://api.umbraco.io/media/type/{alias}",
            "templated": true
        }
    },
    "_embedded": {
        "media": [
            {
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-10-04T11:46:06.653Z",
                "_id": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
                "_updateDate": "2019-10-04T11:46:06.653Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/7bfa2332-cf7f-4c97-941d-50f43f085b06"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/7bfa2332-cf7f-4c97-941d-50f43f085b06/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Folder"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "Design",
                "sortOrder": 1
            },
            {
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-10-04T11:46:14.32Z",
                "_id": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "_updateDate": "2019-10-04T11:46:14.32Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/bff96d2a-18a7-4d72-b788-72e2034a5514"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/bff96d2a-18a7-4d72-b788-72e2034a5514/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Folder"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "People",
                "sortOrder": 2
            },
            {
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-10-04T11:46:21.433Z",
                "_id": "9924b6e9-51fd-4686-ad9a-cb59dbe9b4b1",
                "_updateDate": "2019-10-04T11:46:21.433Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/9924b6e9-51fd-4686-ad9a-cb59dbe9b4b1"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/9924b6e9-51fd-4686-ad9a-cb59dbe9b4b1/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Folder"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "Products",
                "sortOrder": 3
            }
        ]
    }
}
{
    "_hasChildren": false,
    "_level": 2,
    "_createDate": "2019-10-04T13:08:52.203Z",
    "_id": "f2311d74-bc19-465b-8028-4af79f47f155",
    "_updateDate": "2019-10-04T13:08:52.203Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/f2311d74-bc19-465b-8028-4af79f47f155"
        },
        "root": {
            "href": "https://api.umbraco.io/media"
        },
        "children": {
            "href": "https://api.umbraco.io/media/f2311d74-bc19-465b-8028-4af79f47f155/children"
        },
        "mediatype": {
            "href": "https://api.umbraco.io/media/type/Image"
        }
    },
    "mediaTypeAlias": "Image",
    "name": "Banjo",
    "parentId": "9924b6e9-51fd-4686-ad9a-cb59dbe9b4b1",
    "sortOrder": 4,
    "umbracoFile": {
        "src": "/media/oiodd2qz/7373036290_5e8420bf36_b.jpg",
        "focalPoint": {
            "left": 0.5,
            "top": 0.5
        },
        "crops": null
    },
    "umbracoWidth": "1024",
    "umbracoHeight": "683",
    "umbracoBytes": "299546",
    "umbracoExtension": "jpg"
}
?page={integer=1}
?pageSize={integer=10}
{
    "_totalItems": 5,
    "_totalPages": 1,
    "_page": 1,
    "_pageSize": 10,
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/bff96d2a-18a7-4d72-b788-72e2034a5514/children?page=1"
        },
        "media": [
            {
                "href": "https://api.umbraco.io/media/b0d9704a-8c1a-498f-8892-d3a18acc6f01"
            },
            {
                "href": "https://api.umbraco.io/media/3bc8bf5c-5f39-4a49-b8f3-a09c265aa739"
            },
            {
                "href": "https://api.umbraco.io/media/9b4a8092-a157-4a0e-9626-1f320a7a5f79"
            },
            {
                "href": "https://api.umbraco.io/media/9012c147-90dc-4c7e-8249-4b4092aff340"
            },
            {
                "href": "https://api.umbraco.io/media/313bf02d-bfba-4d61-a12c-1fbdbe0fee1c"
            }
        ]
    },
    "_embedded": {
        "media": [
            {
                "_hasChildren": false,
                "_level": 2,
                "_createDate": "2019-10-04T11:49:57.863Z",
                "_id": "b0d9704a-8c1a-498f-8892-d3a18acc6f01",
                "_updateDate": "2019-10-04T11:49:57.863Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/b0d9704a-8c1a-498f-8892-d3a18acc6f01"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/b0d9704a-8c1a-498f-8892-d3a18acc6f01/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                },
                "mediaTypeAlias": "Image",
                "name": "Jan Skovgaard",
                "parentId": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "sortOrder": 0,
                "umbracoFile": {
                    "src": "/media/jryntma0/18720470241_ff77768544_h.jpg",
                    "focalPoint": {
                        "left": 0.5,
                        "top": 0.5
                    },
                    "crops": null
                },
                "umbracoWidth": "1600",
                "umbracoHeight": "1067",
                "umbracoBytes": "240126",
                "umbracoExtension": "jpg"
            },
            {
                "_hasChildren": false,
                "_level": 2,
                "_createDate": "2019-10-04T11:50:12.933Z",
                "_id": "3bc8bf5c-5f39-4a49-b8f3-a09c265aa739",
                "_updateDate": "2019-10-04T11:50:12.933Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/3bc8bf5c-5f39-4a49-b8f3-a09c265aa739"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/3bc8bf5c-5f39-4a49-b8f3-a09c265aa739/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                },
                "mediaTypeAlias": "Image",
                "name": "Matt Brailsford",
                "parentId": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "sortOrder": 1,
                "umbracoFile": {
                    "src": "/media/lk5nqozz/18531852339_981b067419_h.jpg",
                    "focalPoint": {
                        "left": 0.5,
                        "top": 0.5
                    },
                    "crops": null
                },
                "umbracoWidth": "1600",
                "umbracoHeight": "1067",
                "umbracoBytes": "438249",
                "umbracoExtension": "jpg"
            },
            {
                "_hasChildren": false,
                "_level": 2,
                "_createDate": "2019-10-04T11:57:36.863Z",
                "_id": "9b4a8092-a157-4a0e-9626-1f320a7a5f79",
                "_updateDate": "2019-10-04T11:57:36.863Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/9b4a8092-a157-4a0e-9626-1f320a7a5f79"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/9b4a8092-a157-4a0e-9626-1f320a7a5f79/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                },
                "mediaTypeAlias": "Image",
                "name": "Lee Kelleher",
                "parentId": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "sortOrder": 2,
                "umbracoFile": {
                    "src": "/media/ssaevg0x/18531854019_351c579559_h.jpg",
                    "focalPoint": {
                        "left": 0.5,
                        "top": 0.5
                    },
                    "crops": null
                },
                "umbracoWidth": "1600",
                "umbracoHeight": "1067",
                "umbracoBytes": "324821",
                "umbracoExtension": "jpg"
            },
            {
                "_hasChildren": false,
                "_level": 2,
                "_createDate": "2019-10-04T11:57:56.267Z",
                "_id": "9012c147-90dc-4c7e-8249-4b4092aff340",
                "_updateDate": "2019-10-04T11:57:56.267Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/9012c147-90dc-4c7e-8249-4b4092aff340"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/9012c147-90dc-4c7e-8249-4b4092aff340/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                },
                "mediaTypeAlias": "Image",
                "name": "Jeavon Leopold",
                "parentId": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "sortOrder": 3,
                "umbracoFile": {
                    "src": "/media/ihabfeg2/18095416144_44a566a5f4_h.jpg",
                    "focalPoint": {
                        "left": 0.5,
                        "top": 0.5
                    },
                    "crops": null
                },
                "umbracoWidth": "1600",
                "umbracoHeight": "1067",
                "umbracoBytes": "348162",
                "umbracoExtension": "jpg"
            },
            {
                "_hasChildren": false,
                "_level": 2,
                "_createDate": "2019-10-04T11:58:15.54Z",
                "_id": "313bf02d-bfba-4d61-a12c-1fbdbe0fee1c",
                "_updateDate": "2019-10-04T11:58:15.54Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/media/313bf02d-bfba-4d61-a12c-1fbdbe0fee1c"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://api.umbraco.io/media/313bf02d-bfba-4d61-a12c-1fbdbe0fee1c/children"
                    },
                    "mediatype": {
                        "href": "https://api.umbraco.io/media/type/Image"
                    }
                },
                "mediaTypeAlias": "Image",
                "name": "Jeroen Breuer",
                "parentId": "bff96d2a-18a7-4d72-b788-72e2034a5514",
                "sortOrder": 4,
                "umbracoFile": {
                    "src": "/media/fpydwmn0/18530280048_459b8b61b2_h.jpg",
                    "focalPoint": {
                        "left": 0.5,
                        "top": 0.5
                    },
                    "crops": null
                },
                "umbracoWidth": "1600",
                "umbracoHeight": "1067",
                "umbracoBytes": "240519",
                "umbracoExtension": "jpg"
            }
        ]
    }
}
--MultipartBoundary
Content-Disposition: form-data; name="content"
Content-Type: application/json

{
    "mediaTypeAlias": "Image",
    "name": "Han Solo",
    "parentId": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
    "umbracoFile": { "src": "han-solo.png" }
}
--MultipartBoundary
Content-Disposition: form-data; name="umbracoFile"; fileName="han-solo.png"
Content-Type: image/png

BINARY DATA
--MultipartBoundary--
{
    "_hasChildren": false,
    "_level": 2,
    "_createDate": "2019-10-10T12:24:58.76Z",
    "_id": "b60a1257-4bef-4d5a-aeb6-4af17b6233b2",
    "_updateDate": "2019-10-10T12:24:58.76Z",
    "_deleteDate": "2019-10-10T12:25:15.3860527Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2"
        },
        "root": {
            "href": "https://api.umbraco.io/media"
        },
        "children": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2/children"
        },
        "mediatype": {
            "href": "https://api.umbraco.io/media/type/Image"
        }
    },
    "mediaTypeAlias": "Image",
    "name": "Han Solo",
    "parentId": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
    "sortOrder": 1,
    "umbracoFile": {
        "src": "/media/kejavnxp/han-solo.png",
        "focalPoint": {
            "left": 0.5,
            "top": 0.5
        },
        "crops": null
    },
    "umbracoWidth": "672",
    "umbracoHeight": "896",
    "umbracoBytes": "489855",
    "umbracoExtension": "png"
}
Content-Type: multipart/form-data; boundary=MultipartBoundry

--MultipartBoundry
Content-Disposition: form-data; name="content"
Content-Type: application/json

{
    "mediaTypeAlias": "Image",
    "name": "Han Solo",
    "parentId": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
    "sortOrder": 1,
    "umbracoFile": { "src": "han-solo.png" }
}
--MultipartBoundry
Content-Disposition: form-data; name="umbracoFile"
Content-Type: image/png

BINARY DATA
--MultipartBoundry--
{
    "_hasChildren": false,
    "_level": 2,
    "_createDate": "2019-10-10T12:24:58.76Z",
    "_id": "b60a1257-4bef-4d5a-aeb6-4af17b6233b2",
    "_updateDate": "2019-10-10T12:24:58.76Z",
    "_deleteDate": "2019-10-10T12:25:15.3860527Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2"
        },
        "root": {
            "href": "https://api.umbraco.io/media"
        },
        "children": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2/children"
        },
        "mediatype": {
            "href": "https://api.umbraco.io/media/type/Image"
        }
    },
    "mediaTypeAlias": "Image",
    "name": "Han Solo",
    "parentId": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
    "sortOrder": 1,
    "umbracoFile": {
        "src": "/media/kejavnxp/han-solo.png",
        "focalPoint": {
            "left": 0.5,
            "top": 0.5
        },
        "crops": null
    },
    "umbracoWidth": "672",
    "umbracoHeight": "896",
    "umbracoBytes": "489855",
    "umbracoExtension": "png"
}
{
    "_hasChildren": false,
    "_level": 2,
    "_createDate": "2019-10-10T12:24:58.76Z",
    "_id": "b60a1257-4bef-4d5a-aeb6-4af17b6233b2",
    "_updateDate": "2019-10-10T12:24:58.76Z",
    "_deleteDate": "2019-10-10T12:25:15.3860527Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2"
        },
        "root": {
            "href": "https://api.umbraco.io/media"
        },
        "children": {
            "href": "https://api.umbraco.io/media/b60a1257-4bef-4d5a-aeb6-4af17b6233b2/children"
        },
        "mediatype": {
            "href": "https://api.umbraco.io/media/type/Image"
        }
    },
    "mediaTypeAlias": "Image",
    "name": "Han Solo",
    "parentId": "7bfa2332-cf7f-4c97-941d-50f43f085b06",
    "sortOrder": 1,
    "umbracoFile": {
        "src": "/media/kejavnxp/han-solo.png",
        "focalPoint": {
            "left": 0.5,
            "top": 0.5
        },
        "crops": null
    },
    "umbracoWidth": "672",
    "umbracoHeight": "896",
    "umbracoBytes": "489855",
    "umbracoExtension": "png"
}
> dotnet restore
> dotnet run
Booting Umbraco Headless console

Enter the Project Alias of your Headless Project
[A] Fetch and show Content Tree
[B] Fetch and show Media Tree
[C] Show Root Content
[D] Show Root Media
[E] List Content URLs
[F] Upload image to Media Library
[X] Exit
Enter your choice:
a

Fetching and listing Content tree

+- Home
   +- About
Enter your choice:
d

Fetching and showing root Media

'Company Logo' can be seen on: https://media.umbraco.io/dev-docs/8d7c736482a65b4/company_logo.jpg
'Company Logo Small' can be seen on: https://media.umbraco.io/dev-docs/8d7c73648f72d6a/company_logo_small.jpg
'Product01' can be seen on: https://media.umbraco.io/dev-docs/8d7c7364978df6c/Product01.jpg
'Product02' can be seen on: https://media.umbraco.io/dev-docs/8d7c7364a0b846c/Product02.jpg
'Product03' can be seen on: https://media.umbraco.io/dev-docs/8d7c7364a0b846c/Product03.jpg
blog post
custom elements
input event
import
Lit
Headless Backoffice Bridge
JSON Schema
UDI
headless backoffice bridge
Heartcore issue tracker
shadow DOM
Creating a Custom Grid Editor
Creating Content with Media
Umbraco Headless Client
create a trial
Content Delivery API
Content Management API.
API Key
.NET Standard client library
Node.js client library
.NET Standard
ASP.NET Core MVC
console application
Blazor Server sample
Node.js
Umbraco Cloud Portal
Heartcore Backoffice
Common Headers
Authentication
Errors
Get root media
Get by id
Get children
Create media
Update media
Delete media

Content Management Sample

Learn how to access and work with the Content Management API on your Umbraco Heartcore project.

Requirements

  • .NET/.NET Core (2.0 or newer) or .NET Framework (4.6.1 or newer)

Getting Started

  1. Add the Umbraco.Headless.Client.Net package to your project.

    dotnet add package Umbraco.Headless.Client.Net

  2. Add environment variables for your project alias and your API key.

    appsettings.json
    {
        "Heartcore": {
            "ProjectAlias": "your-project-alias",
            "ApiKey": "your-api-key"
        }
    }
  3. Register the ContentManagementService to your dependency injection container. The registration of the ContentManagementService is handled by the AddUmbracoHeartcore extension method.

Program.cs / Startup.cs
```csharp
builder.Services.AddUmbracoHeartcore(options =>
{
    //configure options
});
```
  1. Inject the ContentManagementService into your non-static class.

    private readonly ContentManagementService _contentManagementService;
    
    public UmbracoService(ContentManagementService contentManagementService)
    {
        _contentManagementService = contentManagementService;
    }

If you don't want to use dependency injection, you can manually create an instance of the ContentManagementService class. The constructor requires that you know the project alias and your API key.

var managementService = new ContentManagementService("your-project-alias", "your-api-key");

Now you are ready to start using the ContentManagementService.

Content

When working with content, the ContentManagementService can Get, Create, Update, Publish, Unpublish, and Delete content.

Get Content

The ContentManagementService has three methods for getting content.

GetRoot()

Gets all content at the root of the tree.

To use this method, call the method on the ContentManagementService instance:

var content = await _contentManagementService.Content.GetRoot();

GetById(Guid id)

Gets a specific content item matching a GUID.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the content item you want to get:

var content = await _contentManagementService.Content.GetById(yourGuidObject);
//or
var content = await _contentManagementService.Content.GetById(Guid.Parse("your-guid-as-a-string"));

GetChildren(Guid id)

Gets all content that is a child of a specific content item.

To use this method, call the method on the ContentManagementService instance and pass the GUID of the content item to get the children:

var content = await _contentManagementService.Content.GetChildren(yourGuidObject);
//or
var content = await _contentManagementService.Content.GetChildren(Guid.Parse("your-guid-as-a-string"));

Create Content

The ContentManagementService has one method for creating content.

Create(Content content)

Creates a new content item based on the passed-in Content object.

To use this method, call the method on the ContentManagementService instance and pass in the content item you want to create:

var newContent = await _contentManagementService.Content.Create(yourContentObject);

Update Content

The ContentManagementService has one method for updating content.

Update(Content content)

Updates an existing content item based on the passed-in Content object.

To use this method, call the method on the ContentManagementService instance and pass in the content item you want to update:

var updatedContent = await _contentManagementService.Content.Update(yourContentObject);

Publish Content

The ContentManagementService has one method for publishing content.

Publish(Guid id, string culture = "*")

Publishes an existing content item based on the passed-in GUID and culture.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the content item you want to publish:

var publishedContent = await _contentManagementService.Content.Publish(yourGuidObject);
//or
var publishedContent = await _contentManagementService.Content.Publish(Guid.Parse("your-guid-as-a-string"));

Optionally, you can also pass in the culture of the content item you want to publish:

var publishedContent = await _contentManagementService.Content.Publish(yourGuidObject, "en-US");
//or
var publishedContent = await _contentManagementService.Content.Publish(Guid.Parse("your-guid-as-a-string"), "en-US");

Unpublish Content

The ContentManagementService has one method for unpublishing content.

Unpublish(Guid id, string culture = "*")

Unpublishes an existing content item based on the passed-in GUID and culture.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the content item you want to unpublish:

var unpublishedContent = await _contentManagementService.Content.Unpublish(yourGuidObject);
//or
var unpublishedContent = await _contentManagementService.Content.Unpublish(Guid.Parse("your-guid-as-a-string"));

Optionally, you can also pass in the culture you want to unpublish the content item in:

var unpublishedContent = await _contentManagementService.Content.Unpublish(yourGuidObject, "en-US");
//or
var unpublishedContent = await _contentManagementService.Content.Unpublish(Guid.Parse("your-guid-as-a-string"), "en-US");

Delete Content

The ContentManagementService has one method for deleting content.

Delete(Guid id)

Deletes an existing content item based on the passed-in GUID.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the content item you want to delete:

var deletedContent = await _contentManagementService.Content.Delete(yourGuidObject);
//or
var deletedContent = await _contentManagementService.Content.Delete(Guid.Parse("your-guid-as-a-string"));

Media

When working with media, the ContentManagementService can Get, Create, Update and Delete media.

For Media you create programmatically, you have to use the "raw" property values that Umbraco expects for the specific property editor.

The different scenarios are:

  1. File Upload (A File Upload property editor)

    When uploading a file, you must specify the file name for the umbracoFile property alias.

    var media = new Umbraco.Headless.Client.Net.Management.Models.Media {
        Name = "name-of-media", 
        MediaTypeAlias = "File", 
        ParentId = parentFolderGuidObject};
    media.SetValue(
        "umbracoFile", 
        fileName, 
        new FileInfoPart(new FileInfo(imagePath), 
        fileName, 
        $"image/{Path.GetExtension(imagePath).Trim('.')}"));
  2. Image Upload (A Image Cropper property editor)

    When uploading an Image (by default, it uses the Image Cropper property editor), you must specify the source's file name for the umbracoFile property alias.

    var media = new Umbraco.Headless.Client.Net.Management.Models.Media {
        Name = "name-of-media", 
        MediaTypeAlias = "Image", 
        ParentId = parentFolderGuidObject};
    media.SetValue(
        "umbracoFile", 
        new { src = fileName }, 
        new FileInfoPart(new FileInfo(imagePath), 
        fileName, 
        $"image/{Path.GetExtension(imagePath).Trim('.')}"));

Get Media

The ContentManagementService has three methods for getting media.

GetRoot()

Gets all media at the root of the tree.

To use this method, call the method on the ContentManagementService instance:

var rootMedia = await _contentManagementService.Media.GetRoot();

GetById(Guid id)

Gets a specific media item matching a GUID.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the media item you want to get:

var media = await _contentManagementService.Media.GetById(yourGuidObject);
//or
var media = await _contentManagementService.Media.GetById(Guid.Parse("your-guid-as-a-string"));

GetChildren(Guid id)

Gets all media that is a child of a specific media item.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the media item to get the children:

var mediaChildren = await _contentManagementService.Media.GetChildren(yourGuidObject);
//or
var mediaChildren = await _contentManagementService.Media.GetChildren(Guid.Parse("your-guid-as-a-string"));

Create Media

The ContentManagementService has one method for creating media.

Create(Media media)

Creates a new media item based on the passed-in Media object.

To use this method, call the method on the ContentManagementService instance and pass in the media item you want to create:

var newMedia = await _contentManagementService.Media.Create(yourMediaObject);

Update Media

The ContentManagementService has one method for updating media.

Update(Media media)

Updates an existing media item based on the passed-in Media object.

To use this method, call the method on the ContentManagementService instance and pass in the media item you want to update:

var updatedMedia = await _contentManagementService.Media.Update(yourMediaObject);

Delete Media

The ContentManagementService has one method for deleting media.

Delete(Guid id)

Deletes an existing media item based on the passed-in GUID.

To use this method, call the method on the ContentManagementService instance and pass in the GUID of the media item you want to delete:

var deletedMedia = await _contentManagementService.Media.Delete(yourGuidObject);
//or
var deletedMedia = await _contentManagementService.Media.Delete(Guid.Parse("your-guid-as-a-string"));

Further reading

MVC Sample

In /samples/Umbraco.Headless.Client.Samples.Web/ you will find a .NET 6.0-based MVC website implementation. It presents one possible approach to creating a website using Umbraco Heartcore for Content Delivery.

The sample is built around a sample project with the alias demo-headless. You can choose to test the sample with the sample project or connect the sample to your own project.

Prerequisites

Run the sample on your local machine

Before running the sample, you must define which Umbraco Heartcore project you want to fetch content from.

  • Open the appsettings.json found in samples/Umbraco.Headless.Client.Samples.Web/Umbraco.Headless.Client.Samples.Web/

  • Add your project alias or use the default alias of the sample project, demo-headless

{
    "Heartcore": {
        "ProjectAlias": "demo-headless",
        "ApiKey": ""
    }
}

The MVC sample can be run in one of two ways:

1. Use the command line

Using a command-line tool, run the following two commands in the Umbraco.Headless.Client.Samples.Web folder:

dotnet restore
dotnet run

The first command will restore the packages and the second will run the site. Alternatively, you can use the new hot-reload functionality:

dotnet watch run

To run the project and hot reload or recompile the project whenever changes are detected.

2. Using an Integrated Development Environment (IDE)

Run the application in Visual Studio or Visual Studio Code by hitting F5.

  • Visual Studio Code (VSCode) requires you to have a launch configuration before F5will work.

  • The editor will prompt you to add a launch configuration if you have the C# extension installed in VSCode.

Show your content

For the following section, a Umbraco Heartcore project with the following content structure will be used:

When you have connected the client project to your Umbraco project and run the client project, you will be presented with a default page. The page shows the properties and the data from the content node at the root of your website. This is because no view or controller has yet been defined for your content structure.

We will need to define and build a view and/or an MVC controller for the content types (Document Types) in our client project in order for us to start rendering content.

There are two ways to do this:

  • Define a view file using the Document Type alias or

  • Build a controller using the already defined UmbracoController

Each approach is explained in more detail below.

Define a view file

  1. Create a model class for the content type you want to render, e.g., Models/HomePage.cs. Make sure the model extends the abstract class Content and that the properties you want to render from the Umbraco content node are defined as public properties with PascalCasing. PascalCasing means that a content node property called personName will be mapped to the PersonName property in the model.

  2. Create a homePage.cshtml file in Views/DefaultUmbraco - the name of the file should be the alias of the Document Type the root content node is using.

  3. Set HomePage as the model.

  4. Set layout to null - this can be used later on when you want to share one layout between more views.

@model Umbraco.Headless.Client.Net.Delivery.Models.Content
@{
    Layout = null;
}

When you build the solution and start it up, this view file will now be used to populate the frontend.

Build a controller

  1. Right-click the Controllers folder in Visual Studio and select Add > Controller...

  2. Select MVC Controller - Empty

  3. Use the alias of the Document Type used on the root content node for the name of the controller, e.g. HomePageController

  4. Set the controller to use UmbracoController

  5. Set the Index() action to return UmbracoContext.Content

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Headless.Client.Samples.Web.Mvc;

namespace Umbraco.Headless.Client.Samples.Web.Controllers
{
    public class HomePageController : Controller
    {
        public HomePageController(UmbracoContext umbracoContext) : base(umbracoContext)
        {
        }

        public IActionResult Index()
        {
            return View(UmbracoContext.Content);
        }
    }
}

The controller is now in place but to show our content we also need to define a view.

  1. Create a folder in /Views using the alias of the Document Type, e.g. /HomePage.

  2. Create an Index.cshtml file in the new folder.

  3. Build and run the solution.

Building view files

To render the data from the properties on our content, we need to use the @Model.PropertyName approach, where the value is the Name of the property you want to display the data from.

An example could be a text string property with the alias heading. To render the data from this property on the frontend, we will need to use @Model.Heading.

note To render data from a property, the property must be defined in the view model (@model), and it must match an alias on the corresponding content node from your Umbraco project.

Below is a complete example of how a view for a root node could look.

@using Umbraco.Headless.Client.Net.Delivery.Models;
@model HeroPage
@{
    Layout = null;
}

<!DOCTYPE HTML>
<html>

<head>
    <title>@Model.Title</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
</head>

<body>

    <h1>@Model.Heading</h1>

    <div>

        <p>@Html.Raw(Model.BodyText)</p>

        <img src="@(Model.PromoImage?.Url)?width=300" />

    </div>

</body>
</html>

HTML is used to build the general structure of the article, while we use Razor to render data from our Umbraco Heartcore project.

References

April 2024

The following changes have been released to all Heartcore sites.

Grid Disabled By Default

Sites that already have Grid Data Types in use will continue to offer the full range of grid support. Grid content can also be imported from a zip package, which will also fully enable support for it across the environment.

Management API Property Type Configuration

Notable Bugfixes

Fixes for commonly-reported issues this month include:

  • The root endpoint of the management API now correctly returns links to other endpoints.

  • The API explorer in the backoffice is no longer prevented from returning responses from the management API due to a Cross-Origin Resource Sharing (CORS) error.

  • The alias for dev & staging environments should no longer point at the live content APIs.

  • The webhook log viewer will now correctly load information about attempted runs.

  • When previewing content in a multilingual setup, the preview window will no longer indefinitely hang until you save the selected variant.

Custom Grid Editors

Learn how to create a Custom Grid Editor in Umbraco Heartcore.

Content

Create a Document Type and grid configuration

First, we will need to create a Document Type containing the Grid Layout property editor.

  • Go to the Settings section.

  • Create a new Document Type called Grid Page.

  • Add a new property called Grid Content.

  • Select the Grid layout editor.

  • Accept the default configuration.

The Document Type should now look like this:

To allow the Document Type to be created in the tree we need to change the permissions:

  • Select the Permissions tab.

  • Ensure Allow as root is checked.

To verify the configuration follow these steps:

  • Go to the Content section.

  • Create a new page based on the Grid Page Document Type we created.

  • Give it a name.

  • Save the page.

Try choosing a layout, add a row and click Add content. Here we will see that we have a couple of editors to choose from.

Try adding one of them to the page to see how they work.

A look at a default grid editor

Before we start writing our own Grid Editor, let's have a look at the Headline Grid Editor.

As we can see the page is divided into two sections; one with a Text Editor with the code for the editor and one with a preview of the editor.

Let's take a look at the code.

A custom editor inherits from HTMLElement and must be the default export.

export default class extends HTMLElement {
  #textarea
  #template = `<textarea
    rows="1"
    placeholder="Write here..."
    class="textstring input-block-level"
    style="font-size: 36px; line-height: 45px; font-weight: bold"></textarea>`

In the constructor we set the inner HTML of our custom element to our template and set the #textarea field to a reference to the textarea.

  constructor() {
    super()

    this.innerHTML = this.#template
    this.#textarea = this.querySelector('textarea')
  }

The click method is called when the grid control is clicked. In this case we use it to set focus on the textarea.

  click() {
    this.#textarea.focus()
  }

A value property is needed for the value to be stored when a page is saved and to set the value when the editor is loaded.

In this example the value property is setting and returning the value of the textarea.

  get value() { return this.#textarea.value }
  set value(value) {
    this.#textarea.value = value || ''
  }
}

Create a custom grid editor

  • Go to the Settings section.

  • Create a new Grid Editor.

  • Choose an icon.

  • Name it Image Gallery.

  • Change the alias to my-image-gallery.

The alias is used as the custom element tag name and must be unique. By choosing a prefix that is less likely to used by any other HTML element, in this case my-, there is less chance for running into conflicts.

In the JS view we can see there is already some boilerplate code. Let's replace it with the following:

import { LitElement, css, html } from 'https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js'

export default class extends LitElement {
  static properties = {
    value: { type: Array },
  }

  static styles = css`
.container {
  display: grid;
  grid-gap: 5px;
  grid-template-columns: repeat(auto-fit, 200px);
  padding: 5px;
}
.add-button {
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  cursor: pointer;
  width: 200px;
  height: 200px;
  padding: 20px;
  padding-bottom: 30px;
  background-color: var(--color-white);
  border: 4px dashed var(--color-gray-8);
  text-align: center;
  box-sizing: border-box;
}
.add-button svg {
  display: block;
  fill: var(--color-gray-8);
  font-size: 85px;
  line-height: 1;
  display: inline-block;
  height: 1.15em;
  width: 1.15em;
  margin: 10px auto;
}
.add-button div {
  color: var(--color-black);
  font-size: 14px;
  font-weight: 700;
}
`

  render() {
    return html`<div class="container">
      <button class="add-button">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
          <path d="M246.486 299.31l-85.604-91.047-58.21 107.66v29.658h289.12c-36.821-31.753-114.476-99.682-114.476-99.682l-30.83 53.411zM347 230.786c16.062 0 29.073-13 29.073-29.06 0-16.04-13.012-29.062-29.073-29.062-16.019 0-29.038 13.021-29.038 29.062 0 16.06 13.019 29.06 29.038 29.06zM37.74 102.699v306.569h434.688V102.699H37.74zm396.082 267.916H77.635l-.016-228.033h354.928v.017h1.275v228.016z"></path>
        </svg>
        <div>Add image</div>
      </button>
    </div>`
  }
}

The preview should now look like this:

Let's break down the code.

import { LitElement, css, html } from 'https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js'

Here we're importing LitElement, CSS and HTML from the Lit library.

export default class extends LitElement {

We're exporting a default class inheriting from LitElement.

  static properties = {
    value: { type: Array },
  }

We tell Lit that we have a value property which we expect to be an Array.

  static styles = css`
.container {
  display: grid;
  grid-gap: 5px;
  grid-template-columns: repeat(auto-fit, 200px);
  padding: 5px;
}
.add-button {
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  cursor: pointer;
  width: 200px;
  height: 200px;
  padding: 20px;
  padding-bottom: 30px;
  background-color: var(--color-white);
  border: 4px dashed var(--color-gray-8);
  text-align: center;
  box-sizing: border-box;
}
.add-button svg {
  display: block;
  fill: var(--color-gray-8);
  font-size: 85px;
  line-height: 1;
  display: inline-block;
  height: 1.15em;
  width: 1.15em;
  margin: 10px auto;
}
.add-button div {
  color: var(--color-black);
  font-size: 14px;
  font-weight: 700;
}
  render() {
    return html`<div class="container">
      <button class="add-button">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
          <path d="M246.486 299.31l-85.604-91.047-58.21 107.66v29.658h289.12c-36.821-31.753-114.476-99.682-114.476-99.682l-30.83 53.411zM347 230.786c16.062 0 29.073-13 29.073-29.06 0-16.04-13.012-29.062-29.073-29.062-16.019 0-29.038 13.021-29.038 29.062 0 16.06 13.019 29.06 29.038 29.06zM37.74 102.699v306.569h434.688V102.699H37.74zm396.082 267.916H77.635l-.016-228.033h354.928v.017h1.275v228.016z"></path>
        </svg>
        <div>Add image</div>
      </button>
    </div>`
  }
}

Let's save the editor and see how it looks when adding it to the a content item.

We now have the Add image button rendering, but clicking it does nothing. Let's do something about that.

  • Go back to the Settings section.

  • Click on the Image Gallery Grid Editor.

We will start by adding the following to the top of the file:

import { mediaPicker } from 'https://cdn.jsdelivr.net/npm/@umbraco/headless-backoffice-bridge@0/headless-backoffice-bridge.min.js'

We will add another function before the render function:

showPicker() {
  mediaPicker.show({
    disableFolderSelect: true,
    onlyImages: true,
    showDetails: true,
    submit: (items) => {
      const selected = items[0]
      if(!this.value) this.value = []
      this.value.push(({ url: selected.udi, ...selected }))
      this.requestUpdate('value')
    }
  })
}

This will open the Media Picker with a configuration that only allows selecting images and showing the detail view, which allows us to enter an alt text, caption and choose a focal point.

The submit callback is called when the Submit is clicked. It will contain an array of the selected items. In this case it will contain a single item, but if we set multiple to true multiple items can be returned.

In our callback method we check if this.value has been initialized. If it has not we initialize a new array. We then push the selected image to the array. Note that we also store the udi (the id of the media) in a url property. We will come back to why we do that later.

Since we add to the array and do not set the value property we need to tell Lit that the property was updated. We do this by calling this.requestUpdate('value').

We will also need to add a click event to the button so it will show the dialog:

<button type="button" class="add-button" @click=${() => this.showPicker()}>

Clicking the button in preview mode does nothing. This is because of a limitation when previewing where we do not have access to the full backoffice. Saving and testing on a Content item should work.

  • Click Save.

  • Go back to the content page.

  • Click the Add image button.

We should now see the image overlay.

Selecting an image does not currently render anything. Let's do something about that. Go back to the grid editor code in the Settings section.

Update the render() function with the following

render() {
  const items = this.value || []

  return html`<div class="container">
    ${items.map(image => html`<umbh-image width="200" height="200" udi=${image.udi} alt=${image.altText} .focalPoint=${image.focalPoint}></umbh-image>`)}
    <button class="add-button" @click=${() => this.showPicker()}>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
        <path d="M246.486 299.31l-85.604-91.047-58.21 107.66v29.658h289.12c-36.821-31.753-114.476-99.682-114.476-99.682l-30.83 53.411zM347 230.786c16.062 0 29.073-13 29.073-29.06 0-16.04-13.012-29.062-29.073-29.062-16.019 0-29.038 13.021-29.038 29.062 0 16.06 13.019 29.06 29.038 29.06zM37.74 102.699v306.569h434.688V102.699H37.74zm396.082 267.916H77.635l-.016-228.033h354.928v.017h1.275v228.016z"></path>
      </svg>
      <div>Add image</div>
    </button>
  </div>`
}

We assign the editor value to a local variable items, if this.value is null or undefined we assign an empty array. Then in the HTML we are now looping over the items and returning an umbh-image for each item. umbh-image is a custom element included with the backoffice bridge, it takes an udi and renders an images based on that.

Go back to the Content section try to add some images to a page using the editor.

We now have an editor that we can add images to which gets rendered in the backoffice. Next step would be to add edit and delete functionality, but we will leave that to the reader.

Using module aliases

Up until now we have been using the full URL when importing third party modules into our editors. While this works fine most of the time, we will most likely run into issues when importing libraries that registers custom elements. This is because custom elements needs to be registered using an HTML tag and a tag can only be registered once.

Imagine we have an editor using custom elements from a third party library. We then create another editor using the same library but in a newer version which adds some new functionality to the custom element we use.

One of two things will happen:

  1. The library checks if a custom element with the same name has already been registered and skips registration. This will leave us not knowing which version is used and might break our implementation.

  2. It will try to register the element with the same name but fail because there is already an element registered with the same name.

In either case we will end up with a broken editor experience. This is where module aliases comes in.

Module aliases allows us to define a common name for a module that we can use in our editors instead of the full URL. A module alias can be defined by going to the Headless -> Custom Editor Configuration page in the Settings section.

With this alias added we can update our import in our editor to:

import { mediaPicker } from '@headless-backoffice-bridge'

The alias will automatically be replaced with the URL we have defined, similar to how node does.

By using the same alias in all our editors, we can ensure that only one version of the library is loaded. If we want to upgrade to a newer version, we will only need to update the URL in one place.

Describing the grid editor using JSON schema

Now that we have a working editor, let's add a couple of images to our page. When done, click Save and publish.

Note down the Id from the Info tab. We will need that in a bit.

  • Go to the Settings section.

  • Expand the Headless node.

  • Type in https://cdn.umbraco.io/content/<CONTENT_ID> in the Explorer URL bar, replacing <CONTENT-ID> with the id we copied before.

  • Click Go!.

In the output we can see the JSON we have stored in the editor.

Let's go back to our Grid Editor implementation and see what we can do.

Looking at the default JSON schema we can see that the type is set to string. This tells Heartcore that our editor is returning its data as a string. This is what we saw before in the API response. Since we are storing an array of images, let's change the type to array. We also need to specify what the array is containing. We do that by adding an items property containing a type: object property.

  • Change the type from string to array

  • Add an items property containing a type: object property.

The schema should now look like this:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "array",
    "items": {
        "type": "object"
    }
}

Let's go back to the API Browser, type the same URL as before and click Go!.

Inspecting the output, we can already see an improvement. The value is now returned as an array which is already much better.

Remember the url property stored earlier? Let's make it return a URL instead of a UDI.

  • Go back to the Grid Editor schema.

  • Update it to the following:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "url": { "type": "string", "format": "uri-reference" }
        }
    }
}

With the JSON above we are adding a properties object containing a url property. This property has its type set to string, and most importantly, format set to uri-reference. By specifying the format as uri-reference Heartcore will try to parse the value as a UDI and if the UDI is for either a document or media, the URL of that item will be returned instead. We can see that if we go back to the API Browser.

We now have an array where each item has the URL to the picked media item.

While it is not necessary to define all properties in the JSON Schema, it is highly recommended as the schema is also used for validating the editor data when saving.

Besides the uri-reference format there's also rich-text. This is useful when storing rich text data like the output from the TinyMCE editor. When specifying the rich-text format, things like {locallink} and data-uri will automatically be replaced with the correct URLs.

Related articles

Querying with GraphQL

Learn how to query Umbraco Heartcore with GraphQL.

In this tutorial we will be looking at how we can fetch data from Umbraco Heartcore using GraphQL.

We will be using https://demo.heartcore.dev/ as a reference.

At the end of the tutorial we should be able to use the Umbraco Heartcore GraphQL API and be able to fetch all the content needed to render the page in with a single query.

Creating the Document Types

First, we will need to create some Document Types, and as a start, we will create some element types.

Start by creating a folder named Elements under the Document Types folder in the Settings section of the Backoffice.

In that folder create the following Document Types:

Text and Image

Alias: textAndImage

Add a new group called Content with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Title

title

Textstring

Use defaults

Text

text

Rich Text Editor

Use defaults

Image

image

Media Picker

Pick multiple items: not checked Pick only images: checked Disable folder select: checked

Show large image

showLargeImage

Checkbox

Use defaults

Then under permissions check Element Type

Unique Selling Point

Alias: uniqueSellingPoint

Add a new group called Content with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Image

image

Media Picker

Pick multiple items: not checked Pick only images: checked Disable folder select: checked

Title

title

Textstring

Use defaults

Text

text

Textarea

Use defaults

Link

link

Multi Url Picker

Max number of items: 1

Then under permissions check Element Type


Then create another folder called Compositions and create the following Document Types in that folder:

Elements Composition

Alias: elementsComposition

Add a new group called Elements with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Elements

elements

Nested Content

Document Types: Element Type: Text and image, Group: Content, Template: {{title}} Confirm Deletes: checked Show icons: checked Hide label: checked

Then click the Reorder button and change the value for Elements from 0 to 15

Hero Composition

Alias: heroComposition

Add a new group called Hero with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Image

heroImage

Media Picker

Pick multiple items: not checked Pick only images: checked Disable folder select: checked

Title

heroTitle

Textstring

Use defaults

Subtitle

heroSubtitle

Textstring

Use defaults

Unique Selling Points Composition

Alias: uniqueSellingPointsComposition

Add a new group called Unique Selling Points with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Title

uniqueSellingPointsTitle

Textstring

Document Types: Use defaults

Unique Selling Points

uniqueSellingPoints

Nested Content

Document Types: Element Type: Unique Selling Point, Group: Content, Template: {{title}} Confirm Deletes: checked Show icons: not checked Hide label: checked

Then click the Reorder button and change the value for Elements from 0 to 20


At the root create the following Document Types:

Textpage

Alias: textpage

Click on Compositions and select Elements Composition and Hero Composition

Frontpage

Alias: frontpage

Add a new group called Footer with the following properties:

Name
Alias
Property Editor
Property Editor Configuration

Title

footerTitle

Textstring

Use defaults

Links

footerLinks

Multi Url Picker

Use defaults

Then click on Compositions and select Elements Composition, Hero Composition and Unique Selling Points Composition, click on Submit.

On the permissions tab check Allow at root and add Textpage to the Allowed child node types property.

Then go to the Content section and create a new Frontpage with the name Home and create some subpages.

Querying the GraphQL API

The GraphQL endpoint accepts POST requests with the content type application/json, the body should be an object containing as a minimum a query property, for example

{
  "query": "..."
}

Lets start with a basic query that fetches the name, url, and heroTitle properties from the Frontpage.

{
  frontpage(url: "/home/") {
    name
    url
    heroTitle
  }
}

Result:

{
  "data": {
    "frontpage": {
      "name": "Home",
      "url": "/home/",
      "heroTitle": "Umbraco Heartcore"
    }
  }
}

Making the Query Generic

Up until now, we have been working on a single Document Type. In most cases this is fine, but since we want to dynamically fetch content based on the URL we can use the content field.

The content field returns the Content interface type that contains the default fields. To allow us to query the fields on the derived types we can use fragments.

A fragment allows us to query data on the underlying concrete type.

{
  content(url: "/home/") {
    name
    ... on Frontpage {
      heroTitle
      heroSubtitle
      heroImage {
        url(width: 1980, height: 430, cropMode: CROP)
      }
    }
  }
}

This returns the following JSON:

{
  "data": {
    "content": {
      "name": "Home",
      "heroTitle": "Umbraco Heartcore",
      "heroSubtitle": "Umbraco Heartcore is a headless CMS by Umbraco. With Heartcore, you can use the Umbraco backoffice to manage content and media that's ready to be displayed on any device.",
      "heroImage": {
        "url": "https://media.umbraco.io/demo-headless/8d832c5cee78cf8/umbraco-heartcore-preview.png?mode=crop&width=1980&height=430&upscale=false"
      }
    }
  }
}

The query is fetching the name field which exists on the Content interface, it also fetches the heroTitle, heroSubtitle and heroImage on the Frontpage type.

Querying Composition Fields

There is one problem with our query though. Try changing the url argument to a subpage and see whats happening.

As you can see we don't get any data back for the hero fields, even though our Document Type has those fields. This is because we are telling GraphQL that we only want them on the Frontpage type. You might be tempted to fix this by adding another fragment on the Textpage type which would work, but remember we created a Document Type that only contains hero fields which we have added as a Composition to both the Frontpage and Textpage Document Types. We can change the ... on Frontpage fragment to ... on HeroComposition and we will now get the expected data back.

Now our query looks like this:

{
  content(url: "/home/") {
    name
    ... on HeroComposition {
      heroTitle
      heroSubtitle
      heroImage {
        url(width: 1980, height: 430, cropMode: CROP)
      }
    }
  }
}

Querying Nested Content

Since Nested Content is an interface named Element we can query the fields by the specific type using fragments.

{
  frontpage(url: "/home/") {
    elements {
      ... on TextAndImage {
        title
        text
        showLargeImage
        image {
          small: url(width: 320, height: 240, cropMode: CROP)
          medium: url(width: 480, height: 360, cropMode: CROP)
          large: url(width: 1024, height: 768, cropMode: CROP)
        }
      }
    }
  }
}

Now try to write a query that fetches the title, text, link and image fields for the Unique Selling Points property.

Querying the Main Navigation and Footer

The only thing we are missing now to be able to render the complete page is the main navigation and the footer.

The main navigation is showing the children of the frontpage, we can fetch them with the following query:

{
  frontpage(url: "/home/") {
    children {
      edges {
        node {
          name
          url
        }
      }
    }
  }
}

The footer can be fetched using the following query:

{
  frontpage(url: "/home/") {
    footerTitle
    footerLinks {
      name
      target
      type
      url
    }
  }
}

We can even combine the two queries into a single query:

{
  global: frontpage(url: "/home/") {
    mainNavigation: children {
      edges {
        node {
          name
          url
        }
      }
    }
    footerTitle
    footerLinks {
      name
      target
      type
      url
    }
  }
}

In the query above we are also using field aliases, this means that in the response data frontpage will be named global and children will be named mainNavigation.

{
  "data": {
    "global": {
      "mainNavigation": {
        "edges": [
          {
            "node": {
              "name": "What is a Headless CMS?",
              "url": "/home/what-is-a-headless-cms/"
            }
          },
          {
            "node": {
              "name": "What you get with Umbraco Heartcore",
              "url": "/home/what-you-get-with-umbraco-heartcore/"
            }
          }
        ]
      },
      "footerTitle": "About Umbraco",
      "footerLinks": [
        {
          "name": "Umbraco Website",
          "target": "_blank",
          "type": "EXTERNAL",
          "url": "https://umbraco.com/products/umbraco-heartcore"
        },
        {
          "name": "Umbraco Heartcore Documentation",
          "target": "_blank",
          "type": "EXTERNAL",
          "url": "https://docs.umbraco.com/umbraco-heartcore/"
        }
      ]
    }
  }
}

Using Variables

You might have noticed that the url argument is hardcoded in the query. This means that we will always get back the Content for that url. What we want is to pass the argument to the query dynamically.

We can do this by altering the query to include a variable instead of the hardcoded value, this can be done by replacing the argument with $url and wrapping the query with query($url: String).

query ($url: String!){
  content(url: $url) {
    name
    ... on HeroComposition {
      heroTitle
      heroSubtitle
      heroImage {
        url(width: 1980, height: 430, cropMode: CROP)
      }
    }
  }
}

And then we pass the variable in a separate JSON property called variables

{
  "query": "...",
  "variables": {
    "url": "/home/"
  }
}

Putting it all together

Now that we have all the individual parts we can combine it all into a single query that fetches all the data needed to display the pages on our site:

query($url: String!) {
  content(url: $url) {
    ...Hero
    ...UniqueSellingPoints
    ...Elements
  }
  global: frontpage(url: "/home/") {
    mainNavigation: children {
      edges {
        node {
          name
          url
        }
      }
    }
    footerTitle
    footerLinks {
      name
      target
      type
      url
    }
  }
}

fragment Hero on HeroComposition {
  heroTitle
  heroSubtitle
  heroImage {
    url(width: 1980, height: 430, cropMode: CROP)
  }
}

fragment Elements on ElementsComposition {
  elements {
    ... on TextAndImage {
      title
      text
      showLargeImage
      image {
        small: url(width: 320, height: 240, cropMode: CROP)
        medium: url(width: 480, height: 360, cropMode: CROP)
        large: url(width: 1024, height: 768, cropMode: CROP)
      }
    }
  }
}

fragment UniqueSellingPoints on UniqueSellingPointsComposition {
  uniqueSellingPointsTitle
  uniqueSellingPoints {
    ... on UniqueSellingPoint {
      title
      text
      link {
        name
        target
        type
        url
      }
      image {
        url
      }
    }
  }
}

Variables:

{
  "url":"/home/"
}

Deployment workflow

Having multiple environments on your Umbraco Heartcore project can be a great asset for testing and having a place where your content editors can work without interfering with anything on the Live environment.

When working with multiple environments, it is important to follow the correct workflow. In this article, you can learn more about the workflow and the best practices for using it.

The workflow uses a classic "left to right" deployment model, meaning that changes are first made on the Development environment and then deployed to the Staging or Live environment. The workflow depends on whether you have a Staging environment which further depends on the plan your project is on.

We recommend that you do not work with Document Types directly on the Live environment. This should, as a rule of thumb always be done on the "lowest most" environment: the Development environment.

The deployment approach is divided into two steps:

  1. Structure changes like Document Types and Data Types are deployed via the project portal page

  2. Content and Media are transferred/restored via the Umbraco Backoffice

Each step is defined in more details in the following articles.

Rate Limits

Umbraco Heartcore is subject to soft rate limits for requests to the delivery APIs. These limits are based upon the plan tier of the project, as follows:

Plan Tier
Requests per second

Starter

25

Standard

50

Professional

75

Enterprise

Starting from 75

Excluded Traffic

Requests to the Content Management API are not limited.

Rate limits are individual for each of the GraphQL, Content Delivery, and Preview APIs. For example, a Standard Heartcore project may make up to 50 requests per second each of GraphQL and Content Delivery without being in violation.

When a request is made to the Content Delivery or GraphQL APIs, the result is cached. Subsequent requests to the same endpoint with the same parameters will return the cached result. Cached results expire after a variable period or after publishing relevant content. Requests served from the cache do not count toward the rate limit.

Soft limits

Rate limits to Heartcore APIs are currently soft limits. That is, whenever a given environment receives requests above the limit, it will continue to serve responses normally. Umbraco may contact the owner of projects that exceed their allowed rate limit.

Structure deployments

Structure changes like new and/or updated Document Types need to be deployed through environments using the Project View in the Cloud Portal.

In the screenshot above, changes made on a Development environment are ready to be deployed to the Live environment, as indicated by the blue button: "Deploy changes to Live". Had there been a Staging environment on the project, the changes would first be sent to the Staging and then opened up for the option to deploy from Staging to Live.

A deployment from one environment (source) to another (target) goes through the following steps:

  1. The target environment is checked for changes

  2. If changes are found, these are pulled down and merged into the source environment

  3. The changes in the source environment are then pushed to the target environment

This process might take a few minutes, depending on the amount of changes being deployed.

Media

BASE URL: https://cdn.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

401

Unauthorized

Authorization has been denied for this request.

404

NotFound

Media with id '{id}' could not be found.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "NotFound",
    "message": "Media with id 'b6f11172-373f-4473-af0f-0b0e5aefd21c' could not be found."
  }
}

Get root media

Get all media at the root of the tree.

URL: /media

Method: GET

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://cdn.umbraco.io/media"
        },
        "media": [
            {
                "href": "https://cdn.umbraco.io/media/b6f11172-373f-4473-af0f-0b0e5aefd21c"
            },
            {
                "href": "https://cdn.umbraco.io/media/1fd2ecaf-f371-4c00-9306-867fa4585e7a"
            },
            {
                "href": "https://cdn.umbraco.io/media/6d5bf746-cb82-45c5-bd15-dd3798209b87"
            }
        ]
    },
    "_embedded": {
        "media": [
            {
                "_creatorName": "Rasmus",
                "_url": "",
                "_writerName": "Rasmus",
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-06-17T13:46:41.47Z",
                "_id": "b6f11172-373f-4473-af0f-0b0e5aefd21c",
                "_updateDate": "2019-06-17T13:46:41.47Z",
                "_links": {
                    "self": {
                        "href": "https://cdn.umbraco.io/media/b6f11172-373f-4473-af0f-0b0e5aefd21c"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "Design",
                "sortOrder": 1
            },
            {
                "_creatorName": "Rasmus",
                "_url": "",
                "_writerName": "Rasmus",
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-06-17T13:46:41.64Z",
                "_id": "1fd2ecaf-f371-4c00-9306-867fa4585e7a",
                "_updateDate": "2019-06-17T13:46:41.64Z",
                "_links": {
                    "self": {
                        "href": "https://cdn.umbraco.io/media/1fd2ecaf-f371-4c00-9306-867fa4585e7a"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "People",
                "sortOrder": 1
            },
            {
                "_creatorName": "Rasmus",
                "_url": "",
                "_writerName": "Rasmus",
                "_hasChildren": true,
                "_level": 1,
                "_createDate": "2019-06-17T13:46:41.783Z",
                "_id": "6d5bf746-cb82-45c5-bd15-dd3798209b87",
                "_updateDate": "2019-06-17T13:46:41.783Z",
                "_links": {
                    "self": {
                        "href": "https://cdn.umbraco.io/media/6d5bf746-cb82-45c5-bd15-dd3798209b87"
                    }
                },
                "mediaTypeAlias": "Folder",
                "name": "Products",
                "sortOrder": 1
            }
        ]
    }
}

Get by id

Get a single media by its ID.

URL: /media/{id}

Method: GET

Success Response

Code: 200

Content Example:

{
    "_creatorName": "Rasmus",
    "_url": "https://media.umbraco.io/my-headless-site/media/662af6ca411a4c93a6c722c4845698e7/00000006000000000000000000000000/16403439029_f500be349b_o.jpg",
    "_writerName": "Rasmus",
    "_hasChildren": false,
    "_level": 2,
    "_createDate": "2019-06-17T13:46:42.203Z",
    "_id": "662af6ca-411a-4c93-a6c7-22c4845698e7",
    "_updateDate": "2019-06-17T13:46:42.203Z",
    "_links": {
        "self": {
            "href": "https://cdn.umbraco.io/media/662af6ca-411a-4c93-a6c7-22c4845698e7"
        },
        "root": {
            "href": "https://cdn.umbraco.io/media"
        },
        "children": {
            "href": "https://cdn.umbraco.io/media/662af6ca-411a-4c93-a6c7-22c4845698e7/children"
        },
        "parent": {
            "href": "https://cdn.umbraco.io/media/b6f11172-373f-4473-af0f-0b0e5aefd21c"
        }
    },
    "mediaTypeAlias": "Image",
    "name": "Umbraco Campari Meeting Room",
    "parentId": "b6f11172-373f-4473-af0f-0b0e5aefd21c",
    "sortOrder": 0,
    "umbracoFile": {
        "src": "/media/662af6ca411a4c93a6c722c4845698e7/00000006000000000000000000000000/16403439029_f500be349b_o.jpg",
        "focalPoint": null,
        "crops": null
    },
    "umbracoWidth": 1600,
    "umbracoHeight": 1067,
    "umbracoBytes": 759116,
    "umbracoExtension": "jpg"
}

Get children

Get children of a single media.

URL: /media/{id}/children

Method: GET

Query Strings

?page={integer=1}
?pageSize={integer=10}

Success Response

Code: 200

Content Example:

{
    "_totalItems": 1,
    "_totalPages": 1,
    "_page": 1,
    "_pageSize": 10,
    "_links": {
        "self": {
            "href": "https://cdn.umbraco.io/media/b6f11172-373f-4473-af0f-0b0e5aefd21c/children?page=1"
        },
        "page": {
            "href": "https://cdn.umbraco.io/media/{id}/children{?page,pageSize}",
            "templated": true
        },
        "root": {
            "href": "https://cdn.umbraco.io/media"
        },
        "media": {
            "href": "https://cdn.umbraco.io/media/662af6ca-411a-4c93-a6c7-22c4845698e7"
        }
    },
    "_embedded": {
        "media": [
            {
                "_creatorName": "Rasmus",
                "_url": "https://media.umbraco.io/my-headless-site/media/662af6ca411a4c93a6c722c4845698e7/00000006000000000000000000000000/16403439029_f500be349b_o.jpg",
                "_writerName": "Rasmus",
                "_contentTypeAlias": "Image",
                "_createDate": "2019-06-17T13:46:42.203Z",
                "_updateDate": "2019-06-17T13:46:42.203Z",
                "_hasChildren": false,
                "_id": "662af6ca-411a-4c93-a6c7-22c4845698e7",
                "_level": 2,
                "_name": "Umbraco Campari Meeting Room",
                "_parentId": "b6f11172-373f-4473-af0f-0b0e5aefd21c",
                "_sortOrder": 0,
                "_links": {
                    "self": {
                        "href": "https://cdn.umbraco.io/media/662af6ca-411a-4c93-a6c7-22c4845698e7"
                    },
                    "root": {
                        "href": "https://cdn.umbraco.io/media"
                    },
                    "children": {
                        "href": "https://cdn.umbraco.io/media/662af6ca-411a-4c93-a6c7-22c4845698e7/children"
                    }
                },
                "umbracoFile": {
                    "src": "/media/662af6ca411a4c93a6c722c4845698e7/00000006000000000000000000000000/16403439029_f500be349b_o.jpg",
                    "focalPoint": null,
                    "crops": null
                },
                "umbracoWidth": 1600,
                "umbracoHeight": 1067,
                "umbracoBytes": 759116,
                "umbracoExtension": "jpg"
            }
        ]
    }
}

April 2025

The following changes have been released to all Heartcore sites.

Umbraco Workflow now available on Heartcore

Umbraco Workflow is now included as part of the offering on Umbraco Heartcore.

This integration gives Heartcore users powerful content approval and publishing workflows right out of the box. It makes it even easier to manage content governance in headless SaaS projects.

What's Included?

The free version of Umbraco Workflow is now automatically available for all Heartcore projects, allowing for structured review and publishing processes. If you have more advanced needs, a licensed version of Umbraco Workflow is also available. This version includes additional features and customization options, which can be obtained by contacting the Sales Team.

September 2024

The following changes have been released to all Heartcore sites.

New Redirect Endpoint

For a long time, the only way to get redirect information from Heartcore was a single endpoint on the Delivery API. This endpoint returned paginated redirect information for all content items in the tree. If you needed to find the canonical URL for a given path, then this endpoint was your only option. You would need to find your path in the returned items - especially challenging if it was not on the first page of results!

Languages

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Api-Version: 2
Umb-Project-Alias: {project-alias}

Authentication

Authentication is required for this API. You must supply a Bearer Token via an Authorization header or an API Key via an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

Status Code
Error Code
Message

400

BadRequest

Body cannot be empty.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Language with id '{id}' could not be found.

409

LanguageForCultureAlreadyExist

The language '{isoCode}' already exists.

422

ValidationFailed

Validation error occured when trying to save or update the language.

500

InternalServerError

Internal server error.

JSON example:

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}

Get languages

Gets all languages available for content creation.

URL: /language

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/language"
        },
        "languages": [
            {
                "href": "https://api.umbraco.io/language/en-US"
            },
            {
                "href": "https://api.umbraco.io/language/da-DK"
            }
        ]
    },
    "_embedded": {
        "languages": [
            {
                "isoCode": "en-US",
                "cultureName": "English (United States)",
                "isDefault": true,
                "isMandatory": false,
                "_createDate": "0001-01-01T00:00:00Z",
                "_id": "2a8adac1-c405-4de8-997b-cacc68f75dd2",
                "_updateDate": "0001-01-01T00:00:00Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/language/en-US"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/language"
                    }
                }
            },
            {
                "isoCode": "da-DK",
                "cultureName": "Danish",
                "isDefault": false,
                "isMandatory": false,
                "_createDate": "0001-01-01T00:00:00Z",
                "_id": "afe0b0d0-7bb9-4b1b-b4f3-3c2b5d14c4cc",
                "_updateDate": "0001-01-01T00:00:00Z",
                "_links": {
                    "self": {
                        "href": "https://api.umbraco.io/language/da-DK"
                    },
                    "root": {
                        "href": "https://api.umbraco.io/language"
                    }
                }
            }
        ]
    }
}

Get by ISO code

Get a specific langauge by its ISO code.

URL: /language/{id}

Method: GET

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

{
    "isoCode": "en-US",
    "cultureName": "English (United States)",
    "isDefault": true,
    "isMandatory": false,
    "_createDate": "0001-01-01T00:00:00Z",
    "_id": "d29bb164-7afb-471f-b49f-81c91200b56c",
    "_updateDate": "0001-01-01T00:00:00Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/language/en-US"
        },
        "root": {
            "href": "https://api.umbraco.io/language"
        }
    }
}

Create language

Create a new language for use on content.

URL: /language

Method: POST

Permissions required : Access to Settings section of the Umbraco Backoffice

Request

{
    "isoCode": "da-DK",
    "cultureName": "Danish",
    "isDefault": false,
    "isMandatory": false
}

Success Response

Code: 201

Content Example:

{
    "isoCode": "da-DK",
    "cultureName": "Danish",
    "isDefault": false,
    "isMandatory": false,
    "_createDate": "2019-10-10T11:39:57.270409Z",
    "_id": "4cb6b2c5-0de4-42c9-bcfc-a86f58eb8763",
    "_updateDate": "2019-10-10T11:39:57.270409Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/language/da-DK"
        },
        "root": {
            "href": "https://api.umbraco.io/language"
        }
    }
}

Update language

Updates an existing language.

URL: /language/{id}

Method: PUT

Permissions required : Access to Settings section of the Umbraco Backoffice

Request

{
    "isoCode": "da-DK",
    "cultureName": "Danish",
    "isDefault": false,
    "isMandatory": true
}

Success Response

Code: 200

Content Example:

{
    "isoCode": "da-DK",
    "cultureName": "Danish",
    "isDefault": false,
    "isMandatory": true,
    "_createDate": "2019-10-10T11:39:57.270409Z",
    "_id": "4cb6b2c5-0de4-42c9-bcfc-a86f58eb8763",
    "_updateDate": "2019-10-10T11:39:57.270409Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/language/da-DK"
        },
        "root": {
            "href": "https://api.umbraco.io/language"
        }
    }
}

Delete language

Deletes an existing language.

Deleting a language that is in use will result in setting the content based on this language to invariant.

URL: /language/{id}

Method: DELETE

Permissions required : Access to Settings section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

DELETE https://api.umbraco.io/language/da-DK

{
    "isoCode": "da-DK",
    "cultureName": "Danish",
    "isDefault": false,
    "isMandatory": false,
    "_createDate": "0001-01-01T00:00:00Z",
    "_id": "afe0b0d0-7bb9-4b1b-b4f3-3c2b5d14c4cc",
    "_updateDate": "0001-01-01T00:00:00Z",
    "_deleteDate": "2019-10-10T11:43:16.0824903Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/language/da-DK"
        },
        "root": {
            "href": "https://api.umbraco.io/language"
        }
    }
}

Members

BASE URL: https://api.umbraco.io

Table of Contents

Common Headers

Authentication

Authentication is required for this API. You must supply a Bearer Token via an Authorization header or an API Key through an Authorization or Api-Key header.

Errors

If an error occours you will receive a HTTP status code along with an API error code and an error message in the response body.

JSON example:

Get by username

Get a specific member by their username.

URL: /member/{username}

Method: GET

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Create member

Create a new member.

To set a password when creating a member a password field must be included in the posted data. If the password field is omitted no password will be set.

URL: /member/

Method: POST

Permissions required : Access to Member section of the Umbraco Backoffice

Request

Success Response

Code: 201

Content Example:

Update member

Update an existing member.

A member can be unlocked by setting isLockedOut to false in the request. Note that a member cannot be locked by setting the value to true; it will be ignored if the user is not already locked out.

URL: /member/{username}

Method: PUT

Permissions required : Access to Member section of the Umbraco Backoffice

Request

Success Response

Code: 200

Content Example:

Delete member

Delete an existing member by their username.

URL: /member/{username}

Method: DELETE

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Change member password

Change a members password.

URL: /member/{username}/password

Method: POST

Permissions required : Access to Member section of the Umbraco Backoffice

Request

Success Response

Code: 200

Content Example:

Get a reset member password token

Get a reset password token.

URL: /member/{username}/password/reset-token

Method: GET

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Content Example:

Reset member password

Reset a members password.

URL: /member/{username}/password/reset

Method: POST

Permissions required : Access to Member section of the Umbraco Backoffice

Request

Success Response

Code: 200

Content Example:

Add member to member group

Add an existing member to an existing member group.

URL: /member/{username}/groups/{groupName}

Method: PUT

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

Remove member from member group

Remove a specific member from a specific member group.

URL: /member/{username}/groups/{groupName}

Method: DELETE

Permissions required : Access to Member section of the Umbraco Backoffice

Success Response

Code: 200

This sample guide will cover how you can access and work with the from the client library.

Learn how to .

The ApiKey can be left blank when using the demo-headless sample project. If you are testing with your project and have chosen to protect the content exposed via the Content Delivery API, you will need an API Key. It is an option that has to be actively turned on via the Umbraco Backoffice in the Headless tree in the Settings section. Read more about this feature in the .

To connect to your project, you need to change the ProjectAlias value in the application.json file as demonstrated in .

Follow steps 2-3 from the section.

With the grid property editor , it has been decided to hide related functionality in the backoffice for sites that are not using it yet. The modern alternative to Grid Editor is the Block Grid Editor. The migration between Grid and Block Grid won't be fully automated, so this decision was made to encourage use of the most future-proof Data Type.

The Content Management API now exposes additional configuration data about properties via the endpoints. This will allow you to do things like retrieve information about possible prevalues for a dropdown field or radio button list, for example.

The grid editor Data Type in Heartcore is deprecated and will be retired in June 2025 or thereafter. For more information read the following .

In this tutorial, we will create a Custom Grid Editor using and . We will look at how we can define what the API response for our data should look like.

A couple of are defined. One for storing a reference to the textarea field and one for the HTML template.

For this tutorial we will create an image gallery editor using . Lit builds on top of the Web Components standards and helps us avoid a lot of boilerplate code.

We define the styles in a static field called styles. This will make Lit automatically inject a stylesheet into our custom element. The text returned needs to use the css tag from Lit. For more info see the .

The render method returns the HTML we want to show. It needs to be tagged with html. For more info see the .

This imports the mediaPicker function from the library.

Here we have defined an alias @headless-backoffice-bridge pointing to a Content Delivery Network (CDN) URL of the .

Open the

Notice our value stored is returned as a string. This makes it hard to consume, since we will need to parse it as JSON everywhere we use that value. This is where comes in handy.

For the rest of this tutorial the GraphQL queries are written in plain text that can be executed with the .

Since the heroImage is a Media picker we can pass arguments to the url field telling the server to generate an url with the query string parameters.

In the future, Heartcore may change to hard enforcement of rate limits. In this eventuality, APIs will return an response with a Retry-After header when receiving a request above the limit.

Once your structure has been deployed, it will be possible to transfer your content and media as well. This is done from the Umbraco Backoffice - read more about this in the .

Learn more about and explore the comprehensive to unlock its full potential.

In order to save you the trouble, a brand new endpoint has been added to the Delivery API. It allows you to fetch the canonical URL (and any other redirects) for a given path. For more information, check out the .

The number of languages that can be created is determined by the .

Status Code
Error Code
Message
Content Management API
Create content programmatically
.NET 6.0
Backoffice users and API Keys article
Overview of ASP.NET Core MVC
Tutorial: Get started with ASP.NET Core MVC
API Documentation for Umbraco Heartcore
Create an Umbraco Heartcore project
becoming deprecated
content type
blog post
custom elements
Lit
private fields
Lit
Lit styles documentation
Lit templates documentation
backoffice bridge
backoffice bridge library
API Browser
JSON schemas
Custom Grid Editors
GraphQL Playground
Structure deployment
Content transfer/restore
HTTP 429
Content transfer/restore article
Umbraco Workflow
Documentation
pricing tier
Run the sample on your local machine
Define a view file
Create a Document Type and Grid configuration
A look at a default grid editor
Create a custom grid editor
Using module aliases
Describing the grid editor using JSON schema
Image Cropper
Common Headers
Errors
Get Root Media
Get By Id
Get Children
updated Redirect article
Common Headers
Authentication
Errors
Get languages
Get by ISO code
Create language
Update language
Delete language
Api-Version: 2
Umb-Project-Alias: {project-alias}

400

BadRequest

Body cannot be empty.

400

CouldNotUnlockUser

Could not unlock the user.

401

Unauthorized

Authorization has been denied for this request.

403

Forbidden

You are not authorized to access the given resource.

404

NotFound

Member with username '{username}' could not be found.

422

ValidationFailed

Validation error occured when trying to save or update the member.

500

InternalServerError

Internal server error.

{
  "error": {
    "code": "Unauthorized",
    "message": "Authorization has been denied for this request."
  }
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [
        "Club Blue Members"
    ],
    "_lastLoginDate": "2019-10-10T12:04:24Z",
    "_lastPasswordChangeDate": "2019-10-10T12:04:24Z",
    "_createDate": "2019-10-10T12:04:24.203Z",
    "_id": "153c22ad-2940-4d1c-9253-f62a2a873915",
    "_updateDate": "2019-10-10T12:04:24.487Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/john%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "First Club Blue Member",
    "email": "john@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "john@example.com",
    "name": "John Doe"
}
{
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane Doe"
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [],
    "_createDate": "2019-10-10T12:18:06.6087436Z",
    "_id": "fbabbae4-738d-406a-a7b6-e6684a622882",
    "_updateDate": "2019-10-10T12:18:06.6087436Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/john%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane Doe"
}
{
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane A. Doe"
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [],
    "_createDate": "2019-10-10T12:19:57.053Z",
    "_id": "59c97163-0ece-4b92-893a-d3da4af2c888",
    "_updateDate": "2019-10-10T12:20:30.1886381Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/jane%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane A. Doe"
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [],
    "_lastLoginDate": "2019-10-10T12:04:24Z",
    "_lastPasswordChangeDate": "2019-10-10T12:04:24Z",
    "_createDate": "2019-10-10T12:04:24.203Z",
    "_id": "153c22ad-2940-4d1c-9253-f62a2a873915",
    "_updateDate": "2019-10-10T12:04:24.487Z",
    "_deleteDate": "2019-10-10T12:16:41.2371252Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/john%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "First Club Blue Member",
    "email": "john@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "john@example.com",
    "name": "John Doe"
}
{
    "currentPassword": "<current password>",
    "newPassword": "<new password>"
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [],
    "_createDate": "2019-10-10T12:19:57.053Z",
    "_id": "59c97163-0ece-4b92-893a-d3da4af2c888",
    "_updateDate": "2019-10-10T12:20:30.1886381Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/jane%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane A. Doe"
}
{
    "token": "ydAcKSmv+zAdPqFeYPuBAGojmFvJeiI2B6K79x0eOGX5EMevdu/vs16eq5sZ85crk2V+/7JmxN6s/5MJFvNg2K9Iex3cFmNlI8uTmvw2HuQzCr3Zo9KyKh19Gy4iTfzx+Q3Q0z1TCuSdBxjpiI6nuQ==",
    "expires_in": 86399,
    "_links": {
        "self": {
            "href": "/api/member/jane%40example.com/password/reset-token"
        },
        "member": {
            "href": "/api/member/jane%40example.com"
        }
    },
    "_embedded": {
        "member": {
            "_failedPasswordAttempts": 0,
            "_groups": [],
        "_createDate": "2019-10-10T12:19:57.053Z",
        "_id": "59c97163-0ece-4b92-893a-d3da4af2c888",
        "_updateDate": "2019-10-10T12:20:30.1886381Z",
        "_links": {
            "self": {
                "href": "https://api.umbraco.io/member/jane%40example.com"
            },
            "membertype": {
                "href": "https://api.umbraco.io/member/type/Member"
            }
        },
        "comments": "A Valued Club Blue Member",
        "email": "jane@example.com",
        "isApproved": true,
        "isLockedOut": false,
        "memberTypeAlias": "Member",
        "username": "jane@example.com",
        "name": "Jane A. Doe"
    }
}
{
    "token": "ydAcKSmv+zAdPqFeYPuBAGojmFvJeiI2B6K79x0eOGX5EMevdu/vs16eq5sZ85crk2V+/7JmxN6s/5MJFvNg2K9Iex3cFmNlI8uTmvw2HuQzCr3Zo9KyKh19Gy4iTfzx+Q3Q0z1TCuSdBxjpiI6nuQ==",
    "newPassword": "<new password>"
}
{
    "_failedPasswordAttempts": 0,
    "_groups": [],
    "_createDate": "2019-10-10T12:18:06.6087436Z",
    "_id": "fbabbae4-738d-406a-a7b6-e6684a622882",
    "_updateDate": "2019-10-10T12:18:06.6087436Z",
    "_links": {
        "self": {
            "href": "https://api.umbraco.io/member/john%40example.com"
        },
        "membertype": {
            "href": "https://api.umbraco.io/member/type/Member"
        }
    },
    "comments": "A Valued Club Blue Member",
    "email": "jane@example.com",
    "isApproved": true,
    "isLockedOut": false,
    "memberTypeAlias": "Member",
    "username": "jane@example.com",
    "name": "Jane Doe"
}
Common Headers
Authentication
Errors
Get by username
Create Member
Update Member
Delete Member
Change Member Password
Get a reset member password token
Reset member password
Add member to member group
Remove member from member group

.NET Client library

In this article you can learn more about the .NET client library that you can clone and use with your Umbraco Heartcore projects.

It is a library for .NET Core and is based on .NET Standard 2.0. This means that it can be used on the most .NET frameworks, for example UWP, Xamarin.Android, Xamarin.Mac and Desktop .NET 4.6.1.

Download and install

You can also install it through NuGet:

Please be aware that the minimum NuGet client version requirement has been updated to 2.12. This change is made to support multiple .NET Standard targets in the NuGet package.

You will receive a Visual Studio solution file that references the client library (Umbraco.Headless.Client.Net). Additionally, there is a test project (Umbraco.Headless.Client.Net.Tests) utilizing xUnit for unit and integration tests.

Along with the client library you will also find two samples based on the library. We have built an MVC sample and a console sample.

Test your Umbraco Heartcore project against a small MVC site. You can choose to use our sample project and content, or connect to your own project and build your own views and controllers.

Get to know the content management service and how to use it to manage content and media programmatically.

Node.js Client library

Learn how to fetch content and media from your Umbraco Heartcore project using Node.js and the Umbraco.Headless.Client.NodeJs Library.

Prerequisites

  • Access to an Umbraco Heartcore project.

  • Basic familiarity with terminal commands and Node.js.

Step 1: Create Content and Media in Your Heartcore Project

  1. Log into your Heartcore project on the Umbraco Cloud Portal.

  2. Navigate to the Content section.

  3. Create a new content item, such as a "Home Page." Fill in the necessary fields and publish it.

  4. Go to the Media section.

  5. Upload an image.

  6. Note the content’s URL and media ID for fetching via the Node.js client.

Step 2: Initialize a Node.js Project

  1. Open a terminal or command prompt.

  2. Navigate to the directory where you want your project to reside.

  3. Run the following command to create a package.json file:

Step 3: Install the Client Library

There are two ways to install the Umbraco Headless Client Library:

  • Run the following command in your terminal:

Step 4: Write the code to Fetch Content and Media

  1. Create a new file called app.js using a text editor (such as Notepad++ or Visual Studio Code) in your project directory.

  2. Open the app.js file.

  3. Use the following code template:

Step 5: Run the Script

  1. Open a terminal.

  2. Navigate to your project folder.

  3. Run the following command:

Exploring API Methods

The Node.js library provides a variety of methods to fetch and manage data from your Umbraco Heartcore project. These methods allow you to interact with both the Content Delivery API and the Content Management API, depending on your requirements.

Content Delivery API

To fetch content or media, use the following convention:

In the above examples:

  • Use root() to fetch all content or media from the root level.

  • Use children() or ancestors() to navigate the hierarchy and retrieve related content or media items. You can also fetch specific items directly by their ID or URL.

Content Management API

To manage content, media, and other types, use the following convention:

In the above examples:

  • Use create() to add new content.

  • Use all() to fetch all available content types.

References

Filtering and Ordering

Documentation for GraphQL filtering in Umbraco Heartcore.

The GraphQL API allows for filtering and ordering root and traversion collections (ancestors, children and descendants).

Using filters

To start filtering the content, an where argument can be passed to the collection query. E.g. to find all products where it's price is higher than 100 we can write the following query.

Filters can be combined with AND and OR, e.g. if we want to find all content on level 2 or 3 that is updated after 2020-03-13 we write the following query.

Or if we want to get all of type person which names does not start with t we can write the following query.

We can combine AND, OR and NOT in a single query e.g. if we wan't to get all content on level 1 or 2 that does not start with b or j we can write the following query.

Filtering can also be applied to types returning Content and Media, e.g. if we want all content of type Post where the author name is Rasmus, we can write the following query.

Previewing

The collection can also return draft content by passing the preview argument with a boolean to the query. Draft content is always protected and requires an Api-Key.

Lets say we want to show all our products that haven't been published, we can write the following query.

Ordering

The collection can also be sorted by passing the orderBy argument to the query.

If orderBy is not specified the collections are ordered by path which is the order they appear in, in the Umbraco Backoffice tree.

Lets say we want to show all our products ordered by price in ascending order, we can write the following query.

We can even add multiple values to the orderBy argument to order by multiple fields. E.g. if we want to order products by price and then by name, we write the following query.

Paging

We can also limit the number of results returned by paging. To achieve this one can use first and after to do forward paging and last and before to do backward paging.

The cursor can be obtained by including the cursor field on an edge e.g. to get the first 50 products we can write the following query.

We can then use the cursor from the last item to get items that appear after that one. We can also request the PageInfo object which holds information on the start and end cursors and if there are more pages.

first can only be used in combination withafter, and last can only used with before.

Also hasNextPage is only populated when doing forward paging andasPreviousPage is populated when doing backward paging.

Combining filter, order, and paging

Everything shown up until now can be combined in a single query, the following query will get the first 50 products where the price is greater than 100 and order the result in ascending order by price and then by name.

The .NET library can be found on GitHub: .

This article showcases how to fetch content and media from your Umbraco Heartcore project using the official Node.js Client Library. If you are not familiar with Node.js you can take a look at the official .

(version 10 or above) installed on your machine. You can verify the version by running node -v in your terminal.

An API key generated from your Heartcore project. For more information, see the article.

Clone or download the client library from GitHub, or

For a full list of available methods, visit the .

For a full list of available methods, visit the .

For information on the different filters available and how the filter and order types are generated see .

> Install-Package Umbraco.Headless.Client.Net
npm init -y
npm install @umbraco/headless-client
 //Importing the Client Library
const { Client } = require('@umbraco/headless-client')

//Connecting to the Heartcore project on Cloud
const client = new Client({ 
    projectAlias: 'your-project-alias',
    apiKey: 'your-api-key'
})

//Create an async function to fetch content and media
async function run() {
    try {
        //Fetch all content from the root
        const contentResult = await client.delivery.content.root()

        //Fetch a media item by its ID
        const mediaResult = await client.delivery.media.byId('your-media-id')

        //Log results
        console.log('Content:', JSON.stringify(contentResult, null, 2))

        console.log('Media:', JSON.stringify(mediaResult, null, 2))

    } catch (error) {
        console.error('Error fetching data:', error.response ? error.response.data : error.message)
    }
}

run()
node app.js
client.delivery.content.root();

client.delivery.media.root();

client.delivery.content.ancestors(contentId);

client.delivery.content.children(parentId);

client.delivery.content.byId(contentId);
client.management.content.create()

client.management.contentType.all()
query {
  allProduct(
    where: {
      price_gte: 100
    }
  ) {
    edges {
      node {
        name
        price
      }
    }
  }
}
query {
  allContent(
    where: {
      AND: [
        { level_any: [2, 3] }
        { updateDate_gt: "2020-09-13" }
      ]
    }
  ) {
    edges {
      node {
        name
      }
    }
  }
}
query {
  allContent(
    where: {
      NOT: [
        { name_starts_with: "t" }
      ]
    }
  ) {
    edges {
      node {
        name
      }
    }
  }
}
query {
  allContent(
    where: {
      AND: [
        { level_any: [1, 2] }
        {
          NOT: [
            {
              OR: [
                { name_starts_with: "b" }
                { name_starts_with: "j" }
              ]
            }
          ]
        }
      ]
    }
  ) {
    edges {
      node {
        name
      }
    }
  }
}
query {
  allPosts(where: { author: { name: "Rasmus" } }) {
    edges {
      node {
        name
        url
      }
    }
  }
}
query {
  allProduct(
    preview: true
  ) {
    edges {
      node {
        name
      }
    }
  }
}
query {
  allProduct(
    orderBy: price_ASC
  ) {
    edges {
      node {
        name
      }
    }
  }
}
query {
  allProduct(
    orderBy: [ price_ASC, name_ASC ]
  ) {
    edges {
      node {
        name
        price
      }
    }
  }
}
query {
  allProduct(
    first: 50
  ) {
    edges {
      cursor
      node {
        name
        price
      }
    }
  }
}
query {
  allProduct(
    first: 50
  ) {
    edges {
      cursor
      node {
        name
        price
      }
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}
query {
  allProduct(
    first: 50
    where: {
      price_gte: 100
    }
    orderBy: [price_ASC, name_ASC]
  ) {
    edges {
      cursor
      node {
        name
        price
      }
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}
.NET client library for Umbraco Heartcore
MVC sample
Content Management sample
Node.js Documentation
Node.js
Backoffice Users and API Keys
Umbraco.Headless.Client.NodeJs
Content Delivery API sample repository on GitHub
Content Management API sample repository on GitHub
Node.js Documentation
Umbraco Heartcore API Documentation
Create an Umbraco Heartcore project
Schema Generation

February 2024

The following changes have been released to all Heartcore sites.

Block Grid Editor

The Block Grid Editor from core Umbraco is now available in Heartcore. A modern alternative to the Grid Editor, this type is particularly useful for allowing content authors to build page-like structures.

Unlike the core CMS, Heartcore does not yet support custom stylesheets or views to control block appearance in the backoffice. This is on the roadmap and support will be added later in the year.

Backoffice Performance

A lot of work has been put into increasing the performance of the backoffice in this release. Content authors can expect to see a speed improvement across the board to most backoffice operations.

Broken Link Warnings

Previously, deleting a content or media item that was linked to from another item may have resulted in broken links. Now, content authors will be warned when attempting to delete an item which other items are dependent upon. They are also informed which items linked to the deleted one, so that they can change those items if desired.

Rich Text Enhancements

TinyMCE, the library underpinning the Rich Text Editor (RTE) in Heartcore has been upgraded. This includes a slew of bug fixes and a slick new appearance, but has also allowed us to include some frequently-requested enhancements. Both of these must be enabled in the Data Type before being available to content authors.

  • Text color - You may now select foreground and background colors for text.

  • Language selection - You may now choose a language for selected text from a dropdown menu. This will apply a lang attribute to the underlying markup. Browsers and screen readers that parse the markup will then be able to make smarter decisions about how to present that content to end-users.

Notable Bug Fixes

In this release we have upgraded a lot of the technologies upon which Heartcore depends, including the core CMS. This means there is huge number of fixes to defective behaviors that we cannot hope to cover entirely here.

Instead, here is a brief list of fixes to some of the most highly-reported issues:

  • Transferring content between environments should no longer fail if the content contains a URL picker that references another content item.

  • In a content item with list view enabled, ordering children by the "Is Published" column should correctly sort items.

  • The preview button should now correctly display for all content items that vary by culture.

  • Language content management endpoints should now return a 400 Bad Request or 415 Unsupported Media type, instead of a generic 500 error.

  • Sorting on an optional DateTime field using GraphQL should now return results after the first page.

See the for more information about how to get started with the Block Grid.

core CMS documentation
Configuring a block grid editor
Language selection in the rich text editor
Cover

Getting started

Get started working with Umbraco Heartcore

Cover

Umbraco Heartcore APIs

See the different APIs available in Umbraco Heartcore

Cover

Client libraries

Test out your Umbraco Heartcore project with the pre-made client libraries

User Page in the Backoffice
Protect API
Creating the API Key
The created API Key
List of all APIs
Add new environment on Heartcore project.
Add new environment on Heartcore project.
Where to find GraphQL
Documentation and schema pane in the Playground
Sample query in the Playground
Sample query with variables in the Playground
Shows where the history button is
Schema Tab in the Playground
Persisted queries tab
Create persisted query
Update persisted query
Delete persisted query
Empty Preview Urls Overview
Add Preview Urls
Preview Urls Overview
Preview Content
Login Screen
Sections of the backoffice
Section tree
Getting Started
Overview of the content
Overview of the Content info
Overview of the Media section
Headless Dashboard
Manage your created webhooks
Queue for transfer and restore
API Browser user interface
Settings: Document Types
Blank Home Page Document Type
More properties added to Document Type
Document Type Collection
Document Types in the tree
Creating our first content node
Welcome to Umbraco Heartcore Content node
Blog area - Grid view
API Browser - Content
Screenshot showing the Settings section with the Grid Editors tree expanded
Screenshot showing the Module Aliases configuration
Headless settings section
Portal Project Overview
Project Overview
Project Overview.
Add environment.
Add environment.
Invite Team Member Modal.
Invite Team Member Modal.
Project Menu Overview.
Project Menu Overview.
Edit team.
Edit team.
Usage page on Heartcore project.
Usage page on Heartcore project.
Rename Project.
Rename Project.
Content structure
Adding a property with the Grid layout editor
The Grid Page Document Type with the Grid Content property
The Grid Page Document Type with the Grid Content property
A content node based on the Grid Page Document Type
List of available Grid Editors
The grid editor developer view for the Headline editor
The final image gallery grid editor
A custom grid editor for creating an image gallery
The developer view showing the above code and a preview
The first version of the Image Gallery grid editor
Select media overlay shown when clicking the Add image button
Defining custom module aliases
Response from the API with the grid content property encoded as a string
Response from the API with the grid content property returned as an array
Final response from the API
Text and Image Document Type
Unique Selling Point Document Type
Elements Composition Document Type
Nested Content Configured with Elements
Elements Composition Reorder
Hero Composition Document Type
Unique Selling Points Composition Document Type
Nested Content Configured with Unique Selling Points
Unique Selling Points Composition Reorder
Textpage Document Type
Textpage Compositions
Frontpage Document Type
Frontpage Compositions
Frontpage Permissions
Left-to-right deployment model
Deploy to Live

August 2024

The following changes have been released to all Heartcore sites.

Webhook Enhancements

With the core CMS adding webhook support, the same functionality has been adapted into Heartcore to use the same user interface. You will now get the same consistent editing experience in both Umbraco CMS and Umbraco Heartcore, and it also comes with new features.

  • You may now select multiple event types (for example, publish / unpublish) or content types for a webhook. No more needing to create dozens of hooks to achieve what can now be done with only one.

  • You may now specify custom HTTP headers to send to your endpoint whenever the webhook fires.

Aside from the interface, all other aspects of webhooks in Heartcore are unchanged. Webhooks are still fired from the delivery platform with the same IP address range, retry policy, and payload that you are used to.

Improved Firewall

A recent roll-out has added additional firewall rules for all Heartcore services. While efforts have been made to tune these, there is always a small possibility of false positives. If you believe your legitimate traffic is affected, please raise a support ticket through the portal.

Creating content with media

In this tutorial, you will learn how to create content with media using the Management API.

The example will be using the Media Picker V3 property editor.

Determining the request body

Determining the right request body for creating content through the Management API can be a bit tricky. One way to figure out the correct request body is to:

  1. Create the content in the backoffice

  2. Use the Management API Browser to get the properties for the content created.

You can then use the properties as a template for your request body when creating content through the Management API.

The following tutorial shows you the detailed process for determining the request body while creating content with a Media Picker V3 property.

To follow this guide using the Media Picker (legacy) property you need to replace the Media Picker V3 property. You need to do this when creating the Document Type and content nodes.

Create a new Document Type with a Media Picker V3 property

First, we must create a Document Type with a Media Picker V3 property. This will allow us to create content with the Media Picker V3 property.

To create a new Document Type with a Media Picker V3 property, follow these steps:

  1. Go to the settings section in the backoffice and click the Document Types Create... option, and then select the option to create a new Document Type in the sub-menu.

  2. Fill in the name of the Document Type, create a new group and add a new property of the Media Picker V3 type.

  3. Go to the Permissions page for the Document Type and enable 'Allow as root'.

  4. Save the Document Type.

Upload an image to the media section

Now we must upload an image to the media section. This will allow us to select the image in the Media Picker V3 property on the content node we will create later.

To upload an image to the media section, do one of the following:

  • Do it later when creating the content node and selecting the image for the Media Picker V3 property.

  • Go to the media section in the backoffice and drag-and-drop an image into the media section.

  • Go to the media section in the backoffice and upload the image through the File or Image option in the Create dropdown.

Create a new content node of the new Document Type

Next, we need to create a new content node of the new Document Type. This will allow us to query the content node using the Management API Browser.

To create a new content node of the new Document Type, follow these steps:

  1. Go to the content section in the backoffice, click the three dots on the right side of the content sidebar, and select the Document Type we created earlier.

  2. Fill in the name of the content node and select a fitting image for the Media Picker V3 property.

    • If you have not uploaded an image to the media section yet, you can do it when selecting the image for the Media Picker V3 property.

  3. Save and Publish the content node.

Getting your API key for using the Management API

To use the Management API, you need an API key. You can get your API key by following these steps:

  1. Go to the Users section in the backoffice and click the API Keys tab in the editor window.

  2. Click show on the API key you want to use.

Getting the content node ID

To query content using the Management API, you need the ID of the content node. You can get the ID of the content node by following these steps:

  1. Go to the content section in the backoffice.

  2. Click the content node you want to query.

  3. Click the Info tab in the editor window.

  4. Copy the ID from the General section in the editor window.

Query the content node using the Management API Browser

Now we can query the content node using the Management API Browser, the content node ID and our API Key. This will allow us to get the properties for the content node we created.

To query the content node using the Management API Browser, follow these steps:

  1. Go to the settings section in the backoffice, unfold the Headless section, select the API Browser menu item, and click the Content Management tab in the editor window.

  2. Write the request URL to query the newly created content, fill in the API Key as a Custom Request Header, and click the Go! button.

  3. Copy the properties from the response section in the editor window.

Clean up the properties and use it as a template for your request body

Finally, we need to clean up the properties, so it can be used as a template for our request body.

In this case, we can omit ID's and create/update dates as these are auto-generated at creation time:

{
//"_currentVersionState": {
//  "$invariant": "PUBLISHED"
//},
  "name": {
    "$invariant": "Star Wars Blog"
  },
//"_updateDate": {
//  "$invariant": "2023-02-08T13:26:16.6Z"
//},
//"_hasChildren": false,
//"_level": 1,
//"_createDate": "2023-02-08T13:21:35.27Z",
//"_id": "a6126eb4-c667-466c-ae7c-252a5b2e7be9",
  "contentTypeAlias": "blog",
//"sortOrder": 0,
  "image": {
    "$invariant": [{
      //"key": "394c9bfd-be7b-486d-968a-ce844aa76b5e",
        "mediaKey": "766c9c5b-f4eb-4a5c-b94e-06701eafcbab",
      //"crops": [],
      //"focalPoint": null
      }]
  }
}

Resulting in the following request body:

//You cannot use this request body as-is, as the mediaKey will differ.
{
  "name": {
    "$invariant": "Star Wars Blog"
  },
  "contentTypeAlias": "blog",
  "image": {
    "$invariant": [{
        "mediaKey": "766c9c5b-f4eb-4a5c-b94e-06701eafcbab",
      }]
  }
}

The media key is the ID of the image in the media section. As such it is the image reference to the image the Media Picker V3 property uses.

If you copy the JSON from the response section to another editor/application make sure the formatting is correct, and no extra characters are added. These characters can be hidden but will cause the request to fail.

Creating a Media Picker with the Management API

To create a new content node with a Media Picker, follow these steps:

  1. Go to the Management API Browser, fill in the API Key as a Custom Request Header, and click the Go! button.

  2. Now click the small orange exclamation mark button next to the content link in the Links section. This opens up a modal with the option to make non-GET requests.

  3. Next copy and paste your request body into the request body section in the modal.

  4. Click the Make Request button.

Now you have created a new content node with a Media Picker property editor that correctly references the image with the ID "766c9c5b-f4eb-4a5c-b94e-06701eafcbab".

Publishing a Media Picker with the Management API

After having created the content node it is time to publish it, so it can be viewed on the front-end.

To publish a content node with a Media Picker, follow these steps:

  1. Go to the Management API Browser, fill in the API Key as a Custom Request Header, Write the request URL for the content, and click the Go! button.

  2. Navigate to and click the small orange exclamation mark button next to the publish link in the Links section.

  3. Change the request type to PUT, and leave the request body empty as an empty object.

  4. Click the Make Request button.

And you are done! You are now able to upload a media item and create a new content node using the newly uploaded media item in a Media Picker v3 property.

You can use a similar approach for discovering the format of more complex content when you want to create it through the Content Management API.

For more information about webhook functionality, both new and old, check out the .

Creating a Document Type 1
Creating a Document Type 2
Creating a Document Type 3
Creating a Document Type 4
Creating media with drag and drop
Creating media with the File or Image option in the Create dropdown

Send a request (for example with the Management API) to upload an image from binary data. See the for more information on how to do this.

Creating a content node 1
Creating a content node 2

If you do not have an API key yet, you can create one under Users > Your User > API Keys > Create API Key. See the section for more information on how to do this.

Getting the content node ID
Navigating to the Management API Browser
Filling info into the Management API Browser
Copying the JSON properties

See the section for more info on the other properties.

Following the steps demonstrated in the , we can now create a new content node with a Media Picker using the Management API.

Opening the non-GET request modal
Making a non-GET request
Publishing a content node

If you want to create content with media programmatically, you can try out the the . The client library also supports the use of the Management API.

updated Webhooks article
Getting Started
Media Picker 3
.NET Client Library for Umbraco Heartcore
API Documentation
previous section