Create document requests, track uploads, and receive events from your own systems.
Create a request and email the upload link to your client in one call:
curl https://www.filecollect.io/api/v1/requests \
-H "Authorization: Bearer fc_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "2026 Tax Return Documents",
"clientName": "Maria Alvarez",
"clientEmail": "maria@example.com",
"sendInvite": true,
"items": [
{ "label": "Photo ID", "type": "file" },
{ "label": "Prior year tax return", "type": "file" },
{ "label": "Did you sell any property this year?", "type": "question" }
]
}'
Response:
{ "success": true, "id": 42, "slug": "a1b2c3d4e5f6", "url": "https://www.filecollect.io/r/a1b2c3d4e5f6", "driveFolderUrl": "https://drive.google.com/..." }
Every request needs an API key in the Authorization header:
Authorization: Bearer fc_live_...
Keys are shown once at creation and stored hashed. Each key acts on behalf of the workspace that created it: the API sees exactly the same requests, clients, and templates as your dashboard. Keep keys out of client-side code; treat them like passwords. Revoke a key any time from Settings.
Verify a key with GET /api/v1/me, which returns your workspace id, firm name, and plan.
https://www.filecollect.io/api/v1Content-Type: application/json).429 with a Retry-After header.{ "error": "human readable message" } with a conventional status code (400 validation, 401 bad key, 403 plan or permission, 404 not found, 429 throttled).| Endpoint | Description |
|---|---|
GET/requests | List requests. Query params: status (draft, sent, in_progress, complete, closed), limit (max 100, default 50), offset. |
POST/requests | Create a request. See fields below. |
GET/requests/:id | Full request detail: items, answers, uploaded files with Drive file ids. |
PATCH/requests/:id | Update title, dueDate, welcomeMessage, or status (closed to close, in_progress to reopen). |
POST/requests/:id/remind | Send a manual reminder to the client. Throttled to one per request per hour; returns 429 if nudged recently. |
| Field | Type | Notes |
|---|---|---|
title | string | Required. |
clientEmail | string | Finds or creates the client in your workspace. |
clientName | string | Used when creating a new client. |
items | array | Checklist items: { "label", "type": "file" | "question", "description", "required" }. Overrides template items if both are sent. |
templateId | number | Copy items from one of your templates (see GET /templates). |
sendInvite | boolean | When true (and clientEmail is set), emails the upload link immediately and starts the reminder schedule. Otherwise the request stays a draft. |
dueDate | string | ISO date, e.g. 2026-08-15. |
welcomeMessage | string | Shown to the client at the top of the upload page and in the invite email. |
accessCode | string | Clients must enter this code to view and upload. |
reminderCadenceDays | number | 1 to 30. Defaults to your workspace setting. |
| Endpoint | Description |
|---|---|
GET/clients | List clients with request counts. Optional ?email= for an exact-match lookup. |
POST/clients | Create a client: { "name", "email", "phone", "notes" }. Returns 409 with existingId if the email already exists. |
GET/templates | List your templates and the built-in system templates, with item counts. Use a template's id as templateId when creating requests. |
GET/files | Most recent uploads across all requests, newest first. Query param: limit (max 50, default 10). Each entry is shaped like the file.uploaded webhook payload. |
FileCollect POSTs signed JSON events to your endpoints as things happen: files arrive, answers come in, items get approved or rejected, requests complete. Manage endpoints in Settings or via the API:
| Endpoint | Description |
|---|---|
GET/webhooks | List your endpoints and the available event types. |
POST/webhooks | { "url", "events" }. URL must be https. events is optional; omit to receive everything. Returns the signing secret once. |
PATCH/webhooks/:id | { "active": true } re-enables a disabled endpoint and resets its failure counter. |
DELETE/webhooks/:id | Remove the endpoint. |
| Event | Fires when |
|---|---|
request.created | A request is created (dashboard or API). |
file.uploaded | A client uploads a file. data.file.held is true when the file is held by a plan limit. |
answer.submitted | A client answers a question item. |
item.approved | You approve an item. |
item.rejected | You reject an item; data.reason carries the note sent to the client. |
request.completed | Every item is approved or marked not applicable. |
POST your-url
Content-Type: application/json
X-FileCollect-Event: file.uploaded
X-FileCollect-Delivery: 1234
X-FileCollect-Signature: t=1752834000,v1=5f3a...
{
"event": "file.uploaded",
"created": "2026-07-18T10:20:00.000Z",
"data": {
"request": { "id": 42, "slug": "a1b2c3d4e5f6", "title": "2026 Tax Return Documents" },
"item": { "id": 7, "label": "Photo ID" },
"file": { "name": "01_Photo-ID_maria.jpg", "originalName": "IMG_2041.jpg", "size": 2048576, "mimeType": "image/jpeg", "held": false },
"client": { "name": "Maria Alvarez" }
}
}
The signature is an HMAC-SHA256 of <timestamp>.<raw body> using your endpoint's secret:
const crypto = require('crypto');
function verify(secret, signatureHeader, rawBody) {
const parts = Object.fromEntries(signatureHeader.split(',').map(p => p.split('=')));
const expected = crypto.createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
PATCH /webhooks/:id.X-FileCollect-Delivery to deduplicate.The FileCollect Zapier integration gives you the triggers and actions above without writing code: trigger Zaps when files arrive or requests complete, and create requests or clients from other tools. Accept the invite on Zapier, then connect your account with an API key from Settings.
Something missing from the API? Tell us what you are building; integration requests from Firm customers shape the roadmap directly.