API Documentation
Use the Foxdrop REST API to manage requests, clients, and templates programmatically. API access requires a Pro or Team plan.
Authentication
All API requests must include a valid API key in the Authorization header. You can create API keys from Settings > API in your dashboard.
curl -H "Authorization: Bearer fd_live_abc123..." \
https://app.foxdrop.com/api/v1/requestsAPI keys use the prefix fd_live_ followed by 32 hex characters. Keep your keys secret — they grant full access to your organization's data.
Endpoints
Requests
/api/v1/requestsList all requests (paginated). Filter by status with ?status=active
/api/v1/requestsCreate a new request with items
/api/v1/requests/:idGet a request with its items
/api/v1/requests/:idUpdate a request (title, due_date, status)
/api/v1/requests/:idArchive a request (soft delete)
Create request example:
curl -X POST https://app.foxdrop.com/api/v1/requests \
-H "Authorization: Bearer fd_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"title": "Tax Documents 2025",
"client_id": "uuid-here",
"due_date": "2025-04-15",
"items": [
{ "label": "W-2 Form", "required": true },
{ "label": "1099 Forms", "required": false },
{ "label": "Photo ID", "required": true }
]
}'Response:
{
"data": {
"id": "uuid",
"title": "Tax Documents 2025",
"status": "active",
"portal_url": "https://app.foxdrop.com/p/abc123",
"due_date": "2025-04-15",
"created_at": "2025-03-17T12:00:00Z",
...
}
}Clients
/api/v1/clientsList all clients (paginated, searchable via ?search=)
/api/v1/clientsCreate a new client
/api/v1/clients/:idGet a client with request summary
/api/v1/clients/:idUpdate a client
/api/v1/clients/:idDelete a client (blocked if active requests exist)
Templates
/api/v1/templatesList all templates (paginated)
/api/v1/templatesCreate a new template with items
Pagination
All list endpoints support pagination via query parameters:
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number |
per_page | 20 | Items per page (max 100) |
Paginated responses include a meta object:
{
"data": [...],
"meta": {
"total": 42,
"page": 1,
"per_page": 20,
"total_pages": 3
}
}Errors
Errors follow a consistent format with an error code and message:
{
"error": {
"code": "validation_error",
"message": "Request title is required"
}
}| Code | Status | Description |
|---|---|---|
unauthorized | 401 | Invalid or missing API key |
plan_required | 403 | Feature requires Pro+ plan |
plan_limit | 403 | Plan limit reached |
not_found | 404 | Resource not found |
validation_error | 422 | Invalid request body |
rate_limit_exceeded | 429 | Too many requests |
duplicate | 409 | Resource already exists |
Webhooks
Configure webhooks in Settings > Webhooks to receive real-time notifications when events occur. Webhooks use HTTPS POST with JSON payloads.
Event Types
| Event | Description |
|---|---|
request.created | A new request was created |
request.completed | All items in a request are submitted/approved |
request.archived | A request was archived |
file.uploaded | A client uploaded a file |
item.approved | An item was approved |
item.rejected | An item was rejected |
Payload Format
{
"event": "request.created",
"payload": {
"request_id": "uuid",
"title": "Tax Documents 2025",
"client_id": "uuid",
"portal_url": "https://app.foxdrop.com/p/abc123"
},
"delivered_at": "2025-03-17T12:00:00Z"
}Signature Verification
Every webhook includes an X-Foxdrop-Signature header containing an HMAC-SHA256 hex digest of the request body, signed with your webhook secret. Verify this signature to ensure the request came from Foxdrop.
Verification example (Node.js):
import crypto from "crypto";
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Headers
| Header | Description |
|---|---|
X-Foxdrop-Signature | HMAC-SHA256 hex digest |
X-Foxdrop-Event | Event type (e.g., request.created) |
X-Foxdrop-Delivery | Unique delivery ID (UUID) |
Retry Behavior
Webhooks have a 10-second timeout. If a delivery fails (non-2xx response or timeout), the failure count increments. After 10 consecutive failures, the webhook is automatically disabled. Successful deliveries reset the failure count. You can re-enable disabled webhooks from the settings page.
Rate Limits
API requests are rate-limited per API key:
- 100 requests per minute
- 1,000 requests per hour
Rate limit information is included in response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the rate limit resets |
When you exceed the rate limit, you'll receive a 429 Too Many Requests response.