API & MCP Reference
Everything you need to integrate with Intake — via REST API or MCP.
Base URL:
https://dointake.com/api/v1
Introduction
Intake offers two integration paths: a REST API and an MCP server (Model Context Protocol). Both provide full access to clients, document requests, forms, and webhooks.
REST API Base URL: https://dointake.com/api/v1
MCP Server: Connect any MCP-compatible client (Claude, Cursor, etc.) — see the MCP Protocol section for setup.
All REST requests and responses use JSON. Timestamps are returned in ISO 8601 format. All resource IDs are opaque strings.
Authentication
Authenticate by including your API key in the Authorization header as a Bearer token.
API keys are created under Avatar menu → Settings → API Keys. Each key has scopes that control access:
| Scope | Access |
|---|---|
read | List and retrieve resources |
write | Create and update resources |
webhooks | Manage webhook subscriptions |
Rate limiting: 120 requests per minute per API key. When exceeded, the API returns 429 with a Retry-After header.
/api/v1/me
Test your API key
Returns information about the authenticated user.
curl https://dointake.com/api/v1/me \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": 1,
"name": "Your Name",
"email": "you@example.com",
"subscription_status": "active"
}
}
Errors
The API uses standard HTTP status codes. Errors return a JSON object with an error key containing code and message fields.
| Status | Meaning |
|---|---|
200 | Success |
201 | Created |
204 | Deleted (no content) |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — insufficient scope or plan limit exceeded |
404 | Not found |
422 | Validation error |
429 | Rate limited |
500 | Internal server error |
/api/v1/...
Error response format
All errors follow this structure. Validation errors include a `details` object mapping field names to error messages.
{
"error": {
"code": "validation_error",
"message": "Validation failed",
"details": {
"email": [
"can't be blank"
]
}
}
}
Pagination
List endpoints return all matching records. Use query parameters to filter results:
- Clients:
?search=termto filter by name or email - Requests:
?status=pending&client_id=xxx&deal_id=xxx - Deals:
?status=active
Clients
Manage your clients. Clients are the people you collect documents from.
/api/v1/clients
List clients
Returns all clients for your account. Optionally filter by search term.
| Parameter | Type | Required | Description |
|---|---|---|---|
search |
string | optional | Filter by name or email |
curl https://dointake.com/api/v1/clients?search=jane \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com",
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"phone": "+1234567890"
}
]
}
/api/v1/clients/:id
Get a client
Retrieve a single client by their ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Client ID |
curl https://dointake.com/api/v1/clients/cl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com",
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"phone": "+1234567890"
}
}
/api/v1/clients
Create a client
Create a new client.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | required | Client's full name |
email |
string | required | Client's email address |
phone |
string | optional | Client's phone number |
curl -X POST https://dointake.com/api/v1/clients \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Jane Smith", "email": "jane@example.com"}'
{
"data": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com",
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"phone": null
}
}
Requests
Document requests are sent to clients to collect files and information. Each request has a checklist of items and collects uploads from the client.
/api/v1/requests
List requests
Returns all document requests. Filter by status, client, or deal.
| Parameter | Type | Required | Description |
|---|---|---|---|
status |
string | optional | Filter by status (e.g. pending, sent, complete) |
client_id |
string | optional | Filter by client ID |
deal_id |
string | optional | Filter by deal ID |
curl "https://dointake.com/api/v1/requests?status=sent" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "req_xyz789",
"status": "sent",
"title": "Tax Documents 2025",
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"sent_at": "2025-01-20T09:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"due_date": "2025-04-15",
"item_count": 5
}
]
}
/api/v1/requests/:id
Get a request
Retrieve a single request with its checklist items.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "req_xyz789",
"status": "sent",
"description": "Please upload your tax documents",
"title": "Tax Documents 2025",
"forms": [
{
"id": "sub_abc123",
"name": "Client Intake Form",
"status": "completed",
"completed_at": "2025-01-20T14:30:00Z",
"submitted_ip": "203.0.113.42",
"responses": [
{
"label": "Full Name",
"type": "text",
"value": "Jane Smith",
"field_id": "field_1"
},
{
"label": "Signature",
"signed": true,
"type": "signature",
"value": null,
"field_id": "field_2"
}
]
}
],
"items": [
{
"id": "item_001",
"name": "W-2 Form",
"position": 0,
"status": "pending",
"description": "From your employer",
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"upload_count": 0
}
],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"sent_at": "2025-01-20T09:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"due_date": "2025-04-15",
"deal_id": null,
"max_reminders": 10,
"notify_professional_after_days": 7,
"reminder_count": 3,
"item_count": 1,
"last_reminder_at": "2025-02-10T09:00:00Z",
"next_reminder_at": "2025-02-12",
"pdf_forms": [
{
"id": "pfr_abc123",
"status": "completed",
"completed_at": "2025-01-20T15:00:00Z",
"template_name": "Engagement Letter",
"download_url": "https://dointake.com/downloads/tok_xyz789"
}
]
}
}
/api/v1/requests
Create a request
Create a new document request for a client. Optionally include checklist items.
| Parameter | Type | Required | Description |
|---|---|---|---|
client_id |
string | required | Client ID to send the request to |
title |
string | required | Request title |
description |
string | optional | Description or instructions |
due_date |
string | optional | Due date (YYYY-MM-DD) |
items |
array | optional | Array of checklist items to create |
curl -X POST https://dointake.com/api/v1/requests \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"client_id": "cl_abc123", "title": "Tax Documents", "items": [{"name": "W-2 Form"}]}'
{
"data": {
"id": "req_xyz789",
"status": "pending",
"description": null,
"title": "Tax Documents",
"items": [
{
"id": "item_001",
"name": "W-2 Form",
"position": 0,
"status": "pending",
"description": null,
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"upload_count": 0
}
],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"sent_at": null,
"created_at": "2025-01-15T10:30:00Z",
"due_date": null,
"deal_id": null,
"item_count": 1
}
}
/api/v1/requests/:id
Update a request
Update an existing document request.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Request ID |
title |
string | optional | Request title |
description |
string | optional | Description or instructions |
due_date |
string | optional | Due date (YYYY-MM-DD) |
reminder_enabled |
boolean | optional | Enable email reminders |
reminder_frequency_days |
integer | optional | Days between reminders (1–30) |
max_reminders |
integer | optional | Max reminders to send (1–100, null for unlimited) |
notify_professional_after_days |
integer | optional | Notify professional if no response after N days (1–90, null to disable) |
curl -X PATCH https://dointake.com/api/v1/requests/req_xyz789 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title"}'
{
"data": {
"id": "req_xyz789",
"status": "sent",
"description": null,
"title": "Updated Title",
"items": [],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"sent_at": "2025-01-20T09:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"due_date": "2025-04-15",
"deal_id": null,
"item_count": 0
}
}
/api/v1/requests/:id/send
Send a request
Send a draft request to the client via email. Changes status from draft to sent.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Request ID |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/send \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "req_xyz789",
"status": "sent",
"title": "Tax Documents",
"items": [],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"sent_at": "2025-01-20T09:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"deal_id": null,
"item_count": 0
}
}
/api/v1/requests/:id/complete
Complete a request
Mark a document request as complete.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Request ID |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/complete \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "req_xyz789",
"status": "complete",
"title": "Tax Documents",
"items": [],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": "2025-02-01T14:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"deal_id": null,
"item_count": 0
}
}
/api/v1/requests/:id/reopen
Reopen a request
Reopen a completed document request.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Request ID |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/reopen \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "req_xyz789",
"status": "sent",
"title": "Tax Documents",
"items": [],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"completed_at": null,
"created_at": "2025-01-15T10:30:00Z",
"deal_id": null,
"item_count": 0
}
}
/api/v1/requests/:request_id/reminders
List reminders
Returns the reminder audit trail for a request. Shows when each reminder was sent, to whom, and which items were pending.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789/reminders \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"sent_at": "2025-02-01T09:00:00Z",
"urgency": "friendly",
"pending_items": [
"W-2 Form",
"1099 Form"
],
"recipient_email": "jane@example.com",
"recipient_type": "client"
},
{
"sent_at": "2025-02-04T09:00:00Z",
"urgency": "urgent",
"pending_items": [
"W-2 Form"
],
"recipient_email": "jane@example.com",
"recipient_type": "client"
},
{
"sent_at": "2025-02-08T09:00:00Z",
"urgency": "overdue",
"pending_items": [],
"recipient_email": "pro@example.com",
"recipient_type": "professional"
}
]
}
Checklist Items
Checklist items are individual documents or pieces of information requested within a document request.
/api/v1/requests/:request_id/items
List checklist items
Returns all checklist items for a given request.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789/items \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "item_001",
"name": "W-2 Form",
"position": 0,
"status": "pending",
"description": "From your employer",
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"review_note": null,
"review_status": null,
"upload_count": 0
}
]
}
/api/v1/requests/:request_id/items
Create a checklist item
Add a new checklist item to a request.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
name |
string | required | Item name |
description |
string | optional | Instructions for the client |
required |
boolean | optional | Whether this item is required (default: true) |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/items \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "W-2 Form", "description": "From your employer"}'
{
"data": {
"id": "item_002",
"name": "W-2 Form",
"position": 1,
"status": "pending",
"description": "From your employer",
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"review_note": null,
"review_status": null,
"upload_count": 0
}
}
/api/v1/items/:id
Update item review status
Set the review status and optional note on a checklist item. Only works when the item's status is "received". Review status values are validated against the user's configured list (defaults: in_review, approved, rejected).
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Item ID |
review_status |
string | required | Review status (user-configured, defaults: in_review, approved, rejected) |
review_note |
string | optional | Optional note (e.g. reason for rejection) |
curl -X PATCH https://dointake.com/api/v1/items/itm_abc123 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"review_status": "in_review"}'
{
"data": {
"id": "itm_abc123",
"name": "W-2 Form",
"position": 0,
"status": "received",
"description": "From your employer",
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"review_note": null,
"review_status": "in_review",
"upload_count": 1
}
}
/api/v1/items/:id/re-request
Re-request item
Re-request a checklist item. Resets status to pending, clears review_status and review_note. Previous uploads are preserved for reference.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Item ID |
curl -X POST https://dointake.com/api/v1/items/itm_abc123/re-request \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "itm_abc123",
"name": "W-2 Form",
"position": 0,
"status": "pending",
"description": "From your employer",
"required": true,
"created_at": "2025-01-15T10:30:00Z",
"review_note": null,
"review_status": null,
"upload_count": 1
}
}
Uploads
Uploads are files submitted by clients in response to document requests. Uploads are read-only via the API.
/api/v1/requests/:request_id/uploads
List uploads
Returns all uploads for a given request.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789/uploads \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "upl_001",
"status": "processed",
"file_size": 245000,
"content_type": "application/pdf",
"created_at": "2025-01-20T14:30:00Z",
"original_filename": "w2-2025.pdf",
"ai_classification": "W-2",
"ai_confidence": 0.97,
"submitted_ip": "203.0.113.42",
"item_id": "item_001"
}
]
}
Form Templates
Form templates define reusable sets of fields that can be attached to requests. When attached, the template's fields are snapshotted so future edits don't affect existing requests.
/api/v1/form-templates
List form templates
Returns all form templates for your account.
curl https://dointake.com/api/v1/form-templates \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "tmpl_abc123",
"name": "Client Intake",
"description": "Basic client information form",
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z",
"field_count": 5
}
]
}
/api/v1/form-templates/:id
Get a form template
Retrieve a form template with all its field definitions.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Template ID |
curl https://dointake.com/api/v1/form-templates/tmpl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "tmpl_abc123",
"name": "Client Intake",
"description": "Basic client information form",
"fields": [
{
"id": 1,
"label": "Full Legal Name",
"position": 0,
"type": "text",
"config": {
"validation": "none"
},
"description": null,
"required": true
},
{
"id": 2,
"label": "Email Address",
"position": 1,
"type": "email",
"config": {
"validation": "email"
},
"description": null,
"required": true
},
{
"id": 3,
"label": "Filing Status",
"position": 2,
"type": "select",
"config": {
"options": [
"Single",
"Married",
"Head of Household"
]
},
"description": "Select your tax filing status",
"required": true
}
],
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z"
}
}
/api/v1/form-templates
Create a form template
Create a new form template, optionally with fields in one call. Field types: text, textarea, number, date, email, phone, select, radio, checkbox, signature. Fields with options (select, radio, checkbox) need config.options.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | required | Template name |
description |
string | optional | Template description |
fields |
array | optional | List of field objects with type, label, required, description, config |
curl -X POST https://dointake.com/api/v1/form-templates \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Client Intake", "fields": [{"type": "text", "label": "Full Name", "required": true}, {"type": "email", "label": "Email", "config": {"validation": "email"}}]}'
{
"data": {
"id": "tmpl_abc123",
"name": "Client Intake",
"description": null,
"fields": [
{
"id": 1,
"label": "Full Name",
"position": 0,
"type": "text",
"config": {
"validation": "none"
},
"description": null,
"required": true
},
{
"id": 2,
"label": "Email",
"position": 1,
"type": "email",
"config": {
"validation": "email"
},
"description": null,
"required": false
}
],
"updated_at": "2025-01-15T10:30:00Z",
"created_at": "2025-01-15T10:30:00Z"
}
}
/api/v1/form-templates/:id
Delete a form template
Delete a form template. Returns 409 if the template is attached to any requests.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Template ID |
curl -X DELETE https://dointake.com/api/v1/form-templates/tmpl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
204 No Content
/api/v1/form-templates/:form_template_id/fields
Add a field
Add a field to an existing form template. The field is appended to the end.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_template_id |
string | required | Template ID |
type |
string | required | Field type: text, textarea, number, date, email, phone, select, radio, checkbox, signature |
label |
string | required | Field label |
description |
string | optional | Help text |
required |
boolean | optional | Whether field is required (default: false) |
config |
object | optional | Field config — options for select/radio/checkbox, validation rule |
curl -X POST https://dointake.com/api/v1/form-templates/tmpl_abc123/fields \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "select", "label": "State", "config": {"options": ["CA", "NY", "TX"]}}'
{
"data": {
"id": 4,
"label": "State",
"position": 3,
"type": "select",
"config": {
"options": [
"CA",
"NY",
"TX"
]
},
"description": null,
"required": false
}
}
/api/v1/form-templates/:form_template_id/fields/:id
Update a field
Update a field on a form template.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_template_id |
string | required | Template ID |
id |
integer | required | Field ID |
label |
string | optional | Updated label |
required |
boolean | optional | Updated required flag |
config |
object | optional | Updated config |
curl -X PATCH https://dointake.com/api/v1/form-templates/tmpl_abc123/fields/4 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "Updated Label", "required": true}'
{
"data": {
"id": 4,
"label": "Updated Label",
"position": 3,
"type": "select",
"config": {
"options": [
"CA",
"NY",
"TX"
]
},
"description": null,
"required": true
}
}
/api/v1/form-templates/:form_template_id/fields/:id
Delete a field
Remove a field from a form template.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_template_id |
string | required | Template ID |
id |
integer | required | Field ID |
curl -X DELETE https://dointake.com/api/v1/form-templates/tmpl_abc123/fields/4 \
-H "Authorization: Bearer YOUR_API_KEY"
204 No Content
Request Forms
Attach form templates or inline forms to requests. Clients fill them out in the portal alongside document uploads.
/api/v1/requests/:request_id/forms
Attach a form
Attach a saved template or create an inline form on a request. To attach a template, send template_id. For an inline form, send name and fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
template_id |
string | optional | Template ID (for saved templates) |
name |
string | optional | Form name (for inline forms) |
fields |
array | optional | Field definitions (for inline forms) |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/forms \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template_id": "tmpl_abc123"}'
{
"data": {
"id": "sub_def456",
"fields": [
{
"id": "1",
"label": "Full Name",
"position": 0,
"type": "text",
"config": {},
"required": true
},
{
"id": "2",
"label": "Email",
"position": 1,
"type": "email",
"config": {
"validation": "email"
},
"required": true
}
],
"completed": false,
"completed_at": null,
"template_name": "Client Intake",
"created_at": "2025-01-20T09:00:00Z"
}
}
/api/v1/requests/:request_id/forms
List attached forms
List all forms attached to a request. Completed forms include responses.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789/forms \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "sub_def456",
"fields": [
{
"id": "1",
"label": "Full Name",
"position": 0,
"type": "text",
"config": {},
"required": true
}
],
"completed": true,
"completed_at": "2025-01-21T15:00:00Z",
"template_name": "Client Intake",
"created_at": "2025-01-20T09:00:00Z",
"responses": [
{
"label": "Full Name",
"type": "text",
"value": "Jane Smith",
"field_id": "1"
}
]
}
]
}
/api/v1/requests/:request_id/forms/:id
Detach a form
Remove an attached form from a request. Also deletes any responses.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
id |
string | required | Request form ID (sub_xxx) |
curl -X DELETE https://dointake.com/api/v1/requests/req_xyz789/forms/sub_def456 \
-H "Authorization: Bearer YOUR_API_KEY"
204 No Content
PDF Templates
Upload and manage form-fillable PDF templates. Uploaded PDFs are analyzed for native AcroForm fields. You can also place custom fields via the editor UI.
/api/v1/pdf-templates
List PDF templates
List all PDF templates for the authenticated user.
curl https://dointake.com/api/v1/pdf-templates \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "ptl_abc123",
"name": "W-9 Form",
"filename": "w9.pdf",
"file_size": 85432,
"created_at": "2025-02-01T10:00:00Z",
"page_count": 1,
"has_native_fields": true,
"custom_field_count": 0,
"native_field_count": 12
}
]
}
/api/v1/pdf-templates/:id
Get a PDF template
Get a PDF template with field definitions and an editor URL for the placement UI.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Template ID (ptl_xxx) |
curl https://dointake.com/api/v1/pdf-templates/ptl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "ptl_abc123",
"name": "W-9 Form",
"filename": "w9.pdf",
"file_size": 85432,
"content_type": "application/pdf",
"created_at": "2025-02-01T10:00:00Z",
"page_count": 1,
"has_native_fields": true,
"native_field_definitions": [
{
"name": "topmostSubform[0].Page1[0].f1_1[0]",
"type": "Text"
}
],
"custom_field_definitions": [],
"editor_url": "https://dointake.com/dashboard/pdf-templates/ptl_abc123"
}
}
/api/v1/pdf-templates
Upload a PDF template
Upload a PDF file as a new template. Use multipart/form-data with a 'file' field. The PDF is analyzed for page count and native form fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
file | required | PDF file (multipart upload) |
curl -X POST https://dointake.com/api/v1/pdf-templates \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@w9.pdf"
{
"data": {
"id": "ptl_def456",
"name": "w9",
"filename": "w9.pdf",
"file_size": 85432,
"content_type": "application/pdf",
"created_at": "2025-02-01T10:00:00Z",
"page_count": 1,
"has_native_fields": true,
"native_field_definitions": [
{
"name": "topmostSubform[0].Page1[0].f1_1[0]",
"type": "Text"
}
],
"custom_field_definitions": [],
"editor_url": "https://dointake.com/dashboard/pdf-templates/ptl_def456"
}
}
/api/v1/pdf-templates/:id
Delete a PDF template
Delete a PDF template. Returns 409 if the template is attached to any requests.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Template ID (ptl_xxx) |
curl -X DELETE https://dointake.com/api/v1/pdf-templates/ptl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
204 No Content
PDF Fill Requests
Attach PDF templates to requests as fill requests. Clients fill in the PDF fields in the portal and the completed PDF is stored as an upload.
/api/v1/requests/:request_id/pdf-fills
Attach a PDF fill request
Attach a PDF template to a request. The client will be prompted to fill in the PDF fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
pdf_template_id |
string | required | PDF template ID (ptl_xxx) |
curl -X POST https://dointake.com/api/v1/requests/req_xyz789/pdf-fills \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"pdf_template_id": "ptl_abc123"}'
{
"data": {
"id": "pfr_ghi789",
"status": "pending",
"completed_at": null,
"template_id": "ptl_abc123",
"template_name": "W-9 Form",
"created_at": "2025-02-01T12:00:00Z",
"has_native_fields": true
}
}
/api/v1/requests/:request_id/pdf-fills
List PDF fill requests
List all PDF fill requests for a given request.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
curl https://dointake.com/api/v1/requests/req_xyz789/pdf-fills \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "pfr_ghi789",
"status": "completed",
"completed_at": "2025-02-02T09:30:00Z",
"template_id": "ptl_abc123",
"template_name": "W-9 Form",
"created_at": "2025-02-01T12:00:00Z",
"has_native_fields": true
}
]
}
/api/v1/requests/:request_id/pdf-fills/:id
Delete a PDF fill request
Remove a PDF fill request from a request.
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id |
string | required | Request ID |
id |
string | required | Fill request ID (pfr_xxx) |
curl -X DELETE https://dointake.com/api/v1/requests/req_xyz789/pdf-fills/pfr_ghi789 \
-H "Authorization: Bearer YOUR_API_KEY"
204 No Content
Deals
Deals represent multi-party transactions (e.g. real estate closings, loan applications). Each deal has parties, and each party can have associated document requests.
/api/v1/deals
List deals
Returns all deals. Optionally filter by status.
| Parameter | Type | Required | Description |
|---|---|---|---|
status |
string | optional | Filter by status (e.g. active, closed) |
curl https://dointake.com/api/v1/deals \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "deal_001",
"name": "123 Main St Closing",
"status": "active",
"created_at": "2025-01-15T10:30:00Z",
"party_count": 3
}
]
}
/api/v1/deals/:id
Get a deal
Retrieve a deal with all parties and their requests.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Deal ID |
curl https://dointake.com/api/v1/deals/deal_001 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "deal_001",
"name": "123 Main St Closing",
"status": "active",
"description": "Residential purchase",
"created_at": "2025-01-15T10:30:00Z",
"parties": [
{
"id": "pty_001",
"position": 0,
"requests": [
{
"id": "req_xyz789",
"status": "sent",
"title": "Buyer Documents",
"item_count": 5
}
],
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"role": "Buyer",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [],
"delegate_to_id": null
}
],
"party_count": 1
}
}
/api/v1/deals
Create a deal
Create a new deal. Optionally create from a deal template by passing `template_id`.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | required | Deal name |
description |
string | optional | Deal description |
template_id |
string | optional | Create from a deal template |
curl -X POST https://dointake.com/api/v1/deals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "123 Main St Closing"}'
{
"data": {
"id": "deal_002",
"name": "123 Main St Closing",
"status": "active",
"description": null,
"created_at": "2025-01-15T10:30:00Z",
"parties": [],
"party_count": 0
}
}
/api/v1/deals/:id
Update a deal
Update an existing deal.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Deal ID |
name |
string | optional | Deal name |
description |
string | optional | Deal description |
curl -X PATCH https://dointake.com/api/v1/deals/deal_001 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "456 Oak Ave Closing"}'
{
"data": {
"id": "deal_001",
"name": "456 Oak Ave Closing",
"status": "active",
"description": "Residential purchase",
"created_at": "2025-01-15T10:30:00Z",
"parties": [],
"party_count": 1
}
}
Deal Templates
Deal templates define reusable multi-party workflows. Each template has party roles with pre-configured form templates, PDF templates, and document checklists. Create a deal from a template to get all parties set up in one call.
/api/v1/deal-templates
List deal templates
Returns all deal templates available to the user, including system templates.
curl https://dointake.com/api/v1/deal-templates \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "dtpl_abc123",
"name": "Mortgage Loan",
"description": "Standard mortgage loan closing workflow",
"created_at": "2025-01-15T10:30:00Z",
"is_system": true,
"party_count": 10
}
]
}
/api/v1/deal-templates/:id
Get a deal template
Retrieve a deal template with all party roles and their attached form templates, PDF templates, and document types.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Deal template ID |
curl https://dointake.com/api/v1/deal-templates/dtpl_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "dtpl_abc123",
"name": "Mortgage Loan",
"description": "Standard mortgage loan closing workflow",
"created_at": "2025-01-15T10:30:00Z",
"is_system": true,
"parties": [
{
"position": 0,
"role": "Borrower",
"document_types": [
{
"id": 1,
"name": "Pay Stub"
}
],
"form_templates": [
{
"id": "ftpl_abc123",
"name": "Personal Info"
}
],
"pdf_templates": [
{
"id": "ptl_abc123",
"name": "W-9 Form"
}
]
},
{
"position": 1,
"role": "Escrow",
"document_types": [],
"form_templates": [],
"pdf_templates": []
}
],
"party_count": 2
}
}
/api/v1/deals
Create deal from template
Create a deal from a template by passing `template_id`. All party roles from the template are created automatically. Assign clients to parties afterward.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | required | Deal name |
template_id |
string | required | Deal template ID (dtpl_xxx) |
description |
string | optional | Deal description |
curl -X POST https://dointake.com/api/v1/deals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Smith Purchase", "template_id": "dtpl_abc123"}'
{
"data": {
"id": "deal_xyz789",
"name": "Smith Purchase",
"status": "draft",
"description": null,
"created_at": "2025-01-15T10:30:00Z",
"parties": [
{
"id": "pty_001",
"position": 0,
"requests": [],
"client": null,
"role": "Borrower",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [],
"delegate_to_id": null
},
{
"id": "pty_002",
"position": 1,
"requests": [],
"client": null,
"role": "Escrow",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [],
"delegate_to_id": null
}
],
"party_count": 2
}
}
/api/v1/deals/:deal_id/parties/:party_id/requests/from-template
Create request from template
Create a fully-loaded request for a party using the deal template's attachments. Automatically attaches all form templates, PDF templates, and document checklists defined for this party's role. The party must have a client assigned.
| Parameter | Type | Required | Description |
|---|---|---|---|
deal_id |
string | required | Deal ID |
party_id |
string | required | Party ID |
curl -X POST https://dointake.com/api/v1/deals/deal_xyz789/parties/pty_001/requests/from-template \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": {
"id": "req_abc789",
"status": "draft",
"title": "Borrower — Documents",
"items": [
{
"id": "item_001",
"name": "Pay Stub",
"status": "pending"
}
],
"client": {
"id": "cli_abc123",
"name": "Jane Smith",
"email": "borrower@example.com"
},
"created_at": "2025-01-15T10:30:00Z"
}
}
Parties
Parties represent participants in a deal (e.g. buyer, seller, lender). Each party can be linked to a client.
/api/v1/deals/:deal_id/parties
List parties
Returns all parties for a deal.
| Parameter | Type | Required | Description |
|---|---|---|---|
deal_id |
string | required | Deal ID |
curl https://dointake.com/api/v1/deals/deal_001/parties \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "pty_001",
"position": 0,
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"role": "Buyer",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [
"assistant@example.com"
],
"delegate_to_id": null
}
]
}
/api/v1/deals/:deal_id/parties
Create a party
Add a party to a deal. Optionally link to an existing client.
| Parameter | Type | Required | Description |
|---|---|---|---|
deal_id |
string | required | Deal ID |
role |
string | required | Party role (e.g. Buyer, Seller) |
client_id |
string | optional | Link to an existing client |
cc_emails |
array of strings | optional | CC email addresses for notifications (max 10) |
delegate_to_id |
string | optional | Party ID to delegate requests to. The delegate's client receives emails instead. Must be in the same deal. Set to null to clear. |
curl -X POST https://dointake.com/api/v1/deals/deal_001/parties \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"role": "Seller", "client_id": "cl_def456", "cc_emails": ["assistant@example.com"]}'
{
"data": {
"id": "pty_002",
"position": 1,
"client": {
"id": "cl_def456",
"name": "Bob Jones",
"email": "bob@example.com"
},
"role": "Seller",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [
"assistant@example.com"
],
"delegate_to_id": null
}
}
/api/v1/parties/:id
Update a party
Update a party's role or linked client.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Party ID |
role |
string | optional | Party role |
client_id |
string | optional | Link to a different client |
cc_emails |
array of strings | optional | CC email addresses for notifications (max 10) |
delegate_to_id |
string | optional | Party ID to delegate requests to. The delegate's client receives emails instead. Must be in the same deal. Set to null to clear. |
curl -X PATCH https://dointake.com/api/v1/parties/pty_001 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"delegate_to_id": "pty_002"}'
{
"data": {
"id": "pty_001",
"position": 0,
"client": {
"id": "cl_abc123",
"name": "Jane Smith",
"email": "jane@example.com"
},
"role": "Primary Buyer",
"created_at": "2025-01-15T10:30:00Z",
"cc_emails": [
"assistant@example.com",
"team@example.com"
],
"delegate_to_id": "pty_002"
}
}
Activity Log
An immutable audit trail of events in your account. Use this endpoint to track changes to deals, requests, parties, and documents.
/api/v1/activity
List activity
Returns activity log entries for your account, newest first. Supports cursor-based pagination and filtering.
| Parameter | Type | Required | Description |
|---|---|---|---|
deal_id |
string | optional | Filter by deal public ID |
party_id |
string | optional | Filter by party public ID |
request_id |
string | optional | Filter by request public ID |
resource_type |
string | optional | Filter by resource type (deal, request, party, item, upload) |
event_type |
string | optional | Filter by event type (e.g. request.sent, deal.created) |
before |
string | optional | Cursor for pagination — pass an activity ID to fetch older entries |
limit |
integer | optional | Max entries to return (1–100, default 50) |
curl https://dointake.com/api/v1/activity?deal_id=deal_abc123 \
-H "Authorization: Bearer sk_live_..."
{
"data": [
{
"id": "act_x1y2z3a4b5",
"metadata": {
"client_name": "Jane Doe",
"request_title": "Tax Documents 2025"
},
"request_id": "req_abc123",
"deal_id": "deal_abc123",
"event_type": "request.sent",
"party_id": "pty_def456",
"resource_id": "req_abc123",
"resource_type": "request",
"occurred_at": "2025-03-15T10:30:00Z"
}
]
}
Webhooks
Subscribe to events in your account. When an event occurs, we send an HTTP POST to your configured URL with a JSON payload.
/api/v1/webhooks
List webhooks
Returns all webhook subscriptions.
curl https://dointake.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"active": true,
"id": "wh_001",
"events": [
"request.completed",
"upload.created"
],
"description": "Production webhook",
"url": "https://example.com/webhook",
"created_at": "2025-01-15T10:30:00Z"
}
]
}
/api/v1/webhooks
Create a webhook
Create a new webhook subscription. The response includes a `secret` for verifying webhook signatures — store it securely, it won't be shown again.
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | required | URL to receive webhook events |
events |
array | required | Event types to subscribe to |
description |
string | optional | Description for this webhook |
active |
boolean | optional | Whether the webhook is active (default: true) |
curl -X POST https://dointake.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhook", "events": ["request.completed"]}'
{
"data": {
"active": true,
"id": "wh_002",
"events": [
"request.completed"
],
"description": null,
"secret": "whsec_abc123...",
"url": "https://example.com/webhook",
"created_at": "2025-01-15T10:30:00Z"
}
}
/api/v1/webhooks/:id
Update a webhook
Update a webhook subscription.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Webhook ID |
url |
string | optional | URL to receive webhook events |
events |
array | optional | Event types to subscribe to |
description |
string | optional | Description |
active |
boolean | optional | Whether the webhook is active |
curl -X PATCH https://dointake.com/api/v1/webhooks/wh_001 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"active": false}'
{
"data": {
"active": false,
"id": "wh_001",
"events": [
"request.completed",
"upload.created"
],
"description": "Production webhook",
"url": "https://example.com/webhook",
"created_at": "2025-01-15T10:30:00Z"
}
}
/api/v1/webhooks/:id
Delete a webhook
Permanently delete a webhook subscription.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | required | Webhook ID |
curl -X DELETE https://dointake.com/api/v1/webhooks/wh_001 \
-H "Authorization: Bearer YOUR_API_KEY"
# 204 No Content
Webhook Events
When an event occurs, we send a POST request to your webhook URL with a JSON payload.
Available event types:
| Event | Fired when |
|---|---|
request.created | A new document request is created |
request.completed | A request is marked complete |
request.reopened | A completed request is reopened |
upload.created | A client uploads a file |
pdf_form.completed | A client completes a fillable PDF form |
deal.created | A new deal is created |
deal.updated | A deal is updated |
Payload format:
{
"event": "request.completed",
"timestamp": "2025-01-20T14:00:00Z",
"data": { ... }
}
The data field contains the full resource object (same shape as the corresponding GET endpoint).
Webhook Security
Every webhook delivery includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the request body, signed with your webhook secret.
Always verify signatures to ensure payloads are from Intake and haven't been tampered with.
Verification — Node.js
Verify in Node.js
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Verification — Python
Verify in Python
import hmac, hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
Verification — Ruby
Verify in Ruby
require 'openssl'
def verify_webhook(payload, signature, secret)
expected = OpenSSL::HMAC.hexdigest(
'sha256', secret, payload
)
Rack::Utils.secure_compare(signature, expected)
end
Verification — PHP
Verify in PHP
function verifyWebhook($payload, $signature, $secret) {
$expected = hash_hmac('sha256', $payload, $secret);
return hash_equals($expected, $signature);
}
MCP Protocol
Intake exposes a native Model Context Protocol (MCP) server, letting AI agents like Claude, GPT, or custom agents manage your entire intake workflow programmatically.
Endpoint: POST https://dointake.com/mcp
Protocol: JSON-RPC 2.0 (MCP spec 2025-03-26)
Authentication: OAuth 2.1 (recommended) or API key Bearer token. Tool access respects read / write scopes.
Connecting as a Claude Connector (Recommended)
Intake is available as a native Claude Connector. This is the easiest way to connect — no API key or config files needed.
In Claude Desktop or claude.ai:
- Open Settings → Connectors
- Click Add Connector
- Enter the URL:
https://dointake.com/mcp - Claude will automatically discover the authorization server, open a consent screen, and connect to your Intake account
That's it. Claude handles authorization and token management automatically.
Connecting with an API Key
For programmatic agents, CI/CD, or clients that don't support OAuth, you can use an API key instead.
Claude Desktop — Add to your claude_desktop_config.json:
{
"mcpServers": {
"intake": {
"url": "https://dointake.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
Cursor — Add to your .cursor/mcp.json:
{
"mcpServers": {
"intake": {
"url": "https://dointake.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
Protocol Flow
A typical MCP session follows three steps:
1. Initialize — Negotiate protocol version and discover server capabilities.
→ {"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {"protocolVersion": "2025-03-26",
"clientInfo": {"name": "my-agent", "version": "1.0"}}}
← {"jsonrpc": "2.0", "id": 1, "result": {
"protocolVersion": "2025-03-26",
"capabilities": {"tools": {"listChanged": false}},
"serverInfo": {"name": "intake", "version": "1.0.0"}}}
2. List tools — Discover available tools and their input schemas.
→ {"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
← {"jsonrpc": "2.0", "id": 2, "result": {"tools": [...]}}
3. Call a tool — Execute a tool with arguments.
→ {"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": {"name": "list_clients", "arguments": {}}}
← {"jsonrpc": "2.0", "id": 3, "result": {
"content": [{"type": "text", "text": "[{...}]"}]}}
Tool results are returned as JSON text in the content array. Errors set isError: true:
← {"jsonrpc": "2.0", "id": 4, "result": {
"content": [{"type": "text", "text": "Request not found"}],
"isError": true}}
Example: Full Workflow
An agent can handle a complete intake flow without any dashboard interaction:
1. create_client(name, email)
2. create_request(client_id, title, items)
3. attach_inline_form(request_id, name, fields) — or attach_form_to_request
4. upload_pdf_template(file_base64, filename) — optional
5. attach_pdf_to_request(request_id, template_id) — optional
6. send_request(request_id)
7. get_request(id) → poll for completion
8. get_form_responses(request_id) → read submitted data
tools/call → list_clients
list_clients
List all clients
tools/call → create_client
create_client
Create a new client
tools/call → list_requests
list_requests
List document requests
tools/call → get_request
get_request
Get request with items, uploads, and portal URL
tools/call → create_request
create_request
Create a request with checklist items
tools/call → update_request
update_request
Update title, description, due date, reminders, max_reminders, notify_professional_after_days
tools/call → add_checklist_item
add_checklist_item
Add a document item to a request
tools/call → update_item
update_item
Set review status and note on an item
tools/call → re_request_item
re_request_item
Re-request a rejected item
tools/call → send_request
send_request
Send a draft request to the client
tools/call → complete_request
complete_request
Mark a sent request as complete
tools/call → list_request_reminders
list_request_reminders
List reminder audit trail for a request
tools/call → list_uploads
list_uploads
List uploads for a request
tools/call → list_form_templates
list_form_templates
List form templates
tools/call → get_form_template
get_form_template
Get template with fields
tools/call → create_form_template
create_form_template
Create template with fields
tools/call → add_form_field
add_form_field
Add a field to a form template
tools/call → attach_form_to_request
attach_form_to_request
Attach a form template to a request
tools/call → attach_inline_form
attach_inline_form
Create and attach a one-off form
tools/call → get_form_responses
get_form_responses
Get submitted form responses
tools/call → list_pdf_templates
list_pdf_templates
List PDF templates
tools/call → get_pdf_template
get_pdf_template
Get template with field info
tools/call → upload_pdf_template
upload_pdf_template
Upload a PDF (base64-encoded)
tools/call → attach_pdf_to_request
attach_pdf_to_request
Attach a PDF to a request as a fill request
Make.com Integration
Connect Intake to 1,000+ apps using Make.com (formerly Integromat). Here's a step-by-step guide:
1. Create a webhook in Make.com
Create a new scenario and add a "Webhooks" module → "Custom webhook". Copy the webhook URL.
2. Register the webhook in Intake
Use the API to create a webhook pointing to your Make.com URL:
POST /api/v1/webhooks
{"url": "https://hook.make.com/your-id", "events": ["request.completed"]}
3. Map the data
When Make.com receives its first webhook, it will learn the data structure. Use the fields to trigger actions in other apps — create a row in Google Sheets, send a Slack notification, update a CRM, etc.
4. Common recipes
- Request completed → Slack notification — Get notified when a client finishes uploading documents
- Upload created → Google Drive — Automatically save uploaded files to a specific folder
- Deal created → CRM update — Sync new deals to your CRM system