Verify it's really us
Recompute the HMAC-SHA256 of the raw request body with your webhook secret and compare it with X-Findest-Signature. If it doesn't match, discard the request. The secret is shown once, when you create the webhook.
A REST endpoint to read what Findest has already filed, and an outbound webhook that fires the moment a document lands in your cloud. No scraping your Drive, no polling: the data comes to you, signed so you can trust it.
Included on every plan, Free too
GET /public-api/documents?limit=.POST on every filed document.Build a request, sign a webhook and check a URL. Everything below runs in your browser: no key is needed and nothing is sent anywhere.
curl -H "Authorization: Bearer fk_live_YOUR_KEY" \ "https://rlarmblikgtxmqlertzg.supabase.co/functions/v1/public-api/documents?limit=50"
X-Findest-Signature
75c206b2f7c8aff1bbaa642f604c66ffe4b1641cb962f7a15628c18218c1393c
Create an API key on the API page of the app, then call the endpoint to get the same records you see in your History: filename, detected type, status and final destination.
| Parameter | Description |
|---|---|
| Authorization | Header. Bearer <your key>. A key only ever returns its own account's documents. |
| limit | Query, optional. How many documents to return, newest first. Default 50, maximum 200. |
{
"documents": [
{
"id": "a1b2c3d4",
"filename": "Invoice_Endesa_2026-03-14.pdf",
"doc_type": "Invoice",
"status": "uploaded",
"destination": { "folder_name": "Invoices 2026" },
"created_at": "2026-03-14T09:12:03Z"
}
]
}
Set a webhook URL once, and every time a document is filed, Findest sends it a signed POST. No need to poll the API on a schedule.
// Header: X-Findest-Signature: <hex HMAC-SHA256 of the raw body> { "event": "document.archived", "data": { "id": "a1b2c3d4", "filename": "Invoice_Endesa_2026-03-14.pdf", "doc_type": "Invoice", "folder_name": "Invoices 2026", "web_link": "https://drive.google.com/file/d/…" }, "sent_at": "2026-03-14T09:12:04Z" }
import crypto from "node:crypto"; function isFromFindest(rawBody, signature, secret) { const expected = crypto .createHmac("sha256", secret) .update(rawBody) .digest("hex"); return signature?.length === expected.length && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); }
Recompute the HMAC-SHA256 of the raw request body with your webhook secret and compare it with X-Findest-Signature. If it doesn't match, discard the request. The secret is shown once, when you create the webhook.
If your endpoint is down or times out, the filing itself still succeeds. The webhook isn't retried yet, so treat it as a notification and the API as the source of truth.
The URL must be https:// on port 443 and resolve to a public host. Redirects aren't followed and each call times out after 10 seconds.
In the app, on the API page in the sidebar. The raw key is shown once, when you create it: Findest only stores its hash, so copy it before closing the dialog.
GET /public-api/documents returns at most 200 records per request (50 by default, set with ?limit=). There's no hard per-minute limit yet, but treat it as a read endpoint for your own integrations, not a public API for third parties.
Not yet. Today the public API is read-only (documents) plus the outbound webhook. Rules, connections and teams are managed from the app itself.
No, delivery is best-effort and single-attempt for now. Use the API to backfill anything you might have missed instead of relying on the webhook alone.
Recompute the HMAC-SHA256 of the raw request body with your webhook secret and compare it with the X-Findest-Signature header. The secret is shown once, when you create the webhook.