PrivyPad is a zero-knowledge encrypted notes app. This skill covers all interactions
with its public REST API (https://www.privypad.com/api/v1/).
All note and group endpoints require a Bearer token in the Authorization header.
Authorization: Bearer pp_<uuid>.<base64url-secret>
The token is created once in PrivyPad Settings and must be supplied by the user.
Never ask the user for their password — the token is self-contained.
Token management endpoints (/api/tokens) use the session cookie instead and
are only available in a browser context; do not attempt to call them from scripts.
https://www.privypad.com/api/v1
GET /notes
Query parameters (all optional):
| Parameter | Type | Description |
|---|---|---|
| ----------- | --------- | -------------------------------------- |
| group | string | Filter by group name |
| pinned | boolean | true to return only pinned notes |
| limit | integer | Max results to return |
| offset | integer | Pagination offset |
GET /notes/:id
POST /notes
Content-Type: application/json
{
"title": "string",
"content": "string",
"group": "string", // optional
"tags": ["string"], // optional
"isPinned": false // optional
}
PATCH /notes/:id
Content-Type: application/json
{
"title": "string", // any subset of fields
"content": "string",
"group": "string",
"tags": ["string"],
"isPinned": true
}
DELETE /notes/:id
Add ?permanent=true to hard-delete instead of moving to trash.
GET /groups
Returns all group names for the authenticated user. No query parameters.
const PRIVYPAD_TOKEN = "pp_<uuid>.<base64url-secret>"; // supplied by user
const BASE = "https://privypad.com/api/v1";
async function privypad(method, path, body) {
const res = await fetch(`${BASE}${path}`, {
method,
headers: {
"Authorization": `Bearer ${PRIVYPAD_TOKEN}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) throw new Error(`PrivyPad ${res.status}: ${await res.text()}`);
return res.json();
}
// Examples
const notes = await privypad("GET", "/notes?pinned=true");
const note = await privypad("GET", `/notes/${id}`);
const created = await privypad("POST", "/notes", { title: "Hello", content: "World" });
const updated = await privypad("PATCH", `/notes/${id}`, { isPinned: true });
await privypad("DELETE", `/notes/${id}`);
const groups = await privypad("GET", "/groups");
import httpx
TOKEN = "pp_<uuid>.<base64url-secret>" # supplied by user
BASE = "https://privypad.com/api/v1"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
def privypad(method, path, **kwargs):
r = httpx.request(method, BASE + path, headers=HEADERS, **kwargs)
r.raise_for_status()
return r.json()
# Examples
notes = privypad("GET", "/notes", params={"group": "Work"})
created = privypad("POST", "/notes", json={"title": "Hi", "content": "There"})
updated = privypad("PATCH", f"/notes/{note_id}", json={"isPinned": True})
privypad("DELETE", f"/notes/{note_id}?permanent=true")
groups = privypad("GET", "/groups")
client-side secret needed to decrypt them. Never log or expose the token.
DELETE /notes/:id moves to trash by default. Pass ?permanent=true only when the user explicitly confirms permanent deletion.
content field must be HTML, not Markdown. Use , , , , , , /
, /
etc.
PATCH accepts any subset of fields — only send what changes.limit + offset when fetching large note lists to avoidoversized responses.
return 401. Prompt the user to generate a new token in PrivyPad Settings.
共 1 个版本