The task node
Kinds, outcomes, branches_by_outcome, the dialer, and how your application renders and completes tasks.
A task node creates a task for the sender and waits for its outcome. A call, a manual LinkedIn invitation, a WhatsApp message typed by hand, a visit: anything a human does is a task with a kind you choose to render.
"call_1": {
"type": "task",
"params": {
"kind": "call",
"title": "Call {{ contact.first_name | \"them\" }}",
"body": "They opened a proposal for {{ attrs.company.name | \"their company\" }}.",
"link": "https://crm.acme.com/people/{{ attrs.crm_id | \"\" }}",
"due": "1bd",
"expire": "3bd",
"connected_outcomes": ["connected", "meeting_set"],
"dialer": true,
"auto_complete": true
},
"next": { "completed": "wait_3d", "no_answer": "email_2" },
"branches_by_outcome": { "connected": "end_connected", "meeting_set": "end_booked", "voicemail": "sms_follow" }
}# an inbox for a sender
curl "$SEQ/v1/senders/u_42/tasks?status=open" -H "Authorization: Bearer $KEY"
# the sender did the work
curl -X POST $SEQ/v1/tasks/tsk_01J9…/complete -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"outcome":"voicemail","note":"Left a message, try Thursday."}'Params
| Param | Meaning |
|---|---|
kind | ^[a-z][a-z0-9_]*$, up to 32 characters. call has dialer behaviour; linkedin_connect and linkedin_message emit LinkedIn signals; anything else is yours |
title, body, link | templates, rendered when the task is created and stored on it ({{ contact.* }}, {{ attrs.* }}, {{ sender.* }}, {{ sequence.name }}) |
due | a duration from now, on the sender's calendar (1bd is the next business day in the sender's zone) |
expire | when the task expires if nobody completes it; default due + 7 days |
connected_outcomes | outcomes that count as a reply (a call_connected signal): exits when exit_on has reply, wakes wait_for call_connected, counts in analytics. Default ["connected"] |
dialer | call only: push the contact's number into the sender's Allo dialer queue. Default false |
auto_complete | call only: complete the task from Allo's call.completed. Default true |
Outcomes and branches
The outcome is free text (1 to 32 characters) that your application sends. The flow takes branches_by_outcome[outcome] when it is wired, otherwise completed; when neither is wired the enrollment completes. Expiry takes no_answer. Cancelling an open task (POST /v1/tasks/{id}/cancel) also takes no_answer.
Completing a task records a task_completed signal always, plus call_connected when the outcome is in connected_outcomes, connection_accepted for linkedin_connect + accepted, and a reply on linkedin for linkedin_message + replied. A task that is no longer open is returned unchanged (idempotent). Completion wakes the enrollment at once; no planner tick to wait for.
Calls through Allo
With dialer: true the number is pushed to the sender's power-dialer queue within a minute of creation (the sender needs an sms channel, which holds their Allo user id). When Allo reports an outbound call from the sender's number to the contact's number, the open call task completes itself with the outcome mapped from the call result (ANSWERED → connected, VOICEMAIL → voicemail, else no_answer; override with settings.allo.outcome_map) and the call summary as the note. A rep who dials from Allo marks nothing by hand. Set auto_complete: false to keep completion manual, for example when your app shows a disposition form. See Connect Allo.
How a client renders tasks
GET /v1/tasks?sender=&status=open&kind=&contact= and GET /v1/senders/{id}/tasks return tasks with id, kind, title, body, link, due_at, expires_at, status (open, done, expired, cancelled), outcome, note, dialer, enrollment, contact, sender. Show kind with your own label and icon, the rendered title and body, the link, and a set of outcome buttons that match the node's branches_by_outcome keys plus completed. The task.created and task.expired webhooks let you mirror tasks into your own inbox or Slack as they appear. See Tasks.