Documentation
Webhooks
Have Folevi tell your server when notes, tasks and comments change, with signed requests you can verify.
Updated
A webhook is an address on your server that Folevi calls when something happens in your notes: a note is created, changed or moved to Trash, a task is added or completed, a comment is written. It’s how Zapier, n8n, Make and your own code hear about changes without asking over and over. To read or add things, use the REST API.
Add a webhook
Open Settings → Connected apps and choose Add webhook under Webhooks. Enter an address that starts with https://, choose the events and the places (your Personal, and any workspaces you pick), then copy the signing secret. It starts with whsec_ and is shown only once. You can have up to five webhooks. Send test event sends a webhook.test event to check your setup, and Recent deliveries shows the last 20 attempts with their status codes.
| Event | When it’s sent |
|---|---|
| note.created | A note is created. Sent about 30 seconds later, so the title typed right after is included. |
| note.updated | A note’s text or title changes. At most once a minute per note: edits in that minute are one event. |
| note.deleted | A note is moved to Trash. |
| task.created | A to-do is added to a note. |
| task.completed | A to-do is checked off. |
| comment.created | A comment or a reply is written. |
You only get events for notes you can open yourself, in the places you chose. A page restricted to other people sends you nothing.
What Folevi sends
Each event is a POST with a JSON body. Payloads are small on purpose: a note’s title and link, never its content. Tasks include their text, since that’s what a task is. Comments include ids and the note’s link, not what was written. Fetch more through the REST API if you need it.
{
"id": "evt_01JA2Z6Q3M8V4C2P9K7T5R1B0N",
"type": "task.completed",
"createdAt": "2026-10-14T09:12:44.000Z",
"place": { "id": "personal", "name": "Personal" },
"data": {
"id": "01JA2Z5X1T9QH3E8D2W6M4R7AA",
"text": "Send the summary",
"status": "done",
"dueDate": "2026-10-15",
"dueTime": null,
"priority": "high",
"note": { "id": "01JA2YQ8...", "title": "Meeting notes", "url": "https://app.folevi.com/d/01JA2YQ8..." },
"url": "https://app.folevi.com/d/01JA2YQ8...#block-01JA2Z5X..."
}
}Requests also carry Folevi-Event-Id and Folevi-Event-Type headers. The event id stays the same on every retry, so use it to ignore an event you’ve already handled.
Check the signature
Every request has a Folevi-Signature header like t=1792234364,v1=5257a8…. t is when it was sent (Unix seconds) and v1 is the HMAC-SHA256, in hex, of t, a full stop and the raw request body, keyed with your signing secret. Compute it yourself and compare, and turn away requests whose t is more than five minutes old. In Node:
import crypto from "node:crypto";
import express from "express";
const secret = process.env.FOLEVI_WEBHOOK_SECRET; // whsec_...
const app = express();
// Read the body raw: the signature covers the exact bytes Folevi sent.
app.post("/folevi", express.raw({ type: "application/json" }), (req, res) => {
const parts = Object.fromEntries((req.get("Folevi-Signature") ?? "").split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${req.body}`).digest("hex");
const valid = typeof parts.v1 === "string" && parts.v1.length === expected.length && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
const recent = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
if (!valid || !recent) return res.status(400).send("Bad signature");
const event = JSON.parse(req.body);
console.log(event.type, event.data.id);
res.sendStatus(200);
});
app.listen(3000);Answers, retries and turning off
Answer with any 2xx status within 10 seconds. Anything else counts as a failure, and so do redirects: Folevi never follows them. A failed event is tried again after 1 minute, 10 minutes, 1 hour, 6 hours and 16 hours, six attempts over about a day.
If three events in a row fail every attempt, Folevi turns the webhook off and tells you in the notifications bell. Fix the endpoint, then switch it back on in Settings. A test event never counts toward this.
Security
- Only https addresses on the standard port are accepted, without a user name or password in them.
- Folevi looks up the address before every attempt and never sends to private, local or link-local networks.
- Your signing secret is stored encrypted and shown only when you add the webhook. If it leaks, delete the webhook and add it again.
- Folevi doesn’t read or keep your server’s answer, only its status code and how long it took.
Still stuck? Contact support or write to support@folevi.com.
