Files Endpoint
Implementation: inc/Api/Files.php, inc/Api/AgentFiles.php
Base URL: /wp-json/datamachine/v1/files
Overview
The Files endpoint handles two distinct scopes:
- Flow files — File uploads for pipeline processing with flow-isolated storage, security validation, and automatic URL generation (
inc/Api/Files.php) - Agent files — Agent memory file management with 3-layer directory resolution for SOUL.md, MEMORY.md, USER.md, and daily memory journals (
inc/Api/AgentFiles.php)
Authentication
Requires authenticated user. Agent file endpoints use scoped permissions — users can access their own agent files, and users with manage_agents capability can access any agent’s files.
Flow File Endpoints
POST /files
Upload a file for flow processing (flow_step_id).
Permission: manage_options capability required
Parameters:
flow_step_id(string, optional): Flow step ID for flow-level filesfile(file, required): File to upload (multipart/form-data)
File Restrictions:
- Maximum size: Determined by WordPress
wp_max_upload_size()setting (typically 2MB-128MB) - Blocked extensions: php, exe, bat, js, sh, and other executable types
- Security: Path traversal protection and MIME type validation
Example Request:
# Flow scope
curl -X POST https://example.com/wp-json/datamachine/v1/files
-u username:application_password
-F "flow_step_id=abc-123_42"
-F "file=@/path/to/document.pdf"Success Response (201 Created):
{
"success": true,
"data": {
"filename": "document_1234567890.pdf",
"size": 1048576,
"modified": 1704153600,
"url": "https://example.com/wp-content/uploads/datamachine-files/5/My%20Pipeline/42/document_1234567890.pdf"
},
"message": "File "document.pdf" uploaded successfully."
}Response Fields:
success(boolean): Request success statusdata(object): Uploaded file informationfilename(string): Timestamped filenamesize(integer): File size in bytesmodified(integer): Unix timestamp of uploadurl(string): Public URL to access file
message(string): Success confirmation
GET /files
List files in a flow scope (flow_step_id).
Success Response (200 OK):
{
"success": true,
"data": [
{
"name": "document_1234567890.pdf",
"size": 1048576,
"modified": 1704153600,
"url": "https://example.com/wp-content/uploads/datamachine-files/.../document_1234567890.pdf"
}
]
}GET /files/{filename}
Download a file by filename.
Permission: manage_options capability required
Parameters:
filename(string): Timestamped filenamesize(integer): File size in bytesmodified(integer): Unix timestamp of uploadurl(string): Public URL to access file
Response: Returns the file content directly.
DELETE /files/{filename}
Delete a file by filename.
Permission: manage_options capability required
Parameters:
filename(string): Timestamped filenamesize(integer): File size in bytesmodified(integer): Unix timestamp of uploadurl(string): Public URL to access file
Success Response (200 OK):
{
"success": true,
"data": {
"deleted": true,
"filename": "document_1234567890.pdf"
}
}Agent File Endpoints
Implementation: inc/Api/AgentFiles.php (@since v0.38.0)
Agent files use a 3-layer directory resolution system:
- Shared layer (
shared/) — Site-wide files like SITE.md - Agent layer (
agents/{slug}/) — Agent-specific files: SOUL.md, MEMORY.md - User layer (
users/{id}/) — User-specific files: USER.md
The user_id parameter controls which user context to resolve. Defaults to the current authenticated user. Users with manage_agents capability can access other users’ files.
GET /files/agent
List agent files for the current user context.
Permission: Authenticated user (own files) or manage_agents capability (other users)
Parameters:
filename(string, required): File to retrievepipeline_id(integer, optional): Filter by pipelineflow_id(integer, optional): Filter by flowflow_step_id(string, optional): Filter by flow step
Success Response (200 OK):
{
"success": true,
"data": [
{
"filename": "SOUL.md",
"size": 2048,
"modified": 1704153600,
"layer": "agent"
},
{
"filename": "MEMORY.md",
"size": 4096,
"modified": 1704240000,
"layer": "agent"
}
]
}GET /files/agent/{filename}
Read an agent memory file (SOUL.md, MEMORY.md, USER.md, etc.).
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
filename(string, required): File to deletepipeline_id(integer, optional): Filter by pipelineflow_id(integer, optional): Filter by flowflow_step_id(string, optional): Filter by flow step
Success Response (200 OK):
{
"success": true,
"data": {
"filename": "MEMORY.md",
"content": "# Agent Memorynn## Staten...",
"size": 4096,
"modified": 1704240000
}
}PUT /files/agent/{filename}
Write/update an agent memory file.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
user_id(integer, optional): WordPress user ID for layered context resolution
Example:
curl -X PUT https://example.com/wp-json/datamachine/v1/files/agent/MEMORY.md
-H "Content-Type: application/json"
-u username:application_password
-d '{"content": "# Agent MemorynnI know how to..."}'DELETE /files/agent/{filename}
Delete an agent file.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
filename(string, required): Agent memory file (e.g.,SOUL.md,MEMORY.md)user_id(integer, optional): WordPress user ID for context
Daily Memory Endpoints
Implementation: inc/Api/AgentFiles.php (lines 121-195)
Daily memory files store temporal session logs at daily/YYYY/MM/DD.md. These endpoints manage the daily memory journal separate from persistent memory files.
GET /files/agent/daily
List all daily memory files for the agent.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
filename(string, required): Agent memory filecontent(string, required): New file contentuser_id(integer, optional): WordPress user ID for context
Success Response (200 OK):
{
"success": true,
"data": [
{
"date": "2026-03-15",
"size": 1024,
"path": "daily/2026/03/15.md"
},
{
"date": "2026-03-14",
"size": 2048,
"path": "daily/2026/03/14.md"
}
]
}GET /files/agent/daily/{year}/{month}/{day}
Read a specific daily memory file.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
filename(string, required): Agent file to deleteuser_id(integer, optional): WordPress user ID for context
Example Request:
curl https://example.com/wp-json/datamachine/v1/files/agent/daily/2026/03/15
-u username:application_passwordSuccess Response (200 OK):
{
"success": true,
"data": {
"date": "2026-03-15",
"content": "# Daily Memory — 2026-03-15nn## Session Activityn...",
"size": 1024
}
}PUT /files/agent/daily/{year}/{month}/{day}
Write or update a daily memory file.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
user_id(integer, optional): WordPress user ID for context
Example Request:
curl -X PUT https://example.com/wp-json/datamachine/v1/files/agent/daily/2026/03/15
-H "Content-Type: application/json"
-u username:application_password
-d '{"content": "# Daily Memory — 2026-03-15nn## Session ActivitynUpdated docs..."}'DELETE /files/agent/daily/{year}/{month}/{day}
Delete a daily memory file.
Permission: Authenticated user (own files) or manage_agents capability
Parameters:
year(string, required): 4-digit year (e.g.,2026)month(string, required): 2-digit month (01–12)day(string, required): 2-digit day (01–31)user_id(integer, optional): WordPress user ID for context
Error Responses
400 Bad Request – File Too Large
{
"code": "file_validation_failed",
"message": "File too large: 50 MB. Maximum allowed size: 32 MB",
"data": {"status": 400}
}400 Bad Request – Invalid File Type
{
"code": "file_validation_failed",
"message": "File type not allowed for security reasons.",
"data": {"status": 400}
}400 Bad Request – Missing Scope
{
"code": "missing_scope",
"message": "Must provide either flow_step_id or scope=agent.",
"data": {"status": 400}
}400 Bad Request – Conflicting Scope
{
"code": "conflicting_scope",
"message": "Invalid request.",
"data": {"status": 400}
}400 Bad Request – Missing File
{
"code": "missing_file",
"message": "File upload is required.",
"data": {"status": 400}
}401 Unauthorized – Not Logged In
{
"code": "rest_forbidden",
"message": "You must be logged in to manage files.",
"data": {"status": 401}
}File Storage
Flow File Directory Structure
Files are stored under the datamachine-files uploads directory.
year(string, required): 4-digit yearmonth(string, required): 2-digit monthday(string, required): 2-digit daycontent(string, required): File contentuser_id(integer, optional): WordPress user ID for context
See FilesRepository for the current directory structure.
wp-content/uploads/datamachine-files/
└── {flow_step_id}/
├── document_1234567890.pdf
├── image_1234567891.jpg
└── data_1234567892.csvAgent File Directory Structure
Agent files use the Data Machine layered directory system:
wp-content/uploads/datamachine/
├── shared/
│ └── SITE.md
├── agents/
│ └── {agent-slug}/
│ ├── SOUL.md
│ ├── MEMORY.md
│ └── daily/
│ └── 2026/
│ └── 03/
│ ├── 14.md
│ └── 15.md
└── users/
└── {user-id}/
└── USER.mdFilename Format
Uploaded flow files are automatically timestamped to prevent collisions:
{original_name}_{unix_timestamp}.{extension}Example: report.pdf → report_1704153600.pdf
Access Control
year(string, required): 4-digit yearmonth(string, required): 2-digit monthday(string, required): 2-digit dayuser_id(integer, optional): WordPress user ID for context
Security Features
Blocked File Types
The following file extensions are blocked for security:
- Flow scope: files are grouped by pipeline + flow.
MIME Type Validation
Server validates MIME types to prevent file type spoofing:
// Allowed MIME types (examples)
- application/pdf
- image/jpeg, image/png, image/gif
- text/csv
- application/json
- etc.Path Traversal Protection
File paths are sanitized to prevent directory traversal attacks:
// Blocked patterns
- ../
- ..\
- Absolute pathsIntegration Examples
Python File Upload
import requests
from requests.auth import HTTPBasicAuth
url = "https://example.com/wp-json/datamachine/v1/files"
auth = HTTPBasicAuth("username", "application_password")
# Upload file
with open('/path/to/document.pdf', 'rb') as f:
files = {'file': f}
data = {'flow_step_id': 'abc-123_42'}
response = requests.post(url, files=files, data=data, auth=auth)
if response.status_code == 201:
result = response.json()
print(f"File uploaded: {result['data']['url']}")
else:
print(f"Upload failed: {response.json()['message']}")JavaScript Agent Memory Access
const axios = require('axios');
const agentFilesAPI = {
baseURL: 'https://example.com/wp-json/datamachine/v1/files/agent',
auth: { username: 'admin', password: 'application_password' }
};
// Read MEMORY.md
async function readMemory() {
const response = await axios.get(`${agentFilesAPI.baseURL}/MEMORY.md`, {
auth: agentFilesAPI.auth
});
return response.data.data.content;
}
// Update MEMORY.md
async function updateMemory(content) {
const response = await axios.put(`${agentFilesAPI.baseURL}/MEMORY.md`,
{ content },
{ auth: agentFilesAPI.auth }
);
return response.data.success;
}
// Read today's daily memory
async function readDailyMemory(year, month, day) {
const response = await axios.get(
`${agentFilesAPI.baseURL}/daily/${year}/${month}/${day}`,
{ auth: agentFilesAPI.auth }
);
return response.data.data.content;
}cURL with Form Data
curl -X POST https://example.com/wp-json/datamachine/v1/files
-u username:application_password
-F "flow_step_id=abc-123_42"
-F "file=@/Users/username/Documents/report.pdf"File Lifecycle
- Upload: File uploaded via REST API
- Validation: Size, type, and security checks
- Storage: Saved to flow-isolated directory
- Processing: Fetch handler accesses file via URL
- Cleanup: Manual cleanup or automated via flow deletion
Related Documentation
- Flow files: Stored in publicly accessible directories, organized by flow step ID for isolation
- Agent files: Access controlled via WordPress user permissions and scoped agent resolution
Base URL: /wp-json/datamachine/v1/files
Implementation: inc/Api/Files.php (flow files), inc/Api/AgentFiles.php (agent files)
Max File Size: WordPress wp_max_upload_size() setting