Content
Last updated: July 3, 2026
A Content is a single piece of actual data stamped out from a Content Type (the template). Take a clothing store as an example: the Content Type "Product" defines the set of attributes such as product name, price, and description, while a single "Stainless Tumbler 500ml" is one Content that follows that template.
A Content is made up of two parts. fields holds the actual value of each field, and sys holds state such as publishing, version, and archiving. In CMA, a Content is a sub-resource of Space. Its read and delete paths are based on /spaces/{spaceId}/contents, while its create and update paths are based on /spaces/{spaceId}/content-types/{contentTypeId}/contents, which is under the Content Type. Management operations are performed on CMA, and the published snapshot is delivered through CDA.
Resource structure
The following is the single-read response for the published Content "Stainless Tumbler 500ml". Along with sys (system properties), it has fields (field values) and metadata (additional information such as tags).
{
"sys": {
"id": "3trmXRM3RqbgSnifyg7PBUM8Ds0Xvw",
"type": "Content",
"space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
"contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
"publish": {
"version": 1,
"at": "2026-06-18T09:51:44.128Z",
"firstAt": "2026-06-18T09:51:44.128Z",
"counter": 1,
"by": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } }
},
"createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"createdAt": "2026-06-18T09:51:14.597Z",
"updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"updatedAt": "2026-06-18T09:51:44.128Z",
"version": 2,
"status": "Published"
},
"fields": {
"price": { "en-US": 18000 },
"productName": { "en-US": "Stainless Tumbler 500ml", "ko-KR": "스테인리스 텀블러 500ml" }
},
"metadata": { "tags": [] }
}Key properties:
sys.id: The unique identifier of the Content. It goes into{contentId}in the single-read, update, delete, and publish paths.sys.contentType: AReferthat points to the Content Type this Content follows.fields: The value of each field. The key is the field'sapiName, and the value is a per-locale map. This is explained in Field keys are apiNames below.metadata.tags: The list of Tags attached to this Content. Each entry is in theRefer<Tag>shape, and it is an empty array[]if no tags are attached.
Field keys are apiNames
The keys of the fields object are each field's apiName. They are not the Content Type's internal id, nor the field name shown in the content studio (e.g. Product Name). So when you create or read a Content, you must use the apiName defined on the Content Type as the key.
The fields of the demo "Product" Content Type and their apiName mapping are as follows.
| Content studio name | apiName | type | localized | required |
|---|---|---|---|---|
| Product Name | productName | ShortText | true | true |
| Price | price | Long | false | false |
| Description | description | RichText | true | false |
| Photo | photo | Refer<Media> | false | false |
| Brand | brand | Refer | false | false |
Each field value is a per-locale map. The shape of the value depends on localized.
- A
localized: truefield can hold values for multiple locales in the form{ "<locale>": value }. Example:"productName": { "en-US": "Stainless Tumbler 500ml", "ko-KR": "스테인리스 텀블러 500ml" }. - A
localized: falsefield (a non-localized field) takes a value only under the single default Locale key of the Space. No other locale key is allowed. Since the demo Space's default Locale isen-US, the price has only the singleen-USkey, as in"price": { "en-US": 18000 }.
What the default Locale is, up to which locale a required field must be filled, and the fallback rules when a value is missing are covered in Localization (concept).
Value shapes by type
The shape of the value inside a locale key follows the field's type. Most types take the value of that type directly (text types take a string, Number and Long take numbers, Boolean takes true/false). The types that are easy to mix up, because their shape is an object or an array, are as follows.
Location: an object in the form{ "latitude": <number>, "longitude": <number> }.latituderanges from -90 to 90 andlongitudefrom -180 to 180, and both keys are required. Keys other than the defined ones are not accepted, so abbreviated keys such aslat,lng, orlonare rejected.Refer: the value is aReferobject pointing at the target. You do not put a bare id string; you put thesysobject as-is. When it points at another Content,targetTypeisContent; when it points at a Media, it isMedia. TheRefershape itself is defined in the Refer shape in System properties (sys).Array: a JSON array holding values of the element type. When the elements are text, it is an array of strings; when the elements areRefer(Content or Media), it is an array ofReferobjects. It is not an array of id strings.
The following is an example of the values that go inside fields (when the Space's default Locale is en-US).
{
"location": { "en-US": { "latitude": 37.5662, "longitude": 126.9910 } },
"tags": { "en-US": ["New", "Limited Edition"] },
"photo": { "en-US": { "sys": { "type": "Refer", "id": "3trmXRM3RqbgSnifyg7PUl8DzDgDzP", "targetType": "Media" } } },
"photos": { "en-US": [ { "sys": { "type": "Refer", "id": "3trmXRM3RqbgSnifyg7PUl8DzDgDzP", "targetType": "Media" } } ] }
}System properties (sys)
Every Content carries common system properties in the sys object. space, contentType, createdBy, and updatedBy are in the Refer shape ({ "sys": { "id", "type": "Refer", "targetType" } }).
| Property | Type | Description |
|---|---|---|
id | string | Unique resource identifier. |
type | string | Resource kind. For a Content this is always "Content". |
space | Refer<Space> | The Space this Content belongs to. |
contentType | Refer<ContentType> | The Content Type this Content follows. |
publish | object | The publish-state pointer. See the keys below. |
archive | object | Archive information. Present only while archived; otherwise the key is absent. See the keys below. |
createdBy | Refer<User> | The user who created it. |
createdAt | string (date-time) | Creation time. |
updatedBy | Refer<User> | The user who last updated it. |
updatedAt | string (date-time) | Last update time. |
version | integer (≥1) | Resource version. It increases by 1 with every change such as create, update, publish, unpublish, and archive. |
status | string (enum) | Publish status. One of the four below. |
status is one of the following four values.
status | Meaning |
|---|---|
Draft | Being authored and not yet published. |
Changed | Has been published before, but later changes are not yet published. |
Published | Published with no unpublished changes. |
Archived | Archived. |
The publish object is a pointer to the publish state. While published, it has all of the following keys.
| Key | Type | Description |
|---|---|---|
version | integer | The sys.version at the time of publishing. |
at | string (date-time) | Last publish time. |
firstAt | string (date-time) | First publish time. Preserved even after unpublishing. |
counter | integer | Cumulative publish count. |
by | Refer<User> | The user who last published. |
When you unpublish, version, at, and by are removed from publish, leaving only firstAt and counter. If it has never been published, publish is { "counter": 0 }.
The archive object is present only while archived. While archived it has version (the sys.version at the time of archiving), at (the archive time), and by (the user who archived it); when not archived, the archive key itself is absent.
The sys.version and all the time values in the examples below are the values at the actual call time, and they differ from call to call.
Publishing, versions, and concurrency
The lifecycle of a Content is as follows.
- When created, its
statusisDraft. AContentis not published automatically on create. This differs from a Content Type. A Content Type is published automatically the moment it is created, whereas a Content enters the delivery path only after a separate publish call. - When you publish, the
statusbecomesPublished. - When you edit it after publishing, the
statusbecomesChanged. This means there are unpublished changes. - When you unpublish, the
statusreturns toDraft. - To archive it, you must unpublish it first. A Content in a published state cannot be archived directly.
sys.version increases by 1 with every change.
Update, partial update, publish, unpublish, archive, and unarchive requests must carry the current sys.version in the x-weegloo-version header. If this value is missing or does not match the current version, it is treated as a concurrent-edit conflict and the request is rejected. Create and delete requests do not carry this header. State transitions such as publish, unpublish, archive, and unarchive have no separate request body.
API
The base URL for all endpoints below is https://cma.weegloo.com/v1, and a Bearer token that authenticates against CMA is required in the Authorization header. Update, partial update, publish, unpublish, archive, and unarchive must also send the X-Weegloo-Version header (the current resource's sys.version) for optimistic concurrency control.
When you filter or sort the flat list (GET /spaces/{spaceId}/contents) by fields.*, you must also scope it with sys.contentType.sys.id={contentTypeId} — a bare contentType={contentTypeId} does not substitute for it. The per-Content Type path (/content-types/{contentTypeId}/contents) already carries it, so it is not needed there.
Related documents
- Content Type: The template for this Content (field definitions and apiNames).
- CDA Content: Delivers (reads) published Content to visitors.
- Tag: The classification labels attached in metadata.tags.
- Localization (concept): The default Locale, required fills, and fallback.
