Create a content entity for a page

Last published: 2025-11-02

In this guide we will explore concepts around creating a content entity to represent this page. For more information on the general concepts around how entities and items work see the content model guide.

This guide uses a hands on approach to exploring using the Baack APIs to create the content for this actual page.

Concepts covered in this guide

  • Entity endpoint for creating our content entity to hold the page data.
    • Entity representation for the data associated with the entity.
    • Company representation of the owner of the entity.
    • Text Item used to create a text item title for the page we create.
      • Text Item representation for basic untranslated string representations for content.
    • Markdown item endpoint used to create a markdown item used for the body of the content.

Step 1: Create a content entity to hold the page content data

The first thing to understand is the content entity model. We will create an example and walk through the attributes to explore their use. Other than a little formatting for readability this requests below are presented verbatim.

curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:8080/n/v1/entity/ --data '{
  "name":"/2ad747ab-51a9-11f0-b99c-d8bbc160a611/content/doc/guides/create-content", 
  "owner":{"urn":"2ad747ab-51a9-11f0-b99c-d8bbc160a611"},
  "status":"PUBLISH",
  "language":"en-GB"}'
{
  "urn":"89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "url":"/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "owner":{
    "urn":"2ad747ab-51a9-11f0-b99c-d8bbc160a611",
    "url":"/n/v1/company/2ad747ab-51a9-11f0-b99c-d8bbc160a611"},
  "status":"DRAFT_UNPUBLISHED",
  "name":"/2ad747ab-51a9-11f0-b99c-d8bbc160a611/content/doc/guides/create-content",
  "language":"en-GB",
  "variant":"",
  "texts":[],
  "doubles":[],
  "dateTimes":[],
  "booleans":[],
  "images":[],
  "templates":[],
  "markdowns":[]
}

Let's walk through the request step by step:

  • This command is using standard CURL to demonstrate the low level native API V1 and the entity POST (CREATE) endpoint. The URL doesn't include any identifier information because the ID (Unique Resource Name) of the created entity will be allocated by the back end. The request is using a bearer token header which we use for server to server or secure environments. See the getting started guide for details of how to access your access token.
  • To create the entity we also provide the required fields:
    • The name of the entity, note we are creating a general content entity which will be accessible on the rendered content delivery endpoints so the name includes a prefix for your //content/. More on entity prefixes in the content guide.
    • The owner company which is the legal owner of the content and is used for accounting, access etc. We are just providing the urn but you could provide any valid company representation, other fields will be ignored. This makes it easy to pass around objects without having to be too concerned about constructing them by hand.
    • The status of the entity we are creating. See the entity representation for details of the life-cycle of an entity.
    • The language of the content on this page. Entities support the concept of different languages for entities to allow content creation for multiple languages. See the content guide for more details of how the language and other fields interact.

The response returned when the entity is created you may note includes quite a few other attributes. We will come back to these later.

Step 2: Create a text item (string) for the title of the page

Creating a text item (untranslated string) for the entity we just created follows much the same pattern as the entity creation in step 1. This time however the text item is parented off the entity rather than the owning company.


curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:8080/n/v1/textitem/ --data '{"name":"title", "entity":{"urn":"89135cc6-f0f2-4249-a315-bc1a8833bfd9"},"sortOrder": 0,"value":"Create content for a page"}'

{
  "urn": "eefd1b52-a9dc-4eb8-a9b1-587e34cdd016",
  "name": "title",
  "sortOrder": 0,
  "value": "Create content for a page",
  "entity": {
    "urn": "89135cc6-f0f2-4249-a315-bc1a8833bfd9",
    "url": "/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9"
  },
  "url": "/n/v1/textitem/eefd1b52-a9dc-4eb8-a9b1-587e34cdd016"
}

Again we are using a HTTP POST (CREATE) request to provide a representation of a new entity. This time we provide the entity, a name for the item, it's sortOrder and a value. The response has a few more fields including the Unique Resource Name (URN) allocated for this text item, it's URL for further operations and a reference to the entity it was created in.

Let's also create a markdown item we will use to compose the body of this message later.

Step 3: Create a markdown item for the body

As with creating a text item, creating a markdown has a very similar set of fields to a text item. The main difference is that the markdown string will be translated when rendered into HTML.

curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:8080/n/v1/markdownitem/ --data '{"name":"body", "entity":{"urn":"89135cc6-f0f2-4249-a315-bc1a8833bfd9"},"sortOrder": 0,"value":"placeholder"}'

{
  "urn": "925c798d-b1e4-4332-abaf-766a448f7bb5",
  "name": "body",
  "sortOrder": 0,
  "value": "placeholder",
  "entity": {
    "urn": "89135cc6-f0f2-4249-a315-bc1a8833bfd9",
    "url": "/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9"
  },
  "url": "/n/v1/markdownitem/925c798d-b1e4-4332-abaf-766a448f7bb5"
}

Again in the response there is a full representation of the markdown item and it's context.

Step 4: Publish our minimal content page

Content on the Baack platform supports a rich life-cycle model where new edits are initially introduced as drafts and updating the entity life-cycle. As we have added new content, this will put the entity into a draft or published with unpublished drafts mode depending on it's history.

Let's go ahead an publish the entity. Note that we will just send the whole representation we received earlier with only the status updated to 'PUBLISH'. Concepts with life-cycle stages like entity have both resting and verb states. Following the concept of Representation State Transfer (REST) the actions on the entity are handled with action verb states rather than a functional approach like a call to a URL like /entity/urn/publish. This concept is used throughout the Baack APIs.

curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:8080/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9 --data '{"urn":"89135cc6-f0f2-4249-a315-bc1a8833bfd9","url":"/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9","owner":{"urn":"2ad747ab-51a9-11f0-b99c-d8bbc160a611","url":"/n/v1/company/2ad747ab-51a9-11f0-b99c-d8bbc160a611"},"status":"PUBLISH","name":"/2ad747ab-51a9-11f0-b99c-d8bbc160a611/content/doc/guides/create-content","language":"en-GB","variant":"","texts":[],"doubles":[],"dateTimes":[],"booleans":[],"images":[],"templates":[],"markdowns":[]}'

{
  "urn": "89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "url": "/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "owner": {
    "urn": "2ad747ab-51a9-11f0-b99c-d8bbc160a611",
    "url": "/n/v1/company/2ad747ab-51a9-11f0-b99c-d8bbc160a611"
  },
  "status": "PUBLISHED",
  "name": "/2ad747ab-51a9-11f0-b99c-d8bbc160a611/content/doc/guides/create-content",
  "language": "en-GB",
  "variant": "",
  "publishTimestamp": "2025-09-18T08:56:12.687",
  "updatedTimestamp": "2025-09-18T08:56:12.687",
  "texts": [],
  "doubles": [],
  "dateTimes": [],
  "booleans": [],
  "images": [],
  "templates": [],
  "markdowns": []
}

That's it! Let's check out our rendered content:

curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9

{
  "urn": "89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "url": "/n/v1/entity/89135cc6-f0f2-4249-a315-bc1a8833bfd9",
  "owner": {
    "urn": "2ad747ab-51a9-11f0-b99c-d8bbc160a611",
    "url": "/n/v1/company/2ad747ab-51a9-11f0-b99c-d8bbc160a611"
  },
  "status": "PUBLISHED",
  "name": "/2ad747ab-51a9-11f0-b99c-d8bbc160a611/content/doc/guides/create-content",
  "language": "en-GB",
  "variant": "",
  "publishTimestamp": "2025-09-18T08:56:12.687",
  "updatedTimestamp": "2025-09-18T08:56:12.687",
  "texts": [
    {
      "urn": "5b6708b4-a953-45df-b60b-a01ef46ccf0a",
      "name": "title",
      "sortOrder": 0,
      "value": "Create a content entity for a page",
      "url": "/n/v1/textitem/5b6708b4-a953-45df-b60b-a01ef46ccf0a"
    }
  ],
  "doubles": [],
  "dateTimes": [],
  "booleans": [],
  "images": [],
  "templates": [],
  "markdowns": [
    {
      "urn": "925c798d-b1e4-4332-abaf-766a448f7bb5",
      "name": "body",
      "sortOrder": 0,
      "value": "placeholder",
      "url": "/n/v1/markdownitem/925c798d-b1e4-4332-abaf-766a448f7bb5"
    }
  ]
}

That's it, we now have a published page with multiple content types associated with it. The collection of content types associated with an entity is expanding quickly but it's easy to see how the content could be used for any manner of content representation.

**Note: this guide was produced on our Alpha build so the specific URLs and url fields in representations are subject to change.