Application API

Reference documentation for the ContentGrid Application REST API.

Resource Types

This document describes the core resource types in the REST API.

Links express a relation between the resource they appear on (the link context), and the link target. Link Relation Types determine the kind of relation between the link context and the link target.

Problem Types

Problem Details are used to provide additional information about the error condition. This reference describes all Problem Detail types that can be returned by the API.

HAL-FORMS Extensions

ContentGrid extensions to the HAL-FORMS specification

Entity Profile: HAL format

The HAL profile format describes the model of an entity type, its attributes and relations.

Subsections of Application API

Resource Types

This document describes the core resource types in a ContentGrid application.

Overview

A ContentGrid application can be configured with kinds of entities that have attributes and relations.

A single instance of such an entity is generically referred to as an entity-item. Multiple entity-items of the same kind together form an entity-collection.

These two form the main resource types in a ContentGrid application. To support these resource types, a couple of additional resource types exist.

entity-item

An entity-item is a single, concrete instance of a certain entity.

Attributes are exposed as fields at the top level of the JSON object. Additionally, an id field is exposed, containing the unique id for the entity-item.

Some attribute types (like content) are exposed as a nested object, which contains the information stored in that attribute.

Like any HAL object, entity-item also has _links and _templates fields.

Example entity-item

This is an example of an invoice with a file in the document attribute.

{
  "id": "3211be1d-1ed1-4850-8ea6-3fa3218031f6",
  "received": "2024-07-15",
  "document": {
     "size": 123456,
     "mimetype": "application/pdf",
     "filename": "example-invoice.pdf"
  },
  "pay_before": "2024-08-14",
  "total_amount": 15.95,
  "_links": {
    [...]
  },
  "_templates": {
    [...]
  }
}

entity-collection

An entity-collection is an (ordered) set of entity-item resources.

Due to the usage of HAL, entity-items are available in a nested JSON object. The list of entity-items will always be located in _embedded.item.

All entity-items in a collection are always of the same type and expose the same attributes. The entity-items may be a reduced representation of a full entity-item resource, where some fields are omitted. The id field, which is used to address the individual entity will always be available.

Example entity-collection

This is an example of a collection of invoices

{
  "_embedded": {
    "item": [
      {
        "id": "3211be1d-1ed1-4850-8ea6-3fa3218031f6",
        "received": "2024-07-15",
        "document": {
            "size": 123456,
            "mimetype": "application/pdf",
            "filename": "example-invoice.pdf"
        },
        "pay_before": "2024-08-14",
        "total_amount": 15.95,
        "_links": {
            [...]
        },
        "_templates": {
          [...]
        }
      },
      {
        "id": "56fe1819-3f70-476c-937d-b400b660ee81",
        "received": "2020-01-01",
        "document": null,
        "pay_before": "2020-02-01",
        "total_amount": 123.4,
        "_links": {
            [...]
        },
        "_templates": {
          [...]
        }
      },
      [...]
    ]
  },
  "_links": {
    [...]
  },
  "page": {
    "size": 20,
    "next_cursor": "1wskufc1",
    "total_items_estimate": 38,
    "total_items_exact": 38
  }
}

Collection meta-information

The entity-collection contains meta-information about itself in the top-level page field:

Field Type Description
size integer, >= 1 Page size; the maximum number of entity-item resources returned on a single page
prev_cursor string or absent Cursor to retrieve the previous page. Absent when there is no previous page
next_cursor string or absent Cursor to retrieve the next page. Absent when there is no next page
total_items_estimate number, >= 0 Estimated total number of items in the collection. Also present when an exact count exists
total_items_exact number, >= 0 or absent Exact total number of items in the collection. Absent when calculation is too resource-intensive to execute

relation

The relation resource represents a relation between two entities. When reading, its format is dependent on whether it is a to-one or a to-many relation:

  • To-one relation (one-to-one, many-to-one): Reading returns a redirect to the linked entity-item
  • To-many relation (one-to-many, many-to-many): Reading returns a redirect to an entity-collection that contains all linked entity-items

relation-item

The relation-item resource represents a single item inside a to-many relation.

Reading returns a redirect to the entity-item, if it is linked in the relation.

entity-content

The entity-content resource represents the file contents that are stored on an entity attribute of type Content.

This resource contains arbitrary file contents, so no assumptions should be made about its format.

