---
title: "Save a wrap-up disposition for a call that produced no CallSid"
description: "Outbound calls that are never answered (no-answer, busy, carrier reject) never fire the Twilio SDK's accept event, so the browser never learns their CallSid and cannot use PUT /api/calls/{callSid}/disposition. The call_logs row still exists — the voice webhook writes it at dial time — so this route addresses it by (workspace, contact, agent, recency) instead. Only fills a row whose disposition is still empty; never overwrites.\n"
---

> Documentation Index
> Fetch the complete documentation index at: https://developer.channelautomations.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Channel Automation API › Twilio

`PUT /api/calls/contact/{contactId}/disposition`

Outbound calls that are never answered (no-answer, busy, carrier reject) never fire the Twilio SDK's accept event, so the browser never learns their CallSid and cannot use PUT /api/calls/{callSid}/disposition. The call_logs row still exists — the voice webhook writes it at dial time — so this route addresses it by (workspace, contact, agent, recency) instead. Only fills a row whose disposition is still empty; never overwrites.

## Path parameters

- `contactId` (`put/api/calls/contact/contactId/disposition.path.contactId`; string, required)

## Request body

_Required._

- `workspace_id` (`put/api/calls/contact/contactId/disposition.workspace_id`; string, required)
- `disposition` (`put/api/calls/contact/contactId/disposition.disposition`; string, required)
- `user_id` (`put/api/calls/contact/contactId/disposition.user_id`; string, optional)
- `cadence_request` (`put/api/calls/contact/contactId/disposition.cadence_request`; object, optional) — Optional manager-approved retry timing; validated atomically for managed calls. Does not change the call result.
  - `wait_minutes` (`put/api/calls/contact/contactId/disposition.cadence_request.wait_minutes`; integer, optional)
    - min 1
  - `retry_at` (`put/api/calls/contact/contactId/disposition.cadence_request.retry_at`; string, optional)
    - format `date-time`
  - `reason` (`put/api/calls/contact/contactId/disposition.cadence_request.reason`; string, optional)
    - maxLength 500
- `callback_at` (`put/api/calls/contact/contactId/disposition.callback_at`; string, optional) — Future promised callback time when disposition is CALLBACK_SCHEDULED.
  - format `date-time`
- `sub_disposition` (`put/api/calls/contact/contactId/disposition.sub_disposition`; string, optional)

## Example request

```json
{
  "workspace_id": "string",
  "disposition": "string",
  "user_id": "string",
  "cadence_request": {
    "wait_minutes": 1,
    "retry_at": "2019-08-24T14:15:22Z",
    "reason": "string"
  },
  "callback_at": "2019-08-24T14:15:22Z",
  "sub_disposition": "string"
}
```

## Code samples

### cURL

```bash
curl --request PUT \
  --url 'https://api.channelautomation.com/api/calls/contact/<contactId>/disposition' \
  --header 'Content-Type: application/json' \
  --data '
{
  "workspace_id": "string",
  "disposition": "string",
  "user_id": "string",
  "cadence_request": {
    "wait_minutes": 1,
    "retry_at": "2019-08-24T14:15:22Z",
    "reason": "string"
  },
  "callback_at": "2019-08-24T14:15:22Z",
  "sub_disposition": "string"
}
'
```

### TypeScript

```typescript
const url = 'https://api.channelautomation.com/api/calls/contact/<contactId>/disposition';
const options = {
  method: 'PUT',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    workspace_id: 'string',
    disposition: 'string',
    user_id: 'string',
    cadence_request: {wait_minutes: 1, retry_at: '2019-08-24T14:15:22Z', reason: 'string'},
    callback_at: '2019-08-24T14:15:22Z',
    sub_disposition: 'string'
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://api.channelautomation.com/api/calls/contact/<contactId>/disposition"

payload = {
    "workspace_id": "string",
    "disposition": "string",
    "user_id": "string",
    "cadence_request": {
        "wait_minutes": 1,
        "retry_at": "2019-08-24T14:15:22Z",
        "reason": "string"
    },
    "callback_at": "2019-08-24T14:15:22Z",
    "sub_disposition": "string"
}
headers = {"Content-Type": "application/json"}

response = requests.put(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

Disposition saved

### 400

Missing/invalid contactId

### 404

No recent un-dispositioned outbound call for that contact

### 500

Server error


Source: https://developer.channelautomations.com/api/put-api-calls-contact-contact-id-disposition/index.md
