> ## Documentation Index
> Fetch the complete documentation index at: https://vida.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cookbook: Run an Outbound Workflow

> Create a retry-aware outbound communication goal, reconcile it safely, and verify the final outcome.

Use this workflow for an outbound call, text, or email that may require retries. One Task should
represent one logical customer outcome and all attempts toward it.

## 1. Resolve the Agent and recipient

1. Read the selected Agent account and confirm the channel is configured.
2. [Search Contacts](/docs/api-reference/contacts/search-and-paginate-contacts) by exact phone or email
   before creating another Contact.
3. Read the Contact's recent communication and any matching ongoing objective.
4. [Read Task limits](/docs/api-reference/tasks/fetch-task-limits).
5. Query existing Tasks by recipient, Contact, stable external reference, and current state.

Do not create new work when an active Task already represents the same goal.

## 2. Define the goal and cadence

The Task should contain:

* `type`: `call`, `text`, or `email`
* the Agent account in `accountId`
* the channel-appropriate `target`
* complete `taskContext`
* an optional `scheduledFor` Unix timestamp
* a stable `externalTaskId` for reconciliation
* `goal.completionCriteria`
* a `retryPolicy` that retries only relevant unresolved outcomes

`externalTaskId` is correlation data, not an idempotency key. Always query before resubmitting an
uncertain request.

Example shape:

```json theme={null}
{
  "type": "call",
  "accountId": 1234,
  "target": "+15551234567",
  "taskContext": "Confirm whether the customer wants to renew this month.",
  "externalTaskId": "renewal:customer-482:2026-08",
  "goal": {
    "completionCriteria": "The customer clearly confirms or declines renewal."
  },
  "retryPolicy": {
    "delaysSeconds": [3600, 86400],
    "retryOn": ["busy", "no_answer", "voicemail", "transient_failure"]
  }
}
```

Follow the [create Task schema](/docs/api-reference/tasks/create-a-new-task) for the selected channel.

## 3. Create and save the Task identity

Create the Task with the same Agent in query `targetAccountId` and body `accountId`. Save the
returned Task ID immediately.

If the create request times out or returns an uncertain server error, query by `externalTaskId`,
recipient, and recent time range before trying again.

## 4. Follow the complete outcome

Poll the [specific Task](/docs/api-reference/tasks/fetch-a-specific-task) until it reaches a terminal
state or requires intervention. Inspect:

* `attemptHistory`
* terminal `result` and outcome
* `logsRef`
* each attempt's conversation reference

Queued or connected does not mean the completion criteria were met.

## 5. Reconcile the destination

Read the complete conversation and verify any promised external effect. Then update the Contact's
objective state with the result, next action, and not-before time when follow-up remains.

Do not remove the Contact from an objective merely because one attempt failed.

## 6. Scale carefully

For a prepared list, use the CSV or batch Task workflow and save the returned batch ID. Review
inserted, rejected, and failed records before submitting another batch.

Use an optional managed outbound number pool only after Vida has enabled it for the organization.

## Completion evidence

Report the Agent account, Contact, Task ID, external reference, terminal outcome, attempt count,
conversation or log references, and the destination-system verification. If the goal remains
incomplete, report the next scheduled attempt or the reason work stopped.