entities-root

The entities-root resource is the parent resource of all entity-collection resources.

It contains metadata about the application, in particular the list of all available entity types (in HAL format).

curl -i https://$APP_ID.$REGION.contentgrid.cloud/   \
    -H "Authorization: Bearer $TOKEN"
GET / HTTP/1.1
Authorization: Bearer $TOKEN
HTTP/1.1 OK
Content-Type: application/hal+json

{
  "_links": {
    "cg:entity": [
      {
        "href": "/invoices",
        "name": "invoice"
        [...]
      },
      {
        "href": "/suppliers",
        "name": "supplier"
        [...]
      }
    ],
    [...]
  }
}

entity-profile

The entity-profile resource is a computer-readable description of an entity type.

It describes the entity’s attributes, relations, constraints, and available operations. The full format is documented in the Entity Profiles reference.

profile-root

The profile-root resource is the parent resource of all entity-profile resources.

It contains metadata about the profiles, in particular the list of all available entity-profile types (in HAL format).

Link Relation Types

Links express a relation between the resource they appear on (the link context), and the link target. The link relation type (RFC8288 Sec 3.3) determines the kind of relation between the link context and the link target.

Next to the standard link relation types, which are to be interpreted with their standardized meaning, ContentGrid defines following extension link relation types:

Link relation type Description
https://contentgrid.cloud/rels/contentgrid/relation Refers to a ContentGrid relation of the entity-item. The link’s name attribute is the relation name
https://contentgrid.cloud/rels/contentgrid/content Refers to the binary content of a content attribute. The link’s name attribute is the content attribute name
https://contentgrid.cloud/rels/contentgrid/entity Refers to a ContentGrid entity (from a root resource entities-root and profile-root). The link’s name attribute is the entity name

CURIEs

CURIEs (Compact URIs) are a shorthand notation for extension link relation types.

They are used as defined in the HAL specification. The curies link relation provides expansion templates.

Before comparing a link relation, a CURIE must be expanded into the full URI.

Formal definition of CURIE expansion

