Workbooks API
The Workbooks API allows you to extract post interactions (comments, reactions) and contact information from posts.
All API requests require authentication. See API Reference for details.
Workbook data is stored in temporary workbooks that expire after 12 hours. Make sure to download all data you need within this timeframe.
Quick Start
Extract interactions from a post in 3 steps:
1. Create a Collection Task
- cURL
- JavaScript
- Python
curl -X POST \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"post_url": "https://www.linkedin.com/posts/username_activity-1234567890",
"data_types": ["comment", "reaction"],
"workspace_id": "507f1f77bcf86cd799439011"
}' \
https://production.viacurrent.com/api/workbooks
const response = await fetch('https://production.viacurrent.com/api/workbooks', {
method: 'POST',
headers: {
'X-API-Key': 'your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
post_url: 'https://www.linkedin.com/posts/username_activity-1234567890',
data_types: ['comment', 'reaction'],
workspace_id: '507f1f77bcf86cd799439011'
})
});
const result = await response.json();
console.log(result);
import httpx
response = httpx.post(
'https://production.viacurrent.com/api/workbooks',
headers={'X-API-Key': 'your_api_key_here'},
json={
'post_url': 'https://www.linkedin.com/posts/username_activity-1234567890',
'data_types': ['comment', 'reaction'],
'workspace_id': '507f1f77bcf86cd799439011'
}
)
print(response.json())
Response:
{
"task_id": "abc123-def456-ghi789",
"status": "PENDING"
}
2. Wait for Completion
The extraction typically takes 1-3 minutes. The task runs asynchronously, so you can check back later or poll for status updates (if status endpoint is available).
3. Retrieve Your Data
Once complete, use the workbook ID to access the collected data:
- cURL
- JavaScript
- Python
# Get all contacts (deduplicated)
curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439012/contacts
# Get comments
curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439012/comments
# Get reactions
curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439012/reactions
const headers = { 'X-API-Key': 'your_api_key_here' };
const workbookId = '507f1f77bcf86cd799439012';
// Get all contacts (deduplicated)
const contactsResponse = await fetch(
`https://production.viacurrent.com/api/workbooks/${workbookId}/contacts`,
{ headers }
);
const contacts = await contactsResponse.json();
// Get comments
const commentsResponse = await fetch(
`https://production.viacurrent.com/api/workbooks/${workbookId}/comments`,
{ headers }
);
const comments = await commentsResponse.json();
// Get reactions
const reactionsResponse = await fetch(
`https://production.viacurrent.com/api/workbooks/${workbookId}/reactions`,
{ headers }
);
const reactions = await reactionsResponse.json();
import httpx
headers = {'X-API-Key': 'your_api_key_here'}
workbook_id = '507f1f77bcf86cd799439012'
# Get all contacts (deduplicated)
contacts = httpx.get(
f'https://production.viacurrent.com/api/workbooks/{workbook_id}/contacts',
headers=headers
).json()
# Get comments
comments = httpx.get(
f'https://production.viacurrent.com/api/workbooks/{workbook_id}/comments',
headers=headers
).json()
# Get reactions
reactions = httpx.get(
f'https://production.viacurrent.com/api/workbooks/{workbook_id}/reactions',
headers=headers
).json()
Create a Workbook
Create a new temporary workbook to extract interactions from a post.
POST /api/workbooks
Request Body
{
"workspace_id": "507f1f77bcf86cd799439013",
"post_url": "https://www.linkedin.com/feed/update/urn:li:activity:...",
"data_types": ["comment", "reaction"]
}
| Field | Type | Required | Description |
|---|---|---|---|
workspace_id | string | Yes | The workspace ID |
post_url | string | Yes | Post URL (see supported formats) |
data_types | array | Yes | Types of data to extract: comment, reaction (post data is always included) |
Response
Returns a task ID for tracking the extraction progress.
{
"task_id": "abc123-def456-ghi789",
"status": "PENDING"
}
Status values:
PENDING- Task is queuedSTARTED- Extraction in progressSUCCESS- Extraction completeFAILURE- Extraction failed
Rate Limiting
- 6 requests per minute per API key
Get Task Status
Monitor the progress of your workbook extraction task.
GET /api/tasks/{task_id}/status
Path Parameters
| Parameter | Type | Description |
|---|---|---|
task_id | string | The task ID returned from workbook creation |
Response
- In Progress
- Completed
- Failed
{
"task_id": "abc123-def456-ghi789",
"status": "running"
}
{
"task_id": "abc123-def456-ghi789",
"status": "success",
"completed_at": "2024-01-15T10:30:00Z",
"result": {
"workbook_id": "507f1f77bcf86cd799439012",
"items_collected": 150,
"success": true
}
}
{
"task_id": "abc123-def456-ghi789",
"status": "failure",
"completed_at": "2024-01-15T10:35:00Z",
"error": "Post not found or access denied"
}
Example Request
- cURL
- JavaScript
- Python
curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/tasks/abc123-def456-ghi789/status
const taskId = 'abc123-def456-ghi789';
const headers = { 'X-API-Key': 'your_api_key_here' };
// Poll for completion
let workbookId;
while (true) {
const response = await fetch(
`https://production.viacurrent.com/api/tasks/${taskId}/status`,
{ headers }
);
const data = await response.json();
if (data.status === 'success' || data.status === 'failure') {
workbookId = data.result?.workbook_id;
break;
}
await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds
}
console.log(`Workbook ID: ${workbookId}`);
import httpx
import time
task_id = "abc123-def456-ghi789"
headers = {"X-API-Key": "your_api_key_here"}
# Poll for completion
while True:
response = httpx.get(
f"https://production.viacurrent.com/api/tasks/{task_id}/status",
headers=headers
)
data = response.json()
if data["status"] in ["success", "failure"]:
break
time.sleep(10) # Wait 10 seconds before checking again
workbook_id = data["result"]["workbook_id"]
Rate Limiting
- 60 requests per minute per API key
Get Contacts
Retrieve deduplicated contact information from a workbook.
GET /api/workbooks/{workbook_id}/contacts
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
fields | string | name,profile_url | Comma-separated fields to include |
activity_filter | string | (all) | Filter by activity: posters, commenters, reactors, or combinations |
Available fields:
name- Full namefirst_name- Parsed first namelast_name- Parsed last nameurn- Platform URN (Universal Resource Name)profile_url- Profile URLprofile_type- Type of profile (user, company)description- Profile headline/descriptionprofile_image_url- Profile picture URLstats- All activity statisticsstats.posts- Number of postsstats.reactions- Number of reactionsstats.comments- Number of comments
Response
[
{
"name": "Jane Smith",
"first_name": "Jane",
"last_name": "Smith",
"profile_url": "https://linkedin.com/in/janesmith",
"profile_image_url": "https://...",
"description": "Product Manager at Tech Corp",
"stats": {
"posts": 0,
"reactions": 1,
"comments": 3
}
}
]
Rate Limiting
- 12 requests per minute per API key
Get Comments
Retrieve all comments from a workbook.
GET /api/workbooks/{workbook_id}/comments
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
include_replies | boolean | true | Include reply comments in results |
Response
[
{
"_id": "507f1f77bcf86cd799439011",
"content": "Great insight! Thanks for sharing.",
"author": {
"name": "John Doe",
"urn": "urn:li:person:...",
"profile_url": "https://linkedin.com/in/johndoe",
"profile_image_url": "https://..."
},
"posted_at": "2024-01-15T10:45:00Z",
"meta": {
"is_reply": false
}
}
]
Rate Limiting
- 12 requests per minute per API key
Get Reactions
Retrieve all reactions from a workbook.
GET /api/workbooks/{workbook_id}/reactions
Response
[
{
"_id": "507f1f77bcf86cd799439011",
"reaction_type": "LIKE",
"author": {
"name": "John Doe",
"urn": "urn:li:person:...",
"profile_url": "https://linkedin.com/in/johndoe",
"profile_image_url": "https://..."
},
"created_at": "2024-01-15T10:30:00Z"
}
]
Reaction types:
LIKECELEBRATESUPPORTLOVEINSIGHTFULFUNNY
Rate Limiting
- 12 requests per minute per API key
Example Workflow
1. Create an interaction run
curl -X POST "https://production.viacurrent.com/api/workbooks" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": "507f1f77bcf86cd799439013",
"post_url": "https://www.linkedin.com/feed/update/urn:li:activity:...",
"data_types": ["comment", "reaction"]
}'
Response:
{
"task_id": "abc123-def456-ghi789",
"status": "PENDING"
}
2. Wait for extraction to complete
Poll the task status (implementation depends on your task monitoring system).
3. Get contacts from the workbook
curl -X GET "https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439014/contacts?fields=name,profile_url,stats&activity_filter=commenters,reactors" \
-H "X-API-Key: your_api_key_here"
4. Get comments
curl -X GET "https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439014/comments" \
-H "X-API-Key: your_api_key_here"
5. Get reactions
curl -X GET "https://production.viacurrent.com/api/workbooks/507f1f77bcf86cd799439014/reactions" \
-H "X-API-Key: your_api_key_here"
Error Responses
400 Bad Request
{
"detail": "This operation is only supported for temporary workbooks."
}
Common causes:
- Invalid post URL format
- Missing required fields
Solution: Verify your post URL is valid and all required fields are provided.
403 Forbidden
{
"detail": "No access to workspace"
}
Solution: Verify you have access to the workspace ID you're using.
409 Conflict
{
"detail": "task_blocked_by_another_task"
}
Cause: A collection task is already running for this post.
Solution: Wait for the existing task to complete before creating a new one.
422 Validation Error
{
"detail": "Invalid post URL format"
}
Solution: Check that your post URL format is correct. Valid formats:
https://www.linkedin.com/posts/username_activity-1234567890https://www.linkedin.com/feed/update/urn:li:activity:...
429 Too Many Requests
{
"detail": "Rate limit exceeded"
}
Solution: Wait before making additional requests. POST requests are limited to 6/minute.
Important Notes
12-Hour Data Window
Workbook data expires after 12 hours. Make sure to:
- Download all required data within this timeframe
- Save the workbook ID immediately after creation
- Extract all needed information (contacts, comments, reactions) before expiration
Task Limitations
- Only one extraction task can run per post at a time
- Extraction typically takes 1-3 minutes depending on post size
- Large posts (1000+ interactions) may take longer