English
Core Concepts
Content Node

Content Node

A Content Node is the basic unit of data in PuppyOne.


What is a Content Node

Inside every PuppyOne Project is a content tree, much like a cloud file system. You can create folders, store JSON data, edit Markdown documents, and upload attachments, and AI agents can read and write those contents directly.

Unlike a traditional table-based model, the content tree supports both structured data and unstructured documents, with arbitrary nesting for greater flexibility.


Four node types

TypeDescriptionTypical Use
folderA folder that can contain child nodesOrganizing directory structure
jsonA JSON file for structured dataProduct data, configuration, API responses
markdownA Markdown file for rich text contentDocs, knowledge base articles, meeting notes
fileA binary uploaded filePDFs, images, attachments

Tree structure

Content Nodes form a tree identified by path. Every node has a unique path within its project, just like in a file system:

/
├── docs/
│   ├── product-spec.md        ← Markdown node
│   ├── api-reference.md       ← Markdown node
│   └── changelog.json         ← JSON node
├── data/
│   ├── products.json          ← JSON node
│   ├── customers.json         ← JSON node
│   └── attachments/
│       └── contract.pdf       ← File node
└── README.md                  ← Markdown node

You can manage Content Nodes much like local files: create directories, move files, rename them, and delete them — all addressed by path.


Storage model

Content is stored in a Mut Merkle tree backed by S3, not in a PostgreSQL table. Each write creates a Mut commit that captures the full tree state, enabling:

  • Immutable version history
  • Efficient diffing between any two commits
  • Atomic multi-file operations
  • Rollback to any previous commit

The Merkle tree structure ensures data integrity and makes it possible to verify that content has not been tampered with.


Node properties

Each Content Node includes these core properties:

PropertyDescription
pathFull path within the project, such as data/products.json
nameNode name, such as products.json
typeNode type: folder, json, markdown, or file
contentNode contents. JSON or Markdown text for supported types; empty for folders and files
project_idThe Project this node belongs to

Version history and audit

Every Content Node tracks changes automatically:

  • Version history — Every write creates a new Mut commit. You can compare any two versions and roll back in one click.
  • Audit logs — See who performed which action on which node, and when.

Access control

Content Nodes support fine-grained access control through FLS, or File Level Security:

  • Authorize by path — Agents can only access approved paths (configured via access_points.config.scope)
  • Authorize by operation — Restrict access to read-only or read/write
  • Unauthorized paths are physically invisible to the agent

For example, a support agent may only be allowed to access products and faq, while everything under internal remains hidden.


Working with Content Nodes

Through the Dashboard

In a project's data view, click the create button to add a folder, JSON file, or Markdown file. Uploaded files can be dragged directly into the page.

Through the REST API

All content operations use the /api/v1/content/{project_id}/... endpoints with path-based addressing:

BASE_URL="https://api.puppyone.ai/api/v1/content/YOUR_PROJECT_ID"
TOKEN="YOUR_ACCESS_TOKEN"
 
# Create a folder
curl -X POST "$BASE_URL/mkdir" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"path": "docs"}'
 
# Write a JSON file
curl -X POST "$BASE_URL/write" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "data/products.json",
    "content": {"items": []},
    "node_type": "json",
    "message": "Create products file"
  }'
 
# Read file content
curl "$BASE_URL/cat?path=data/products.json" \
  -H "Authorization: Bearer $TOKEN"
 
# List directory
curl "$BASE_URL/ls?path=data" \
  -H "Authorization: Bearer $TOKEN"

Through external sync sources

Once you add external sources like Notion, GitHub, or Gmail as access points, synced data is automatically transformed into Content Nodes and stored in your project's file tree.


Best practices

  1. Organize by folder — Structure directories by business domain, such as products, docs, and support
  2. Use JSON for structured data and Markdown for documents — Pick the node type that best fits the content
  3. Use paths to separate permissions — Put content with different access needs into different directories
  4. Take advantage of version history — You can always roll back if a change goes wrong