Since the HAL specification does not formally specify how CURIEs should be expanded, a definition is given here.

  1. A safe_curie or a curie MAY be used as an extension link relation type. They MUST be expanded to a URI to obtain the formal extension link relation type and SHOULD NOT be used as-is.
  2. A CURIE consists of a prefix and a reference, separated by a colon (:). In the context of HAL; the CURIE MUST have a prefix, and the reference MUST also be an NCName.
    safe_curie := '[' curie ']'
    curie := prefix ':' reference
    prefix := NCName
    reference := NCName
  3. The curies links:
    1. MUST have a name link attribute, which is the CURIE prefix.
    2. MUST be a URI template, which MUST end in a variable named rel. (e.g.: http://example.com/relations/{rel}) The CURIE is expanded by expanding the URI template with the rel variable set to the CURIE reference.
  4. Expansion of a CURIE to a URI begins at the HAL Resource object that contains the particular link relation
    1. If a curies link relation is present with its name attribute equal the CURIE prefix, this link relation is used for expanding the CURIE to an URL
    2. Else, the parent HAL Resource object is consulted using the same algorithm.
    3. If the top-level HAL Resource object was reached without finding a link relation for the CURIE, expansion has failed. An error SHOULD be reported, and the link relation MUST be ignored for all purposes.
A HAL resource using CURIEs
{
  [...]
  "_links": {
    "self": {
      "href": "https://example.com/users/123"
    },
    "cg:content": [
      {
        "name": "profile_picture",
        "href": "https://example.com/users/123/picture"
      }
    ],
    "https://contentgrid.cloud/rels/contentgrid/relation": [
      {
        "name": "friends",
        "href": "https://example.com/users/123/friends"
      }
    ],
    "[example:curied-link]": {
      "href": "https://example.com/dahl-curry"
    },
    "unregistered:curie": {
      "href": "https://example.com/unregistered-curie"
    },
    "curies": [
      {
        "name": "cg",
        "href": "https://contentgrid.cloud/rels/contentgrid/{rel}",
        "template": true
      },
      {
        "name": "example",
        "href": "https://example.com/relations/{rel}",
        "template": true
      }
    ]
  }
}

This is equivalent to the following resource when CURIEs are expanded:

{
  [...]
  "_links": {
    "self": {
      "href": "https://example.com/users/123"
    },
    "https://contentgrid.cloud/rels/contentgrid/content": [
      {
        "name": "profile_picture",
        "href": "https://example.com/users/123/picture"
      }
    ],
    "https://contentgrid.cloud/rels/contentgrid/relation": [
      {
        "name": "friends",
        "href": "https://example.com/users/123/friends"
      }
    ],
    "https://example.com/relations/curied-link": {
      "href": "https://example.com/dahl-curry"
    }
  }
}
  1. IANA-registered link relation types and URI-based extension link relatinos are passed through as-is.
  2. CURIEs and Safe CURIEs are expanded based on the URI templates of the curies links
  3. CURIEs using unknown prefixes are completely ignored

Problem Types

The ContentGrid REST API uses the standard HTTP status codes to signal errors.

RFC9457 Problem Details are used to provide additional information about the error condition.

This reference describes all Problem Detail types that can be returned by the ContentGrid Application REST API.

Unless specified otherwise, the HTTP Status code for problems will be 400 Bad Request.

Input Validation Problems

These problems occur when the data you provide in the request body doesn’t meet the requirements.

Input validation problems are always represented by the a Problem Detail with type https://contentgrid.cloud/problems/input/validation.

input/validation

https://contentgrid.cloud/problems/input/validation

The ProblemDetail contains an additional property, errors, which contains a list of validation errors.

Each validation error has the same structure as a ProblemDetail, with as type one of the subtypes listed below. Each validation error also has a field property, which refers to the specific input field for which validation failed with a property path.

Example
{
  "type": "https://contentgrid.cloud/problems/input/validation",
  "title": "Validation error",
  "detail": "2 validation errors",
  "status": 400,
  "errors": [
    {
      "type": "https://contentgrid.cloud/problems/input/validation/required",
      "title": "Mandatory field",
      "detail": "A value must be present, but it is missing or empty",
      "field": "pay_before"
    },
    {
      "type": "https://contentgrid.cloud/problems/input/validation/type",
      "title": "Invalid data type",
      "detail": "Expected value of type date, but got decimal",
      "field": "received",
      "expected_type": "date",
      "actual_type": "decimal"
    }
  ]
}

input/validation/type

https://contentgrid.cloud/problems/input/validation/type

The value provided has the wrong data type.

A data type error can happen when handling a JSON or a multipart form body.

For example:

  • sending a decimal instead of a long
  • sending a JSON array instead of a single value
  • sending a JSON object instead of a single value
  • repeating the same multipart form field multiple times instead of once
  • sending a multipart file instead of a normal form field

Additional Properties:

  • expected_type (string): The technical name of the expected data type
  • actual_type (string): The technical name of the actual data type received

input/validation/type/format

https://contentgrid.cloud/problems/input/validation/type/format

The value is of the correct type, but it doesn’t match the expected format.

In this case the type is correct (usually a string), but the type (e.g. date, timestamp, relation link) requires a specific format, which was not fulfilled.

For example:

  • sending an arbitrary string instead of a date or timestamp in RFC3339 format
  • sending a link to an entity that is of the wrong type for this relation

Additional Properties:

  • expected_type (string): The expected data type
  • format_error (string): Description of the format error

input/validation/no-content

https://contentgrid.cloud/problems/input/validation/no-content

A content attribute can not be set when there is no content present.

This happens when writing to nested fields in a content attribute, but there is no content present.

It is only valid to change content fields (e.g. set filename or mimetype) when an actual file is present.

input/validation/required

https://contentgrid.cloud/problems/input/validation/required

A required field is set to null.

Note

When using PUT to update an entity, all attributes that are not present in the request body are regarded to be null (including attributes of type content). Use the PATCH method if you only want to update some fields.

input/validation/duplicate

https://contentgrid.cloud/problems/input/validation/duplicate

The value provided for an attribute must be unique, but an other entity item already uses this value.

Additional Properties:

  • conflicting_item (string): URL of the entity that already has this value

input/validation/allowed-values

https://contentgrid.cloud/problems/input/validation/allowed-values

The value is not one of the allowed values.

The possible values for an attribute can be restricted to a list of allowed values. It is then not allowed to use any other value.

Additional Properties:

  • allowed_values (list): A list of all the values that are allowed for the field

Query Parameter Problems

These problems occur when request query parameters don’t meet the requirements.

Contrary to input validation, only a single problem is reported at a time.

invalid-query-parameter/filter/format

https://contentgrid.cloud/problems/invalid-query-parameter/filter/format

Query parameter values are always strings. For some operations, they need to be converted to a certain type (e.g. to a number for a greater-than filter, or to a timestamp for a before filter).

If the value can not be converted, this problem is reported

Additional Properties:

  • query_parameter (string): The name of the query parameter
  • attribute (string): The name of the attribute that is being searched on
  • expected_type (string): The expected data type
  • format_error (string): Description of the format error

invalid-query-parameter/sort/format

https://contentgrid.cloud/problems/invalid-query-parameter/sort/format

The _sort query parameter is malformed and doesn’t match the expected format.

The expected format for sorting is <attribute_name>,asc or <attribute_name>,desc for ascending and descending sorting. Other formats are invalid.

Additional Properties:

  • query_parameter (string): The name of the query parameter (always _sort)

invalid-query-parameter/sort/attribute

https://contentgrid.cloud/problems/invalid-query-parameter/sort/attribute

The _sort query parameter references an attribute that doesn’t exist, or on which sorting is not possible.

Sorting is only possible on attributes that are indexed in a way that supports sorting.

Additional Properties:

  • query_parameter (string): The name of the query parameter (always _sort)
  • attribute (string): The attribute which couldn’t be sorted on

invalid-query-parameter/pagination

https://contentgrid.cloud/problems/invalid-query-parameter/pagination

A pagination-related query parameter (_cursor or _limit) is invalid.

  • The _limit field value must be 1-1000.
  • The _cursor field value should never be manually constructed; use the next_cursor and prev_cursor values from API responses (or follow the HAL links).

Additional Properties:

  • query_parameter (string): The name of the query parameter

General request problems

These problems occur when there is something wrong with the request in general, in ways that are normally never encountered when integrating with ContentGrid.

They are still listed here for reference.

invalid-request/body/json

https://contentgrid.cloud/problems/invalid-request/body/json

The request body contains malformed JSON that can not be parsed.

https://contentgrid.cloud/problems/invalid-request/body/single-link

The request body does not have exactly one link.

This problem occurs when sending a request containing multiple (or zero) links to a to-one relation. A PUT on a to-one relation must contain exactly one link.

invalid-request/required-header

https://contentgrid.cloud/problems/invalid-request/required-header

A required HTTP header is missing from the request.

Additional Properties:

  • header (string): The name of the header that is missing

invalid-request/forbidden-header

https://contentgrid.cloud/problems/invalid-request/forbidden-header

A HTTP Header is present that is not allowed

Additional Properties:

  • header (string): The name of the header that is not allowed

invalid-request/invalid-header

https://contentgrid.cloud/problems/invalid-request/invalid-header

A HTTP Header has a value that is not syntatically valid

Additional Properties:

  • header (string): The name of the header that is not valid

Version Conflict Problems

unsatisfied-version

https://contentgrid.cloud/problems/unsatisfied-version

The entity version specified in the If-Match and/or If-None-Match headers doesn’t match the current version.

This error can happen when using conditional requests, and the entity is modified by another request between get and update.

HTTP Status: 412 Precondition Failed

Additional Properties:

  • actual_version (string): The current version of the entity

Not Found Problems

These problems have HTTP status code 404 Not Found.

Different problem types are used to help distinguish between typos in URLs and entity items that may not be present anymore.

not-found/endpoint

https://contentgrid.cloud/problems/not-found/endpoint

The requested API endpoint does not exist.

This problem type indicates an error in the fixed parts of the URL: in the entity, relation or attribute name.

Check the URL for typos. Ensure you’re using the correct entity type name and that the entity type exists in your data model. If the URL used to work, check that the entity/attribute/relation definition was not renamed or deleted in a newer version of the data model.

not-found/entity-item

https://contentgrid.cloud/problems/not-found/entity-item

No entity was found with the specified id. The entity may have been deleted, or may have never existed.

not-found/relation-item

https://contentgrid.cloud/problems/not-found/relation-item

The relation does not contain the requested entity-item.

This can happen for all relation types:

  • to-one relations: When nothing is linked, a GET or DELETE on the relation resource will result in this error
  • to-many relations: When a specific item is not linked, a GET or DELETE on the relation-item resource will result in this error

Integrity Problems

These problems occur when an operation would violate data integrity constraints.

Unless specified otherwise, integrity problems will use the 409 Conflict HTTP status code.

integrity/invalid-relation-target

https://contentgrid.cloud/problems/integrity/invalid-relation-target

One or more entity-items that are being linked don’t exist.

HTTP Status: 400 Bad Request

Additional Properties:

  • errors (array): List of target errors, each containing details about a missing target (of type not-found/entity-item)

integrity/blind-relation-overwrite

https://contentgrid.cloud/problems/integrity/blind-relation-overwrite

In a to-one relation, the target entity is already referenced by another entity. The operation would silently overwrite that reference without ability to apply proper concurrency control.

Additional Properties:

  • new_item (string): URL of the entity you’re trying to link
  • new_relation (string): URL of the relation you’re trying to set
  • existing_item (string): URL of the entity currently linked
  • existing_relation (string): URL of the existing relation
  • target_item (string): URL of the target entity
  • target_relation (string): URL of the inverse relation (if available)

How to Fix: This is a safety mechanism to prevent data loss. You have several options:

  1. Unlink the existing relation first (DELETE on existing_relation), then create the new link
  2. Use the target entity’s relation endpoint to manage the link, if available
  3. Review your data model - you may need a to-many relation instead of to-one

integrity/required-relation

https://contentgrid.cloud/problems/integrity/required-relation

This problem indicates that the entity-item is referenced in a required relation

It can happen when:

  1. trying to delete the entity-item, and it is referenced by any required relation
  2. trying to unlink the entity-item from a relation, and the other side of the relation is required.

HTTP Status: 409 Conflict

Additional Properties:

  • affected_relation (string): URL of the relation that requires this entity

How to Fix: Before deleting or unlinking the entity, either:

  1. Delete the referencing entity first
  2. Update the referencing entity to link to a different entity
  3. If the relation should be optional in your data model, update your model definition

HAL-FORMS Extensions

The HAL-FORMS specification defines request body encodings for application/json and application/x-www-form-urlencoded.

ContentGrid extends the HAL-FORMS specification:

  • to allow construction of nested JSON objects for application/json request body encoding
  • to define request body encodings for multipart/form-data and text/uri-list
  • the options element is extended to define the behavior of a link with a mediatype of application/hal+json and application/prs.hal-forms+json

Body encoding for application/json

To encode a nested JSON object, the property name will be interpreted as a property path.

Properties for which no value is present are not taken into account for serialization purposes.

Nested JSON encoding

Given this HAL-FORMS template:

{
  "contentType": "application/json",
  "properties": [
    {
      "name": "received",
      "prompt": "Received",
      "required": true,
      "type": "datetime"
    },
    {
      "name": "document.mimetype",
      "prompt": "Document mimetype",
      "type": "text"
    },
    {
      "name": "document.filename",
      "prompt": "Document filename",
      "type": "text"
    },
    {
      "name": "pay_before",
      "prompt": "Pay before",
      "required": true,
      "type": "datetime"
    },
    {
      "name": "total_amount",
      "prompt": "Total amount",
      "required": true,
      "type": "number"
    }
  ]
}

The request body is serialized as:

{
  "received": "2024-05-08T14:58:23Z",
  "document": {
      "mimetype": "text/plain",
      "filename": "example.txt"
  },
  "pay_before": "2024-06-08T00:00:00Z",
  "total_amount": 14.58
}

Body encoding for multipart/form-data

When sending bodies encoded as multipart/form-data, bodies SHOULD be encoded according to the WhatWG HTML standard.

Body encoded for text/uri-list

When sending bodies encoded as text/uri-list, the HAL-FORMS template MUST only contain a single property of type url.

Only the value (or values if the property is multi-value) of the property is part of the request body, in accordance to the text/uri-list mime type.

Multi-valued properties are serialized by having each value on a separate line.

uri-list encoding

Given this HAL-FORMS template:

{
  "contentType": "text/uri-list",
  "properties": [
    {
      "name": "supplier",
      "type": "url"
    }
  ]
}

The request body is serialized as:

http://example.com/example-path?q=abc

Extension for options element

The options element contains an enumerated list of possible values for a property.

When the options element contains a link attribute, the possible values are to be retrieved from a remote HTTP resource.

The link attribute has following child-attributes, with the same meaning as the HAL Link Object:

  • href
  • type
  • templated
  • profile

The behavior of the options element promptField and valueField attributes are dependent on the content-type of the remote HTTP resource. The type attribute may be used as a hint for the content-type of the remote HTTP resource, but the actual content-type of the response is authoritative.

Content-Type of remote resource list of values taken from Interpretation of promptField / valueField
application/json items in the top-level array element name of the JSON field to use for prompt/value of the element (default prompt/value)
text/csv rows in the CSV document 0-indexed column number of the row to use for prompt/value of the element (default 0/1)
application/hal+json or application/prs.hal-forms+json embedded resources (_embedded) with link relation type item. Pagination using prev/next links may be used. JSON pointer to the JSON value to use for prompt/value of the element (default empty pointer//_links/self/href)
Example

Given a HAL-FORMS property:

{
  "name": "supplier",
  "options": {
    "link": {
      "href": "https://app.contentgrid.example/suppliers"
    }
  }
}

The following responses by the remote HTTP resources are possible, which all result in a very similar way of displaying.

Content-Type Simple Array Key/Value Array

application/json

["Fedex","UPS","DHL"]
[
  {"prompt" : "Federal Express", "value" : "FedEx"},
  {"prompt" : "United Parcel Service", "value" : "UPS"},
  {"prompt" : "DHL Express", "value" : "DHL"}
]

text/csv

Fedex
UPS
DHL
Federal Express,FedEx
United Parcel Service,UPS
DHL Express,DHL

application/hal+json or application/prs.hal-forms+json

N/A

{
  "_embedded": {
    "item": [
      {
        "name": "Federal Express",
        "_links": {
          "self": {
            "href": "https://app.contentgrid.example/suppliers/FedEx"
          }
        }
      },
      {
        "name": "United Parcel Service",
        "_links": {
          "self": {
            "href": "https://app.contentgrid.example/suppliers/UPS"
          }
        }
      }
    ]
  },
  "_links": {
    "next": {
      "href":  "https:/app.contentgrid.example/suppliers?page=2"
    }
  }
}

with on the next page:

{
  "_embedded": {
    "item": [
      {
        "name": "DHL Express",
        "_links": {
          "self": {
            "href": "https://app.contentgrid.example/suppliers/DHL"
          }
        }
      }
    ]
  },
  "_links": {
    "prev": {
      "href":  "https:/app.contentgrid.example/suppliers?page=1"
    }
  }
}
Note

For the HAL-based resource, the resolved prompt value would be the full item object. It is up to the implementation how to display this object. If this is unwanted, promptField can be set to a JSON pointer to select a specific field as a prompt. (e.g. "promptField": "/name")

Property path

A property path is used to reference fields in nested JSON objects.

The property path is built by separating JSON fields with .. e.g. document.filename will be serialized as a top-level field document which is assigned to an object with a filename field.

Entity Profile: HAL format

The HAL profile format describes the model of an entity type, its attributes and relations.

It also provides the search and create-form HAL-FORMS templates, which describe how to search and create new items of this type.

The entity profile uses standard link relation types and ContentGrid-specific extension link relation types. See the Link Relation Types reference for general information on link relation types and CURIEs.

The entity profile introduces the blueprint CURIE prefix (https://contentgrid.cloud/rels/blueprint/{rel}) for the following link relation types:

Link relation type Context Description
blueprint:attribute entity An attribute defined on the entity
blueprint:relation entity A relation defined on the entity
blueprint:attribute attribute An attribute that is nested inside an other attribute (nested object)
blueprint:constraint attribute A constraint on the attribute
blueprint:search-param attribute A search parameter for the attribute
blueprint:target-entity relation Points to the entity profile of the relation’s target entity type

Entity Profile Fields

The top-level entity profile resource contains:

Field Type Description
name string Internal entity name
title string Human-readable entity name (singular)
description string or null Description of the entity

The entity profile also contains embedded HAL resources:

  • blueprint:attribute: A list of the attributes that are present on the entity
  • blueprint:relation: A list of the relations that are present on the entity

The entity profile contains HAL links:

Link relation type name attribute Description
self N/A Links to this profile
describes collection Links to the entity collection URL
describes item URI template for linking to individual entity items
curies all See CURIEs
Entity profile overview
curl -i https://$APP_ID.$REGION.contentgrid.cloud/profile/invoices   \
    -H 'Accept: application/prs.hal-forms+json'   \
    -H "Authorization: Bearer $TOKEN"
GET /profile/invoices HTTP/1.1
Authorization: Bearer $TOKEN
Accept: application/prs.hal-forms+json
HTTP/1.1 200 OK
Content-Type: application/prs.hal-forms+json

{
  "name": "invoice",
  "title": "Invoice",
  "description": null,
  "_embedded": {
    "blueprint:attribute": [...],
    "blueprint:relation": [...]
  },
  "_links": {
    "self": {
      "href": "https://app.contentgrid.example/profile/invoices",
      "title": "Invoice"
    },
    "describes": [
      {
        "href": "https://app.contentgrid.example/invoices",
        "title": "Invoices",
        "profile": "https://app.contentgrid.example/profile/invoices",
        "name": "collection"
      },
      {
        "href": "https://app.contentgrid.example/invoices/{id}",
        "title": "Invoice",
        "name": "item",
        "templated": true
      }
    ],
    "curies": [
      {
        "href": "https://contentgrid.cloud/rels/contentgrid/{rel}",
        "name": "cg",
        "templated": true
      },
      {
        "href": "https://contentgrid.cloud/rels/blueprint/{rel}",
        "name": "blueprint",
        "templated": true
      }
    ]
  },
  "_templates": {
    "search": {...},
    "create-form": {...}
  }
}

Embedded Resources

The entity profile contains embedded resources that describe the entity’s attributes and relations.

Attribute (blueprint:attribute)

Entity attributes are embedded resources in the entity profile under the link relation blueprint:attribute.

Field Type Description
name string Attribute name
title string Human-readable title
type string Data type: string, long, double, boolean, date, datetime, object
description string or null Attribute description
readOnly boolean Whether the attribute is read-only
required boolean Whether the attribute is required

Each attribute itself contains embedded resources, describing details about the attribute:

Simple attribute
{
  "name": "received",
  "title": "Received",
  "type": "date",
  "description": null,
  "readOnly": false,
  "required": true,
  "_embedded": {
    "blueprint:constraint": [
      {
        "type": "required"
      }
    ],
  }
}

Sub-attributes

Attributes with type: "object" (such as content attributes) can contain nested blueprint:attribute sub-attributes. Sub-attributes have the same structure as top-level attributes, recursively.

Content attribute with sub-attributes
{
  "name": "document",
  "title": "Document",
  "type": "object",
  "description": null,
  "readOnly": false,
  "required": false,
  "_embedded": {
    "blueprint:attribute": [
      {
        "name": "filename",
        "title": "Filename",
        "type": "string",
        "description": null,
        "readOnly": false,
        "required": false
      },
      {
        "name": "mimetype",
        "title": "Mimetype",
        "type": "string",
        "description": "Technical indicator of the type of the file",
        "readOnly": false,
        "required": false
      },
      {
        "name": "length",
        "title": "Size",
        "type": "long",
        "description": "File size in bytes",
        "readOnly": true,
        "required": false
      }
    ]
  }
}

Constraint (blueprint:constraint)

Constraints are embedded in an attribute under the link relation blueprint:constraint.

Field Applies to Type Description
type all string Constraint type; see below
values allowed-values array List of allowed values for the attribute

Following constraint types are supported:

Constraint type Description
required The attribute must have a value and cannot be null.
unique The attribute value must be unique across all entities of this type.
allowed-values The attribute value must be one of a predefined set of allowed values.
created-date The attribute is managed by the system and contains the creation timestamp.
created-by The attribute is managed by the system and contains the creator’s identity.
modified-date The attribute is managed by the system and contains the last modified timestamp.
modified-by The attribute is managed by the system and contains the last modifier’s identity.

Search Parameter (blueprint:search-param)

Search parameters are embedded in an attribute under the link relation blueprint:search-param. They describe the query parameters that can be used to filter on this attribute in the search template.

Field Type Description
name string Query parameter name
title string Human-readable title
type string Search type; see below

Following search parameter types are supported:

Search parameter type Description
exact-match Match the attribute value exactly (case-sensitive string comparison).
prefix-match Match the attribute value by prefix.
greater-than Match values greater than the specified value.
less-than Match values less than the specified value.
greater-than-or-equal Match values greater than or equal to the specified value.
less-than-or-equal Match values less than or equal to the specified value.
full-text Perform a full-text search on the attribute value.
Attribute with search parameters
{
  "name": "pay_before",
  "title": "Pay before",
  "type": "date",
  "description": null,
  "readOnly": false,
  "required": true,
  "_embedded": {
    "blueprint:search-param": [
      {
        "name": "pay_before",
        "title": "Pay before",
        "type": "exact-match"
      },
      {
        "name": "pay_before~after",
        "title": "Pay before: After",
        "type": "greater-than"
      },
      [...]
    ]
}

Relation (blueprint:relation)

Relations are embedded in the entity profile under blueprint:relation.

Field Type Description
name string Relation name
title string Human-readable title
description string or null Relation description
many_source_per_target boolean Multiple source entities can reference the same target
many_target_per_source boolean Source can reference multiple targets
required boolean Whether the relation is required

Each relation has a blueprint:target-entity link, referencing to the profile of the target entity type.

Relation
{
  "name": "supplier",
  "title": "Supplier",
  "description": null,
  "many_source_per_target": true,
  "many_target_per_source": false,
  "required": false,
  "_links": {
    "blueprint:target-entity": {
      "href": "https://app.contentgrid.example/profile/suppliers",
      "title": "Supplier"
    }
  }
}

Templates

The entity profile provides HAL-FORMS templates that describe how to search and create entities of this type. See HAL-FORMS extensions for additional details on the extensions used.

search Template

The search template describes how to filter and sort the entity collection.

Search template properties are composed from 3 sources:

  • search parameters defined on attributes
  • Cross relation search parameters, where the search parameters from the relation target entity are prefixed by the relation name and a dot (e.g. supplier.name)
  • Special properties: _sort

The _sort property is a special property with a list of options. Next to the standard options as defined in HAL-FORMS, each option has property and direction fields. These additional fields can be used to programmatically select an option for a particular attribute and a particular sorting direction without having to resort to string manipulation.

search template
{
  "_templates": {
    "search": {
      "method": "GET",
      "target": "https://app.contentgrid.example/invoices",
      "properties": [
        {
          "name": "pay_before",
          "prompt": "Pay before",
          "type": "date"
        },
        [...]
        {
          "name": "supplier.name",
          "prompt": "Supplier: Name",
          "type": "text"
        },
        {
          "name": "_sort",
          "prompt": "Sort",
          "type": "text",
          "options": {
            "minItems": 0,
            "promptField": "prompt",
            "valueField": "value",
            "inline": [
              {
                "property": "pay_before",
                "direction": "asc",
                "prompt": "Pay before ascending",
                "value": "pay_before,asc"
              },
              {
                "property": "pay_before",
                "direction": "desc",
                "prompt": "Pay before descending",
                "value": "pay_before,desc"
              },
              {
                "property": "total_amount",
                "direction": "asc",
                "prompt": "Total amount 0\u21929",
                "value": "total_amount,asc"
              },
              {
                "property": "total_amount",
                "direction": "desc",
                "prompt": "Total amount 9\u21920",
                "value": "total_amount,desc"
              }
            ]
          }
        }
      ]
    }
  }
}

create-form Template

The create-form template describes how to create a new entity of this type.

Depending on whether content attributes are present, the form can use application/json or multipart/form-data content types.

The create form includes fields for both attributes and relations, following the HAL-FORMS extensions specification.

create-form template
{
  "_templates": {
    "create-form": {
      "method": "POST",
      "target": "https://app.contentgrid.example/invoices",
      "contentType": "multipart/form-data",
      "properties": [
        {
          "name": "received",
          "prompt": "Received",
          "required": true,
          "type": "date"
        },
        {
          "name": "document",
          "prompt": "Document",
          "type": "file"
        },
        {
          "name": "pay_before",
          "prompt": "Pay before",
          "required": true,
          "type": "date"
        },
        {
          "name": "total_amount",
          "prompt": "Total amount",
          "required": true,
          "type": "number"
        },
        {
          "name": "supplier",
          "prompt": "Supplier",
          "type": "url",
          "options": {
            "link": {
              "href": "https://app.contentgrid.example/suppliers",
              "title": "Suppliers"
            },
            "minItems": 0,
            "maxItems": 1,
            "valueField": "/_links/self/href"
          }
        }
      ]
    }
  }
}