{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Basics of editing content using API","description":"Integrate and automate your content creation process with Foleon's powerful API.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"basics-of-editing-content-using-api","__idx":0},"children":["Basics of editing content using API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Foleon's API gives you the ability to create and edit Foleon content completely programatically. Unlike traditional CMS APIs that might require you to send an entire page back and forth, Foleon uses a normalized data structure and patch-based mutations to make precise updates to your content."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"understanding-the-structure-of-a-content-object","__idx":1},"children":["Understanding the structure of a content object"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Foleon Content objects (",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Pages"]},", ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Templates"]},", ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Modules"]},", ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Themes"]},", ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Overlays"]},", etc.) are JSON representations of the content."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["While Foleon content appears as a nested visual hierarchy (e.g. ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Page"]}," → ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Block"]}," → ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Row"]}," → ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Column"]}," → ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Text"]},"), the underlying JSON is normalized (flat). This means entities are stored in collections based on their idenity, rather than being nested deep inside one another."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"the-content-object","__idx":2},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["content"]}," Object"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To gain a better understanding of the structure of your content you can use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}," operation on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/content/"]}," endpoint for your content type. ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/editing-content/getcontent"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}," operation on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/content/"]}," endpoint for your content type."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you perform a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}," operation on a content type (like a PAGE), the endpoint returns a JSON object containing the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["content"]}," object, which acts as a library of every entity present."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["content"]},", you will find keys like \"block\", \"row\", or \"text-item\". Each of these is a collection of entities of that specific type."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each specific entity is a key-value pair within those collections, where the key is the element's UUID and the value an object containing all the entity's properties."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every entity has an identity string (e.g., \"block\" or \"text-item\") to help you identify its type."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Since the JSON isn't nested, entities use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refs"]}," array and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["parent"]}," object to point to their logical children and parent respectively."]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Why this matters"]},": Because the structure is flat, your \"path\" to an object is almost always relatively short. You don't need to traverse the whole tree; you just need the entity's identity and the entity's UUID."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"example-of-a-block-entity","__idx":3},"children":["Example of a \"block\" entity:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"\"block\": {\n    \"19c2c02e-b968-45b6-9a56-3e0a089393ac\": {\n        \"id\": \"19c2c02e-b968-45b6-9a56-3e0a089393ac\",\n        \"refs\": [\n            {\n                \"id\": \"c5e12c80-da0f-4899-b4aa-ad3173f57f0c\",\n                \"identity\": \"row\"\n            }\n        ],\n        \"parent\": {\n            \"id\": \"d8625a73-2784-4036-8d3c-b35f366876bd\",\n            \"identity\": \"page\"\n        },\n        \"styles\": {\n            \"20\": {},\n            \"30\": {},\n            \"40\": {},\n            \"50\": {\n                \"box\": {\n                    \"height\": \"740\"\n                }\n            }\n        },\n        \"options\": {},\n        \"identity\": \"block\",\n        \"customIdentifier\": null,\n        \"triggerContentAnimationOnce\": false\n    }\n},\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"mutation-endpoint","__idx":4},"children":["Mutation endpoint"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To change content, you use the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/editing-content/mutatecontent"},"children":["Mutation Endpoint"]}," which allows you to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["add"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["remove"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["replace"]}," all elements in the content. Instead of overwriting the whole page, you send Immer-style patches\" that describe specific changes. Immer-style patches describe state changes as a list of operations, similar to JSON Patch."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-an-immer-style-patch-looks-like","__idx":5},"children":["What an Immer-style patch looks like"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A patch is an object with three fields:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["op"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The operation: \"add\", \"replace\", or \"remove\"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["path"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["array"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The breadcrumb path to the property you are changing."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["value"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["any"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The new data (required for add and replace)."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"example","__idx":6},"children":["Example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"{\n  \"op\": \"replace\",\n  \"path\": [\"text-item\", \"60b9663d-fab5-44f7-942c-3721063fde2e\", \"text\"],\n  \"value\": \"My text\"\n}\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This patch means: ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["replace"]}," the value of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["text-item.60b9663d-fab5-44f7-942c-3721063fde2e.text"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"My text\""]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"working-with-styles-and-breakpoints","__idx":7},"children":["Working with Styles and Breakpoints"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Design properties are stored in the styles object of an entity. Foleon uses numeric keys to represent different screen widths (breakpoints):"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["50"]},": Desktop (Base styles)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["40"]},": Tablet Landscape"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["30"]},": Tablet Portrait"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["20"]},": Mobile"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you want to change the height of a block on Mobile, your path would target the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"20\""]}," key:"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[\"block\", \"<SOME UUID>\", \"styles\", \"20\", \"box\", \"height\"]"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"workflow-strategy","__idx":8},"children":["Workflow Strategy"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The most efficient way to learn how to format a patch is to let the Foleon Editor do the work for you."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Manually Edit:"]}," Open your Doc in the Foleon Editor and make the change you want to automate (e.g., change a button color or swap an image)."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inspect Mutations:"]}," Call the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/editing-content/getcontentmutations"},"children":["GET operation on the mutations endpoint"]}," for that page."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Replicate:"]}," Look at the most recent entries in the response. The API will show you the exact path and value used by the Editor. You can now copy this logic into your own script."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"best-practices","__idx":9},"children":["Best Practices"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Atomic Batches:"]}," You can send an array of multiple patches in a single request. This ensures all changes are applied at once."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Safety First:"]}," ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/editing-content/getcontent"},"children":["Perform a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}," on the content"]}," first to verify the UUIDs exist before sending a replace or remove mutation."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Development Sandbox:"]}," Use a duplicate of your content when testing scripts to avoid breaking important content."]}]}]}]},"headings":[{"value":"Basics of editing content using API","id":"basics-of-editing-content-using-api","depth":1},{"value":"Understanding the structure of a content object","id":"understanding-the-structure-of-a-content-object","depth":2},{"value":"The content Object","id":"the-content-object","depth":4},{"value":"Example of a \"block\" entity:","id":"example-of-a-block-entity","depth":4},{"value":"Mutation endpoint","id":"mutation-endpoint","depth":2},{"value":"What an Immer-style patch looks like","id":"what-an-immer-style-patch-looks-like","depth":3},{"value":"Example:","id":"example","depth":4},{"value":"Working with Styles and Breakpoints","id":"working-with-styles-and-breakpoints","depth":3},{"value":"Workflow Strategy","id":"workflow-strategy","depth":2},{"value":"Best Practices","id":"best-practices","depth":2}],"frontmatter":{"seo":{"title":"Basics of editing content using API"}},"lastModified":"2026-04-08T13:57:58.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/editing_content/basics_of_editing_content_using_api","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}