This guide explains how to add notes to existing deals in bulk using the Folk API. The process involves retrieving deal information first, then creating notes for each deal.
Overview
The bulk update process consists of three main steps:
Prepare your data - Organize deal information and notes in a CSV or Google Sheet
Retrieve deal details - Use the GET Deal endpoint to fetch deal IDs
Create notes in bulk - Loop through your data and create notes for each deal
Step 1: Prepare Your Data
Start with a CSV file or Google Sheet containing your deal information and notes. Your data should include:
Deal identifier (name, ID, or other unique identifier)
Note content
Author information (optional)
Additional metadata (optional)
Step 2: Retrieve Deal Information
For each deal in your data, you need to retrieve the deal ID using the GET List Deal endpoint. For example, you can use a filter to match the deal name with your CSV file or Google Sheet.
Endpoint
GET /v1/groups/{groupId}/{entityType}
Parameters
groupId (string, required): The ID of the group containing the deals
entityType (string, required): The deal entity type from your custom fields
Query Parameters
limit (integer, default: 20): The number of items to return (1-100)
cursor (string): For pagination across multiple pages. Don't include on first call
combinator (enum, default: "and"): Logical operator to combine filters ("and" or "or")
filter (object): Filters to apply using format : filter[attribute][operator]=value
Headers
Authorization: YOUR_API_KEY
Content-Type: application/json
Example Request
curl -X GET "https://api.folk.app/v1/groups/grp_abc123/deals" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json"
Response
The response will include deal information with the ID you need:
{
"data": {
"id": "obj_abc123def456ghi789jkl012mno345pqr678",
"name": "Acme Corporation Project",
"companies": [
{
"id": "com_987654321",
"name": "Acme Corp"
}
],
"people": [...],
"createdAt": "2021-01-01T00:00:00.000Z",
"customFieldValues": {
"Status": "Active",
"Deal value": "50000"
}
}
}
Important: Save the data.id value - this is what you'll use to create the note.
Step 3: Create Notes for Each Deal
Once you have the deal ID (which starts with "obj_"), use the Create Note endpoint to add notes to each deal.
Endpoint
POST /v1/notes
Headers
Authorization: YOUR_API_KEY
Content-Type: application/json
Request Body
{
"entity": {
"id": "obj_abc123def456ghi789jkl012mno345pqr678"
},
"visibility": "public",
"content": "Your note content here"
}
Parameters Explained
entity.id (required): The deal ID retrieved from Step 2
visibility (required): Either "public" (visible to all users) or "private" (visible only to you)
content (required): The note content (supports plain text and Markdown)
Example Request
curl -X POST "https://api.folk.app/v1/notes" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity": {
"id": "obj_abc123def456ghi789jkl012mno345pqr678"
},
"visibility": "public",
"content": "Follow-up meeting scheduled for next week"
}'
Response
{
"data": {
"id": "nte_note123456789",
"entity": {
"id": "obj_abc123def456ghi789jkl012mno345pqr678",
"entityType": "deal",
"name": "Acme Corporation Project"
},
"content": "Follow-up meeting scheduled for next week",
"visibility": "public",
"author": {
"id": "usr_user123456789",
"fullName": "John Smith",
"email": "john.smith@example.com"
},
"createdAt": "2024-03-15T10:30:00.000Z"
}
}
Bulk Processing Implementation
To process multiple deals, implement a loop that processes each row of your CSV/Google Sheet:
Pseudocode Example
FOR each row in your CSV/Google Sheet:
1. Get deal identifier from row
2. Call GET List Deal endpoint with filter to retrieve deal ID
3. Extract the deal ID from response
4. Call POST Notes endpoint with:
- entity.id = extracted deal ID
- content = note content from row
- visibility = "public" or "private"
5. Call Google Sheet API to add “Done” each line you did (prevent duplicate)
6. Add delay between requests to respect rate limits
END FOR
Implementation
You can implement this process using automation tools like n8n, Zapier, or custom scripts. The key is to loop through your data and execute both API calls for each record.
Content Formatting
The note content supports Markdown formatting. You can include:
Bold text: **text**
Italic text: *text*
Lists, links, headings
User mentions: [User Name](https://api.folk.app/v1/users/usr_userid)
n8n Template available
(Copy paste directly in n8n)
(Copy paste directly in n8n)
{
"name": "Template FOLK NOTES API",
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
240,
112
],
"id": "17c4c48a-acc8-4e47-99e5-efcb9ef91851",
"name": "When clicking ‘Execute workflow’"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
784,
112
],
"id": "06f2d96a-0f4d-4878-a716-03b47572d74b",
"name": "Loop Over Items"
},
{
"parameters": {
"amount": 1
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
992,
208
],
"id": "01844420-4ccd-41b4-859c-f224d2e795df",
"name": "Wait",
"webhookId": "338f9ba6-98d9-447a-84e4-04a304e59be6"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1_45SIjWxBaY_L94c2C2KtsnrDdnjdfugZ8BXCFbZnVw",
"mode": "list",
"cachedResultName": "EXPORT FOLK",
"cachedResultUrl": ""
},
"sheetName": {
"__rl": true,
"value": 862943313,
"mode": "list",
"cachedResultName": "final_export",
"cachedResultUrl": ""
},
"filtersUI": {
"values": [
{
"lookupColumn": "finish"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
496,
112
],
"id": "229d085f-c15b-45be-9763-502c75e58848",
"name": "GET ROW in CSV",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "rpJwzTHsKNcKLYl4",
"name": "TESTACC"
}
}
},
{
"parameters": {
"url": "https://api.folk.app/v1/groups/grp_YOURGROUPID/Deals",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "filter[name][eq]",
"value": "={{ $json.Deal }}"
},
{
"name": "limit",
"value": "1"
},
{
"name": "combinator",
"value": "and"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1232,
208
],
"id": "0c952b5f-793d-4fbc-9270-42357037882b",
"name": "GET - FOLK API1",
"alwaysOutputData": true
},
{
"parameters": {
"method": "POST",
"url": "https://api.folk.app/v1/notes",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"entity\": {\n \"id\": \"{{ $json.data.items[0].id }}\"\n },\n \"visibility\": \"public\",\n \"content\": {{ JSON.stringify($('Wait').item.json.Content) }}\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1456,
208
],
"id": "689173ba-ea44-4e78-9558-5a895beb9e43",
"name": "CREATE NOTE - API FOLK1"
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "1_45SIjWxBaY_L94c2C2KtsnrDdnjdfugZ8BXCFbZnVw",
"mode": "list",
"cachedResultName": "EXPORT FOLK",
"cachedResultUrl": ""
},
"sheetName": {
"__rl": true,
"value": 862943313,
"mode": "list",
"cachedResultName": "final_export",
"cachedResultUrl": ""
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"finish": "done",
"row_number": "={{ $('Wait').item.json.row_number }}"
},
"matchingColumns": [
"row_number"
],
"schema": [
{
"id": "Deal",
"displayName": "Deal",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "ID",
"displayName": "ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Parent ID",
"displayName": "Parent ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Author",
"displayName": "Author",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Author Date",
"displayName": "Author Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Content",
"displayName": "Content",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Attendees",
"displayName": "Attendees",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Tagged Persons",
"displayName": "Tagged Persons",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Tagged Organizations",
"displayName": "Tagged Organizations",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Tagged Opportunities",
"displayName": "Tagged Opportunities",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "finish",
"displayName": "finish",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "row_number",
"displayName": "row_number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"readOnly": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
1664,
208
],
"id": "826c62fe-844f-4592-81fd-4d02a39672d1",
"name": "Update row in sheet",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "rpJwzTHsKNcKLYl4",
"name": "TESTACC"
}
}
}
],
"pinData": {},
"connections": {
"When clicking ‘Execute workflow’": {
"main": [
[
{
"node": "GET ROW in CSV",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "GET - FOLK API1",
"type": "main",
"index": 0
}
]
]
},
"GET ROW in CSV": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"GET - FOLK API1": {
"main": [
[
{
"node": "CREATE NOTE - API FOLK1",
"type": "main",
"index": 0
}
]
]
},
"CREATE NOTE - API FOLK1": {
"main": [
[
{
"node": "Update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Update row in sheet": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "0565c7a3-10cc-4103-b751-b50a97d46e5b",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "0db6b51bd90b963ffe7af42e17939e58c6ce0afbea5705fb41d1f96b37a24265"
},
"id": "M8xtYD7PElsHqiDY",
"tags": []
}
Error Handling
Common errors and how to handle them:
401 Unauthorized: Check your API key
404 Not Found: Verify the deal ID exists
400 Bad Request: Check your request format
429 Too Many Requests: Implement rate limiting with delays
Rate Limiting
To avoid hitting rate limits:
Add delays between requests (100-200ms recommended)
Process in batches rather than all at once
Implement retry logic for failed requests
Best Practices
Test with a small batch first before processing all your data
Log all operations for debugging and verification
Validate data before making API calls
Handle errors gracefully and continue processing other items
Keep backups of your original data