Personal API
Examples
Ready-made code in curl, JavaScript and Python, from the first request to a complete automation.
All the examples read the token and the account ID from environment variables:
export PAPER_TOKEN="paper_…"
export PAPER_ACCOUNT="3f2a…"A minimal client
// Node 18+ or browser. No dependencies.
const BASE = 'https://wire.ia.br/api/v1';
async function paper(path, { method = 'GET', body, retries = 4 } = {}) {
for (let i = 0; ; i++) {
const res = await fetch(BASE + path, {
method,
headers: {
Authorization: `Bearer ${process.env.PAPER_TOKEN}`,
'X-Paper-Account': process.env.PAPER_ACCOUNT,
'Accept-Language': 'en',
...(body ? { 'Content-Type': 'application/json' } : {}),
},
body: body ? JSON.stringify(body) : undefined,
});
if (res.ok) return res.status === 204 ? null : res.json();
const { error } = await res.json().catch(() => ({ error: res.statusText }));
const worthIt = [429, 500, 502, 503].includes(res.status) && i < retries;
if (!worthIt) throw new Error(`${res.status}: ${error}`);
await new Promise((r) => setTimeout(r, 2000 * 2 ** i));
}
}
const me = await paper('/me');
console.log(`Connected as ${me.conta.nome}, ${me.token.tipo} token`);Create the day's page
Creates a page with today's date in a "Script diary" folder, if it doesn't exist yet.
const today = new Date().toISOString().slice(0, 10);
const pages = await paper('/vaults/principal/pages');
let folder = pages.find((p) => p.kind === 'pasta' && p.title === 'Script diary');
if (!folder) {
folder = await paper('/vaults/principal/pages', {
method: 'POST',
body: { title: 'Script diary', kind: 'pasta' },
});
}
if (!pages.some((p) => p.parentId === folder.id && p.title === today)) {
await paper('/vaults/principal/pages', {
method: 'POST',
body: {
title: today,
parentId: folder.id,
markdown: `## For today\n\n- [ ] \n\n## Notes\n`,
},
});
}Append to a page
paper /vaults/principal/pages/pa1k2m3n4o5p -X PATCH \
-d '{"append": "- [ ] Call the supplier @2026-10-07 10:00"}'Read a whole folder for an AI
def folder_text(vault, folder_id):
parts = []
for p in paper(f"/vaults/{vault}/pages?parent={folder_id}"):
if p["kind"] == "pagina" and not p.get("locked"):
page = paper(f"/vaults/{vault}/pages/{p['id']}")
parts.append(f"# {page['title']}\n\n{page['markdown']}")
return "\n\n---\n\n".join(parts)Folders with many pages spend one request per page. For 60 pages or more, spread the reads over a few minutes.
Create an event from a task
await paper('/calendar/events', {
method: 'POST',
body: { title: 'Call the supplier', date: '2026-10-07', time: '10:00', durationMinutes: 15 },
});Upload an image and put it in a page
RESPONSE=$(curl -sS -X POST "https://wire.ia.br/api/v1/vaults/principal/files?name=chart.png" \
-H "Authorization: Bearer $PAPER_TOKEN" \
-H "X-Paper-Account: $PAPER_ACCOUNT" \
-H "Content-Type: image/png" \
--data-binary @chart.png)
MD=$(echo "$RESPONSE" | jq -r .markdown)
paper /vaults/principal/pages/pa1k2m3n4o5p -X PATCH -d "$(jq -n --arg md "$MD" '{append: $md}')"A tool for an agent (Claude, OpenAI and others)
A tool definition in JSON Schema format, which most models accept:
{
"name": "paper_append",
"description": "Appends Markdown text to the end of a page in the person's Paper notebook.",
"input_schema": {
"type": "object",
"properties": {
"vault": { "type": "string", "description": "Vault id, from GET /vaults" },
"page": { "type": "string", "description": "Page id, from GET /vaults/{vault}/pages" },
"text": { "type": "string", "description": "Markdown to append" }
},
"required": ["vault", "page", "text"]
}
}When executing, call PATCH /vaults/{vault}/pages/{page} with {"append": text}.