> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful.com/developers/docs/_mcp/server. Destination nodes form the routing tree of a destination. Every create and upsert request must include an explicit top-level `type` field to select one of three node types: | Destination Node type | Create one to | `type` in the request | `sys.type` in the response | | --------------------- | ------------------------------------------------------------------------- | --------------------------- | --------------------------- | | Folder | Group other Destination Nodes under a path without serving anything at it | `DestinationFolderNode` | `DestinationFolderNode` | | Experience | Serve a published experience at a path | `DestinationExperienceNode` | `DestinationExperienceNode` | | Redirect | Send a path to another Destination Node in the same tree | `DestinationRedirectNode` | `DestinationRedirectNode` | Requests with a missing or unsupported `type` return **422 Unprocessable Entity**. The API does not infer the node type from the presence of `experience` or `redirectTo`. Experience and redirect nodes can be saved as unassigned drafts. An experience node requires `experience` before publishing, and a redirect node requires `redirectTo` before publishing. Publishing an unassigned node returns **422 Unprocessable Entity**. Folder nodes accept neither reference, experience nodes accept only `experience`, and redirect nodes accept only `redirectTo`. ## Node properties Every request to create or update a destination node accepts the following common fields, regardless of the node type: | Field | Type | Required | Description | | ---------- | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | String | true | One of `DestinationFolderNode`, `DestinationExperienceNode`, or `DestinationRedirectNode` | | name | String | false | Human-readable name of the Destination Node | | properties | Array | true | Values for the Destination Node properties the Channel declares. See [Paths](#paths) for the `Path` property | | parent | Link | On update | Link to the parent `Destination` or Destination Node. Optional on create: omit it to attach the node to the Destination root. Required when updating an existing node | The selected node type determines which reference the request accepts: | Field | Type | Required | Description | | ---------- | ------------ | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | experience | ResourceLink | Before publishing a Destination Experience Node | The experience served at this path, addressed by its Contentful Resource Name | | redirectTo | Link | Before publishing a Destination Redirect Node | Another Destination Node in the same Destination. The target must exist and must not be the redirect node itself | A destination node response identifies the node type through `sys.type`. Each variant contains `properties`, `parent`, and `sys`, together with `name`, `experience`, or `redirectTo` when assigned. ## Paths If the Channel declares a node property of type `Path`, supply its value in `properties` as `{ "path": "products" }`. The property discriminator `type` is optional in requests: `{ "type": "Path", "path": "products" }` is also valid. Responses include `type` set to `Path`. Each `properties[].path` is a single local path segment. Create and upsert requests accept only ASCII letters (`A–Z`, `a–z`), numbers (`0–9`), hyphens (`-`), underscores (`_`), and dots (`.`). Nonempty segments must not consist only of dots. Whitespace, Unicode, slashes, other punctuation, and dynamic placeholder syntax are rejected. | Accepted | Rejected | | ---------------------------------------------------- | ---------------------------------------------------------------------------- | | `products`, `Product_2-v1.html`, `.well-known`, `""` | `/products`, `home/team`, `with spaces`, `café`, `[blank]`, `.`, `..`, `...` | Invalid writes return **422 Unprocessable Entity** with a field error at `properties..path`. To build a route with multiple segments, create a node at `products`, then add a child with `path` set to `shoes` to resolve `/products/shoes`. The API joins parent and child segments with `/` when resolving paths. Resolved paths must be unique within the Destination. Use an empty string (`""`) for the home path, which resolves to `/`. Existing stored paths remain readable and are not automatically rewritten. When updating a node whose path no longer meets these rules, submit a valid replacement path, even if the update changes another field. Publish the node through the usual workflow to deliver the changed route. For example, create an experience node with this request body: ```json { "type": "DestinationExperienceNode", "properties": [{ "path": "products" }], "experience": { "sys": { "type": "ResourceLink", "linkType": "Contentful:Experience", "urn": "crn:contentful:::experience:spaces/$self/environments/$self/experiences/productIndex" } } } ``` Write operations are validated against the entire destination tree, not only the destination node in the request. Contentful rejects any operation that would: * Create a duplicate resolved path. * Assign the home path to more than one destination node. * Set a redirect target to a missing node, the redirect node itself, or a node in another Destination. * Violate the integrity of the destination tree. There is no endpoint that lists destination nodes. Use [Get the Destination Node tree for a Destination](/references/experience-management-api/destinations-management/destinations/destinations/get-destination-tree) to enumerate them, or keep the IDs returned by create and upsert requests. ## Changing a node's type Use [Upsert a Destination Node by ID](/references/experience-management-api/destinations-management/destinations/destination-nodes/upsert-destination-node) to change a folder into an experience node, or an experience node into a folder. Changes to or from redirect nodes are unsupported. Unpublish the node, all its descendants, and any redirects targeting it first, starting with the leaves. Send the current `X-Contentful-Version` and a complete body for the target type, preserving the existing `parent` and path properties. Move the node or change its path in a separate update. For example, convert a folder at `articles` into an unassigned experience node: ```json { "type": "DestinationExperienceNode", "name": "Articles", "parent": { "sys": { "type": "Link", "linkType": "Destination", "id": "site" } }, "properties": [{ "path": "articles" }] } ``` You can supply `experience` when converting to an experience node. Omit it when converting to a folder. The operation preserves the node ID and location, updates direct children's parent links and incoming redirects' target links, and returns **200 OK**. The replacement is a new draft with `sys.version` reset to `1`, fresh creation metadata, and no publication history. Relinked children and redirects receive new versions. Use the returned version for your next write and refresh the affected nodes. Conversion requires update permission on the existing node and create permission for the target type. A missing or stale version returns **409 Conflict**. Unsupported transitions, published nodes, or a changed parent or path return **422 Unprocessable Entity** with `DestinationNodeTypeChangeNotAllowed`, `DestinationNodeTypeChangeRequiresUnpublished`, or `DestinationNodeTypeChangeLocationMismatch`, respectively. ## Destination Node [Create a new Destination Node](/references/experience-management-api/destinations-management/destinations/destination-nodes/create-destination-node) [Get a Destination Node by ID](/references/experience-management-api/destinations-management/destinations/destination-nodes/get-destination-node) [Upsert a Destination Node by ID](/references/experience-management-api/destinations-management/destinations/destination-nodes/upsert-destination-node) [Delete a Destination Node by ID](/references/experience-management-api/destinations-management/destinations/destination-nodes/delete-destination-node) ## Publishing [Publish a Destination Node](/references/experience-management-api/destinations-management/destinations/destination-nodes/publish-destination-node) [Unpublish a Destination Node](/references/experience-management-api/destinations-management/destinations/destination-nodes/unpublish-destination-node) ## API Docs - Destination Nodes [Create a new Destination Node](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/create-destination-node.md) - Destination Nodes [Get a Destination Node by ID](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/get-destination-node.md) - Destination Nodes [Upsert a Destination Node by ID](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/upsert-destination-node.md) - Destination Nodes [Delete a Destination Node by ID](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/delete-destination-node.md) - Destination Nodes [Publish a Destination Node](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/publish-destination-node.md) - Destination Nodes [Unpublish a Destination Node](https://contentful.com/developers/docs/references/experience-management-api/destinations-management/destinations/destination-nodes/unpublish-destination-node.md) ## OpenAPI Specification The raw OpenAPI 3.1 specification for this API is available at: - [OpenAPI JSON](https://contentful.com/developers/docs/openapi.json) - [OpenAPI YAML](https://contentful.com/developers/docs/openapi.yaml)