API access
Read-only access for a bot or any outside system. One token per workspace. Call these addresses on findnotes.app.
Tokens
Owners and admins of a Team workspace issue the token from Settings. Billing-exempt workspaces can issue one too. Trials, past-due workspaces, and every other plan cannot. The secret is shown once and only its SHA-256 hash is stored. Give it a label. Expiry is 30, 90 (the default), 365 days, or none. None requires an explicit confirmation. Send it as Authorization: Bearer <token>.
If the workspace loses Team access, the token stops working on the next request and is marked suspended. Restoring access within 30 days turns it back on. After 30 days suspended, it is revoked. It is also revoked if the person who created it is demoted or leaves.
What a token can read
The same articles a normal reader of that workspace can open, except drafts, deleted articles, restricted articles (any permission row), articles marked Hide from API access, and articles on the workspace exclusion list. Attachments of a visible article are included. Convex files are downloaded through the API. Google Drive files are returned as the stored link.
Each article includes author: { "id", "name" } or null. The name is the person's display name only. It is null when the author is missing or the user was deleted. Email is never included.
REST
GET https://findnotes.app/api/v1/articles?limit=20&cursor=
GET https://findnotes.app/api/v1/articles/{id}
GET https://findnotes.app/api/v1/attachments/{id}limit defaults to 20. Values from 1 to 50 are accepted. Anything else is 400. List items include a 200-character preview and no body. nextCursor is null on the last page. A successful JSON response sends an ETag. Repeat the request with If-None-Match to get 304 when nothing changed. Article bodies over 200KB are refused. Convex attachments over 10 MB are refused. The file response uses the attachment's content type.
MCP
POST https://findnotes.app/mcp speaks Streamable HTTP and JSON-RPC 2.0. GET and DELETE return 405. There is no session id. Methods: initialize, notifications/initialized, tools/list, tools/call, and ping. Tools: list_articles, get_article, get_attachment. All three are read-only. Protocol versions 2025-03-26, 2025-06-18, and 2025-11-25 use the initialize handshake. A newer requested version is answered with 2025-11-25. A request that sends an Origin header is rejected with 403. TheAccept header must include both application/json and text/event-stream.
Caps
- 30 requests per minute per token, with a burst of 10
- 60 requests per minute per workspace
- 120 requests per minute across FindNotes
- 2,000 requests and 50 MB per token per UTC day
- 5,000 requests and 100 MB per workspace per UTC day
- 20,000 requests per UTC day across FindNotes
A capped request returns 429 with Retry-After (seconds) and a JSON body { error: "rate_limited", limit, retryAfter }. The same caps apply to /mcp.
Errors
- 401
unauthorized, withWWW-Authenticate: Bearer. Missing, unknown, revoked, suspended, and expired tokens all look the same. - 404
not_found. Hidden, restricted, draft, deleted, excluded, other-workspace, and missing articles look the same. - 400
bad_requestfor a bad limit or cursor. - 413
payload_too_largewhen a body or attachment is over its cap. - 429
rate_limitedwithRetry-After. - 500
internal_error.
On /mcp, a bad token is still HTTP 401 and a rate limit is still HTTP 429. A not-found article, a bad tool argument, or a size cap is HTTP 200 with a tool result isError: true. Unknown methods are JSON-RPC -32601. A request with an Origin header is HTTP 403.
Availability
API access is available to Team workspaces. Owners and admins issue a token from Settings and call the REST and MCP addresses above. Billing-exempt workspaces can use it too. Trials, past-due workspaces, and every other plan cannot.
In production, API_ACCESS_ENABLED is the string true, so those addresses answer requests. Setting that Convex deployment variable to any other value, or leaving it unset, turns both the REST routes and /mcp off. A call then returns 503 { "error": "disabled", "message": "API access is disabled" }. The MCP form is the same error inside a JSON-RPC body. Tokens, the settings screen, and these docs stay up. Requests are not served.