中文
分发给 Agent
REST API

REST API

通过 HTTP 接口直接操作 PuppyOne 的 Content Node。


概述

如果你在构建自己的 Agent、自动化脚本或后端服务,可以直接调用 PuppyOne 的 REST API 来读写 Content Node。这种方式最灵活,适合需要把 PuppyOne 接入现有系统、工作流或服务端逻辑的场景。


基本信息

Base URL

环境Base URL
云端https://api.puppyone.ai/api/v1
自部署http://localhost:9090/api/v1

认证

所有请求都需要携带认证头:

Authorization: Bearer <access_key>

通常你会为 REST API 集成单独创建一个 Access Key,避免和其他 MCP / 沙盒 / 文件同步连接共用。


核心接口

PuppyOne 的主数据模型是 Content Node 树。常见场景里,你最常用的是以下几组接口。

1. 列出节点

GET /nodes?project_id={project_id}&parent_id={parent_id}

适合浏览目录、列出某个文件夹下的子节点。

2. 获取节点详情

GET /nodes/{node_id}?project_id={project_id}

适合读取某个 JSON / Markdown / 文件节点的详细信息。

3. 创建文件夹

POST /nodes/folder
{
  "project_id": "proj_xxx",
  "parent_id": "node_parent",
  "name": "reports"
}

4. 创建 JSON 节点

POST /nodes/json
{
  "project_id": "proj_xxx",
  "parent_id": "node_parent",
  "name": "weekly-report.json",
  "content": {
    "title": "周报",
    "summary": "本周完成了产品定价调整。"
  }
}

5. 创建 Markdown 节点

POST /nodes/markdown
{
  "project_id": "proj_xxx",
  "parent_id": "node_docs",
  "name": "README.md",
  "content": "# 项目说明\n\n这里是文档正文。"
}

6. 更新节点

PUT /nodes/{node_id}
{
  "name": "README.md",
  "content": "# 项目说明\n\n这里是更新后的正文。"
}

7. 删除节点

DELETE /nodes/{node_id}

8. 上传文件

POST /nodes/upload

适合 PDF、图片、附件等二进制内容。服务端会返回上传地址,客户端再把文件传到存储层。


Python 示例

import httpx
 
BASE_URL = "https://api.puppyone.ai/api/v1"
ACCESS_KEY = "sk_live_xxx"
PROJECT_ID = "proj_xxx"
 
headers = {
    "Authorization": f"Bearer {ACCESS_KEY}",
    "Content-Type": "application/json",
}
 
async def list_nodes(parent_id=None):
    params = {"project_id": PROJECT_ID}
    if parent_id:
        params["parent_id"] = parent_id
 
    async with httpx.AsyncClient() as client:
        resp = await client.get(f"{BASE_URL}/nodes", headers=headers, params=params)
        resp.raise_for_status()
        return resp.json()["data"]["nodes"]
 
async def get_node(node_id):
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            f"{BASE_URL}/nodes/{node_id}",
            headers=headers,
            params={"project_id": PROJECT_ID},
        )
        resp.raise_for_status()
        return resp.json()["data"]
 
async def create_json_node(parent_id, name, content):
    body = {
        "project_id": PROJECT_ID,
        "parent_id": parent_id,
        "name": name,
        "content": content,
    }
    async with httpx.AsyncClient() as client:
        resp = await client.post(f"{BASE_URL}/nodes/json", headers=headers, json=body)
        resp.raise_for_status()
        return resp.json()["data"]
 
async def update_node(node_id, content):
    async with httpx.AsyncClient() as client:
        resp = await client.put(
            f"{BASE_URL}/nodes/{node_id}",
            headers=headers,
            json={"content": content},
        )
        resp.raise_for_status()
        return resp.json()["data"]

JavaScript / Node.js 示例

const BASE_URL = "https://api.puppyone.ai/api/v1";
const ACCESS_KEY = "sk_live_xxx";
const PROJECT_ID = "proj_xxx";
 
const headers = {
  Authorization: `Bearer ${ACCESS_KEY}`,
  "Content-Type": "application/json",
};
 
async function listNodes(parentId) {
  const params = new URLSearchParams({ project_id: PROJECT_ID });
  if (parentId) params.set("parent_id", parentId);
 
  const resp = await fetch(`${BASE_URL}/nodes?${params}`, { headers });
  if (!resp.ok) throw new Error(await resp.text());
  const data = await resp.json();
  return data.data.nodes;
}
 
async function getNode(nodeId) {
  const params = new URLSearchParams({ project_id: PROJECT_ID });
  const resp = await fetch(`${BASE_URL}/nodes/${nodeId}?${params}`, { headers });
  if (!resp.ok) throw new Error(await resp.text());
  const data = await resp.json();
  return data.data;
}
 
async function createJsonNode(parentId, name, content) {
  const resp = await fetch(`${BASE_URL}/nodes/json`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      project_id: PROJECT_ID,
      parent_id: parentId,
      name,
      content,
    }),
  });
  if (!resp.ok) throw new Error(await resp.text());
  const data = await resp.json();
  return data.data;
}

适合什么场景

  • 你在做自研 Agent,需要完全控制请求、响应和重试逻辑
  • 你要把 PuppyOne 接到现有后端服务或自动化流程中
  • 你只需要读写数据,不需要 MCP 客户端那套接入体验

如果你更希望“开箱即用”,通常 MCP 会更省事;如果你需要更细粒度的工程控制,REST API 更合适。


下一步