---
title: "Power and Parallel Dialer SDK Call Lifecycle | Trellus"
description: "How the parallel dialer SDK runs manual, power and parallel modes: call progression, wrap-up, pause, hangup, teardown and uncertain call outcomes."
source: "https://www.trellus.ai/developers/dialer-sdk/lifecycle"
note: "Text-only copy of the page for AI assistants and agents. Link to the source address, not this file."
site_summary: "https://www.trellus.ai/llms.txt"
---

# Call lifecycle

How manual, power and parallel modes place calls, how a call progresses, what wrap-up requires, and what to do when an outcome is uncertain.

One owner for queue scheduling

## Manual, power and parallel

The SDK is the only owner of queue scheduling. Your interface renders snapshots and calls methods when the user acts. The transport turns backend and audio events into the SDK’s call events.

The three dialing modes

| Mode | Placement | After a conversation |
| --- | --- | --- |
| Manual | One explicit `dial(task)`. | Waits for wrap-up. The next call needs another action. |
| Power | One queued call at a time. | Waits for wrap-up, then continues the ordered queue. |
| Parallel | Up to the requested number of calls at once. | Stops filling slots when one call connects to the rep, ends the other calls in the window, then waits for wrap-up. |

Start a manual call with `dial(task)`. Start a power or parallel run with `start()`. Power requires one line. Parallel requires at least two.

### How a parallel window resolves

- The first `connected` event wins the window. The SDK stops filling slots and asks for the other calls to end.
- `connected` means the rep joined that call. A destination that answers, or a live detection, does not prove the rep’s audio is attached.
- Calls canceled because another call won become `skipped` with the reason `parallel_loser`. They are not redialed automatically within the same queue.
- A task canceled before it was dispatched stays `queued`.
- Choose any later retry list explicitly in your own workflow.

## Call progression

Call statuses

```
creating → ringing → connected → ending → ended → wrap-up complete
    │          │          │
    └──────────┴──────────┴─→ unknown → reconcile with the existing session
```

- Some stages can be skipped. A busy or unanswered call can go straight from `ringing` to `ended`.
- An immediate rejection by the server becomes `failed`.
- A request that may have been dispatched stays `unknown`. It is not treated as a safe failed call.
- `hangup()` moves a call to `ending`. It stays there until a terminal event confirms the end.

## Wrap-up

A call that ends without a rep conversation frees its capacity automatically. A call that ends after a rep conversation needs wrap-up:

1. The attempt ID appears in `pendingWrapUp`.
2. Your interface collects the outcome and calls `completeWrapUp(attemptId, disposition)`.
3. If you supplied `onDisposition`, the SDK awaits it. Its promise must resolve first.
4. The SDK clears that call’s wrap-up and allows further scheduling.

Complete wrap-up

```javascript
await dialer.completeWrapUp(attemptId, { disposition: 'Connected', notes: 'Example' });
```

### Save the outcome in onDisposition

`onDisposition` is the boundary for a save that your application acknowledges. The callback owns persistence. There is no implicit write to Trellus or to a CRM.

An onDisposition save hook

```javascript
const dialer = createDialer({
  transport,
  maxLines: 3,
  onDisposition: async ({ call, disposition }) => {
    // Your authenticated application persists the exact task/attempt outcome.
    // Resolve only when your own save contract succeeds.
    await saveCallOutcome({
      taskId: call.taskId,
      attemptId: call.attemptId,
      sessionId: call.sessionId,
      ...disposition,
    });
  },
});
```

`saveCallOutcome` is yours to implement. The package does not supply it.

- A failed save keeps the wrap-up pending and the queue paused.
- Repeated `completeWrapUp` calls while a save is pending share that save.
- Without an `onDisposition` handler, `completeWrapUp` continues the local queue.
- Saving a disposition, writing a CRM record, completing a task and receiving a webhook are separate actions. Each has its own acknowledgment.

## Pause, hangup and teardown

- `pause()` stops new placement at once and cancels work that has not been dispatched. Ringing and connected calls stay active.
- `resume()` continues the last power or parallel run when no unknown call or wrap-up is unresolved.
- `hangup(attemptId)` asks the transport to end one known call.
- To stop a run, pause first, then hang up each active call.
- On permanent teardown, await `destroy()`. It tries to end known calls before it disposes owned audio and subscriptions.

**Disposing local audio is not proof.** A server or network failure can prevent a confirmed end. Disposing local media alone does not prove that an unknown call stopped ringing.

The SDK does not persist queue runs across page reloads, and it has no cross-tab ownership lease. Do not reconnect or create a second dialer automatically while a call is uncertain.

## Uncertain outcomes

A request to create a call can time out after the server accepted it. The call may be ringing. The SDK cannot tell.

**Never retry an unknown call automatically.** The SDK blocks continuation with an `unknown` call and does not redial the destination. Your application must not redial it either.

- The same rule applies when the event stream of a known call is lost: scheduling stops and the call keeps its identity.
- When the stream cannot be restored, the SDK reports `connection_lost` and keeps the call’s capacity as uncertain. It never invents an end.
- A failure whose outcome is uncertain carries `outcomeUnknown: true`.
- Reconcile the existing call through the transport and server before you continue. A custom transport can re-establish observation and emit `ended` once the end of the call is confirmed.
- This preview has no public method that marks an unknown call as ended because the user dismissed a warning.
- A create with an ambiguous outcome may not yield a `sessionId`.

Error codes are listed in the [API reference](https://www.trellus.ai/developers/dialer-sdk/api#errors).

## Snapshots are not stored records

- Snapshots are local observed state. They are not a durable audit log.
- Persist the exact task and attempt mapping in your application where you need it.
- After a confirmed create, `call.sessionId` is the identifier to correlate with stored call data. Keep it separate from your task ID and the SDK attempt ID.
- Transcript updates can finish after a call ends. See [transcript finality](https://www.trellus.ai/developers/dialer-sdk/events#transcripts).
- A task status of `completed` is local queue progress. It is not a receipt for a saved outcome.
