API reference
A REST API shaped like Notion's, signed webhooks and an MCP server. They need the Pro or Business plan (or an unlimited workspace) and a personal API key from Settings → API & webhooks.
Authentication
Send your key as a bearer token. A key acts as you : it sees and changes only the pages you can.
curl https://carnetio.slimbennasrallah.com/api/v1/users/me \
-H "Authorization: Bearer car_…"Errors are { "error": "…" } with an HTTP status. Rich text is a plain string; page bodies are Markdown (markdown) or ProseMirror JSON (children).
REST endpoints
| Method | Path | Notes |
|---|---|---|
GET | /api/v1/users/me | You and the workspace |
GET | /api/v1/users | Members |
POST | /api/v1/search | { query, filter: { value: page | database }, page_size } |
GET | /api/v1/pages/:id | A page with its properties |
GET | /api/v1/pages/:id/markdown | The body as Markdown |
GET | /api/v1/pages/:id/children | Sub-pages |
POST | /api/v1/pages | { parent: { page_id | database_id | teamspace_id }, title, icon, properties, markdown } |
PATCH | /api/v1/pages/:id | title, icon, cover, properties, markdown (replaces the body), in_trash |
DELETE | /api/v1/pages/:id | Moves to trash |
GET / PATCH | /api/v1/blocks/:id/children | Read the body's blocks / append markdown or children |
GET | /api/v1/databases/:id | Properties and views |
POST | /api/v1/databases | { parent: { page_id }, title, is_inline } |
POST | /api/v1/databases/:id/query | { filter, sorts, page_size, start_cursor, view_id } |
POST / PATCH / DELETE | /api/v1/databases/:id/properties[/:propertyId] | Add, change, delete a property |
GET / POST | /api/v1/comments | ?page_id= / { parent: { page_id }, markdown, discussion_id } |
POST | /api/v1/ops | { op, args } : any operation the app uses (page.update, schema.update, view.upsert…) |
Rows and properties
Set properties by name with friendly values : option names (a new select option is created on the fly), people by email or name, relations as page ids, dates as ISO strings or { start, end }.
curl -X POST $BASE/pages -H "Authorization: Bearer $KEY" -H "content-type: application/json" -d '{
"parent": { "database_id": "c…" },
"properties": { "Name": "Fix the login page", "Status": "In progress",
"Assignee": "alex@acme.test", "Due": "2026-11-20", "Tags": ["web"] }
}'Formulas and rollups come back computed : { "type": "number", "value": 3, "text": "3" }. Query with property ids and operators like equals, contains, is_within (next_week, past_month…), is_checked.
MCP server
Streamable HTTP at /api/mcp. Tools : search, fetch (a page as Markdown, or a database with its rows), create_pages, update_page, move_pages, duplicate_page, create_database, update_database_schema, query_database, get_comments, create_comment, get_users, get_teamspaces, list_pages, whoami.
claude mcp add --transport http carnetio https://carnetio.slimbennasrallah.com/api/mcp \
--header "Authorization: Bearer car_…"Webhooks
Admins add webhooks in Settings → API & webhooks. Events : page.created, page.updated, page.deleted, comment.created. Failed deliveries retry five times with backoff.
Verify each request : the carnetio-signature header is the hex HMAC-SHA256 of the raw body with the webhook secret.
const sig = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
if (sig !== req.headers["carnetio-signature"]) throw new Error("bad signature");