Skip to content

Task operations and automation

Tasks are individual work items inside a running process. You can list, complete, update, and comment on tasks through the API using Postman.

Task structure

In Tallyfy’s API:

  • Tasks - individual work items in a running process (or standalone one-off tasks)
  • Captures - form field values within tasks (saved via a separate endpoint)
  • Owners - who’s assigned to complete the task (users, guests, or groups)

Listing tasks

Get your assigned tasks

GET {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/me/tasks
Headers:
Authorization: Bearer {{TALLYFY_ACCESS_TOKEN}}
X-Tallyfy-Client: APIClient
Accept: application/json
Query parameters:
- status: active, completed, overdue, due_soon, hasproblem
- per_page: 10 (default)
- page: 1
- sort: deadline, newest, problems, -deadline

Get all tasks in a process

GET {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/runs/{{RUN_ID}}/tasks
Query parameters:
- status: active, complete, overdue, not-started, auto-skipped
- sort: position, deadline, -position, -deadline
- with: step,form_fields,threads,assets,summary

Filter tasks by various criteria

// Advanced filtering in Tests tab
const tasks = pm.response.json().data;
// Overdue tasks
const overdueTasks = tasks.filter(t =>
t.deadline && new Date(t.deadline) < new Date() && t.status === 'active'
);
// Tasks by specific assignee
const userTasks = tasks.filter(t =>
t.owners && t.owners.users && t.owners.users.some(u => u.id === 10001)
);
console.log(`Found ${overdueTasks.length} overdue tasks`);

Completing tasks

Task completion uses a POST to the completed-tasks endpoint, not a PUT. You send the task_id in the request body.

Complete a process task

POST {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/runs/{{RUN_ID}}/completed-tasks
Headers:
Authorization: Bearer {{TALLYFY_ACCESS_TOKEN}}
X-Tallyfy-Client: APIClient
Accept: application/json
Content-Type: application/json
Body:
{
"task_id": "{{TASK_ID}}",
"is_approved": true
}

The is_approved field is optional and only applies to approval-type tasks.

Complete a one-off task

POST {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/completed-tasks
Body:
{
"task_id": "{{TASK_ID}}"
}

Save form field data before completing

You’ll save form field values (captures) through a separate endpoint before completing the task:

POST {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/tasks/{{TASK_ID}}/captures
Body:
{
"id": "field_abc123",
"value": "Approved"
}

Each capture call saves one field at a time. Send multiple requests to fill several fields, then complete the task.

Bulk task completion

Complete multiple tasks in a process:

const runId = pm.environment.get("RUN_ID");
const taskIds = ["task_123", "task_456", "task_789"];
const results = [];
function completeTask(taskId) {
return new Promise((resolve, reject) => {
pm.sendRequest({
url: `${pm.environment.get("TALLYFY_BASE_URL")}/organizations/${pm.environment.get("TALLYFY_ORG_ID")}/runs/${runId}/completed-tasks`,
method: 'POST',
header: {
'Authorization': `Bearer ${pm.environment.get("TALLYFY_ACCESS_TOKEN")}`,
'X-Tallyfy-Client': 'APIClient',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: {
mode: 'raw',
raw: JSON.stringify({ task_id: taskId })
}
}, (err, res) => {
if (err) {
reject(err);
} else {
resolve({ taskId, status: res.code });
}
});
});
}
async function completeTasks() {
for (let i = 0; i < taskIds.length; i++) {
try {
const result = await completeTask(taskIds[i]);
results.push(result);
console.log(`Completed task ${i + 1} of ${taskIds.length}`);
if (i < taskIds.length - 1) {
await new Promise(resolve => setTimeout(resolve, 200));
}
} catch (error) {
console.error(`Failed to complete task ${taskIds[i]}:`, error);
}
}
console.log('Bulk completion results:', results);
}
completeTasks();

File attachments

Upload a file

File uploads use the assets endpoint with multipart/form-data.

  1. Set up the request

    POST {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/assets
    Headers:
    Authorization: Bearer {{TALLYFY_ACCESS_TOKEN}}
    X-Tallyfy-Client: APIClient
    Accept: application/json
    // DO NOT set Content-Type - let Postman handle it
  2. Configure body as form-data

    • Select Body then form-data
    • Add key: file (type: File)
    • Add key: subject_id (type: Text, value: the task ID)
    • Add key: subject_type (type: Text, value: task)
  3. Select file

    • Click Select Files for the file field
    • Choose your file
    • Send request

Tips from Postman experts:

  • Don’t set Content-Type manually - Postman automatically sets multipart/form-data with the correct boundary. Setting it yourself causes “Missing start boundary” errors.
  • Boundary handling - the boundary separates form parts. Postman generates it automatically.

Download a file

GET {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/download-files/{{FILE_ID}}
Headers:
Authorization: Bearer {{TALLYFY_ACCESS_TOKEN}}
X-Tallyfy-Client: APIClient
Accept: application/json

Save the response using Postman’s “Save Response” then “Save to a file” option.

Task assignment patterns

Reassign a task

Update task assignments using the owners object with users, guests, and groups sub-fields:

PUT {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/runs/{{RUN_ID}}/tasks/{{TASK_ID}}
Body:
{
"owners": {
"users": [10001, 10002],
"guests": ["contractor@example.com"],
"groups": []
}
}

Dynamic assignment based on workload

Assign to the least busy team member:

async function assignToLeastBusy(runId, taskId) {
// Get task counts for candidate users
const userIds = [10001, 10002, 10003];
const taskCounts = await Promise.all(userIds.map(async (userId) => {
const tasksResponse = await new Promise((resolve, reject) => {
pm.sendRequest({
url: `${pm.environment.get("TALLYFY_BASE_URL")}/organizations/${pm.environment.get("TALLYFY_ORG_ID")}/users/${userId}/tasks?status=active&without_pagination=true`,
method: 'GET',
header: {
'Authorization': `Bearer ${pm.environment.get("TALLYFY_ACCESS_TOKEN")}`,
'X-Tallyfy-Client': 'APIClient',
'Accept': 'application/json'
}
}, (err, res) => err ? reject(err) : resolve(res));
});
return {
userId,
taskCount: tasksResponse.json().data.length
};
}));
const leastBusy = taskCounts.reduce((prev, current) =>
prev.taskCount < current.taskCount ? prev : current
);
console.log(`Assigning to user ${leastBusy.userId} (${leastBusy.taskCount} active tasks)`);
// Assign the task
return new Promise((resolve, reject) => {
pm.sendRequest({
url: `${pm.environment.get("TALLYFY_BASE_URL")}/organizations/${pm.environment.get("TALLYFY_ORG_ID")}/runs/${runId}/tasks/${taskId}`,
method: 'PUT',
header: {
'Authorization': `Bearer ${pm.environment.get("TALLYFY_ACCESS_TOKEN")}`,
'X-Tallyfy-Client': 'APIClient',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: {
mode: 'raw',
raw: JSON.stringify({
owners: { users: [leastBusy.userId] }
})
}
}, (err, res) => err ? reject(err) : resolve(res));
});
}

Task comments

Add a comment to a task

The comment endpoint uses the singular /comment, not /comments:

POST {{TALLYFY_BASE_URL}}/organizations/{{TALLYFY_ORG_ID}}/tasks/{{TASK_ID}}/comment
Headers:
Authorization: Bearer {{TALLYFY_ACCESS_TOKEN}}
X-Tallyfy-Client: APIClient
Accept: application/json
Content-Type: application/json
Body:
{
"content": "Please review the attached documents before approving."
}

Task escalation for overdue items

Find and escalate overdue tasks:

const tasks = pm.response.json().data;
const now = new Date();
const overdueTasks = tasks.filter(t => {
if (!t.deadline || t.status !== 'active') return false;
return new Date(t.deadline) < now;
});
overdueTasks.forEach(task => {
const hoursOverdue = Math.floor((now - new Date(task.deadline)) / (1000 * 60 * 60));
pm.sendRequest({
url: `${pm.environment.get("TALLYFY_BASE_URL")}/organizations/${pm.environment.get("TALLYFY_ORG_ID")}/tasks/${task.id}/comment`,
method: 'POST',
header: {
'Authorization': `Bearer ${pm.environment.get("TALLYFY_ACCESS_TOKEN")}`,
'X-Tallyfy-Client': 'APIClient',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: {
mode: 'raw',
raw: JSON.stringify({
content: `ESCALATION: This task is ${hoursOverdue} hours overdue. Manager notified.`
})
}
});
});

Troubleshooting task operations

”Cannot complete task” errors

Common causes:

  • Task already completed
  • You aren’t assigned to the task (and can_complete_only_assignees is on)
  • Required form fields haven’t been filled (save captures first)
  • Previous dependencies aren’t complete yet

File upload issues

  • Use multipart/form-data, not JSON
  • Don’t manually set Content-Type - let Postman handle it
  • Include subject_id and subject_type fields

Pagination

Task list endpoints use page and per_page (default 10), not limit/offset:

GET .../me/tasks?status=active&per_page=50&page=1

Set without_pagination=true to get all results in one response.

Next steps

With task automation set up:

Tasks > Complete task

Mark process tasks or standalone tasks as complete by POSTing the task ID to the right endpoint…

Tasks > Update task

Tallyfy’s API lets you update any task (process or one-off) via a PUT request where you can…