# Delete draft

> DELETE /v1/drafts/{id} · Core resources API

Source: https://developer.kustomer.com/api/core-resources/delete-draft

```http
DELETE https://{orgname}.api.kustomerapp.com/v1/drafts/{id}
Authorization: Bearer <API key>
```

## Authorization

Any API key or signed-in user. No specific role is required; any valid credential works.

Deletes a draft.

## About Drafts

A draft is an outbound message that hasn't been sent yet. Unlike creating a message, sending a draft makes Kustomer deliver it to the customer through a connected channel such as email, SMS, chat or WhatsApp.

A draft is what an agent is composing in the reply box before they press send, and it's also how integrations send real messages. [Creating a message](https://developer.kustomer.com/api/core-resources#messages) only records something on the timeline; creating and sending a draft makes Kustomer deliver it through the channel and account you pick. Once a draft is sent, Kustomer removes it and records the delivered message as an `out` message on the conversation. Integrations use drafts to prepare replies for an agent to review, such as an AI-suggested answer, or to send notifications and follow-ups on a schedule.

#### Channels

Every draft is created for a [customer](https://developer.kustomer.com/api/core-resources#customers) and has a `channel`: `email`, `sms`, `chat`, `whatsapp`, `facebook`, `instagram`, `twitter-dm`, `twitter-tweet` or `note`. The channel decides which fields apply and the `body` limit, which ranges from 280 characters for a tweet to 10,240 for email, chat and notes. Email drafts take `to`, `from`, `cc`, `bcc`, `subject` and an optional `template`; `app` picks the sending integration, such as `gmail` or `postmark` for email or `twilio` for SMS. The sender (`from`) should be one of your org's connected accounts, which [`GET /v1/outboundAccounts`](https://developer.kustomer.com/api/core-resources/get-outbound-accounts) lists for every channel. Pass `conversation` to reply in an existing conversation.

A `note` draft is an unsent internal [note](https://developer.kustomer.com/api/core-resources#notes), and a conversation can have only one. Add `createConversation=true` when creating a note draft to open a new conversation for it.

#### Sending and scheduling

| `status` | Meaning |
| --- | --- |
| `draft` | Saved, not sent. |
| `scheduled` | Waiting for its `sendAt` time. |
| `error` | Sending failed; see `error`. |

`sendAt` controls sending. `"sendAt": "now"` sends the draft right away. To schedule it, send a future timestamp together with `scheduled: true`; scheduling works up to 30 days ahead. A future timestamp without `scheduled: true` is treated as now, so the draft goes out immediately. Leaving `sendAt` out keeps it a draft. On `PUT /v1/drafts/{id}`, an empty `sendAt` unschedules a scheduled draft and returns it to `draft`.

Scheduled drafts are locked. Editing one for any other reason, or deleting it, fails with `409 Conflict` unless you pass `force=true`.

#### Which endpoint to use

| To | Call |
| --- | --- |
| Create a draft, or send a message right away | [`POST /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/create-draft-for-customer) |
| List a customer's unsent drafts | [`GET /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/get-all-drafts-for-customer) |
| Edit, send, schedule or unschedule a draft | [`PUT /v1/drafts/{id}`](https://developer.kustomer.com/api/core-resources/update-draft) |
| Discard a draft | [`DELETE /v1/drafts/{id}`](https://developer.kustomer.com/api/core-resources/delete-draft) |
| Find the accounts you can send from | [`GET /v1/outboundAccounts`](https://developer.kustomer.com/api/core-resources/get-outbound-accounts) |
| Read or edit a draft [forward](https://developer.kustomer.com/api/core-resources#conversations-forwards) | [`GET`](https://developer.kustomer.com/api/core-resources/get-draft-forward-by-id) or [`PUT /v1/forwards/{id}`](https://developer.kustomer.com/api/core-resources/update-draft-forward) |

A client can create 120 drafts per customer per minute, including scheduled ones, and WhatsApp drafts have their own per-user limit (see [Rate limits](https://developer.kustomer.com/docs/concepts/rate-limits)). WhatsApp media must be one of the supported file types listed on the create endpoint. `DELETE` with `deleteConversation=true` also removes the conversation, but only if it has no messages, notes or other drafts and was created by the same user. Files go on drafts through the [draft attachment endpoints](https://developer.kustomer.com/api/core-resources#drafts-attachments).

Related: [Messages](https://developer.kustomer.com/api/core-resources#messages), [Conversation forwards](https://developer.kustomer.com/api/core-resources#conversations-forwards), [Draft attachments](https://developer.kustomer.com/api/core-resources#drafts-attachments), [Conversations and messages](https://developer.kustomer.com/docs/concepts/conversations-and-messages)

### Recipes

#### 1. Send an email reply through Kustomer

Have Kustomer deliver an email to a customer from one of your support addresses, threaded into their conversation, for example from an order system or an AI agent.

**Step 1.** [`GET /v1/outboundAccounts`](https://developer.kustomer.com/api/core-resources/get-outbound-accounts.md). Find the address to send from. Each account has a `channel` and an `account`, which for email is the address. The sender you use must be one of these.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/outboundAccounts" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/outboundAccounts \
  | jq -r '.data[] | select(.attributes.channel == "email") | [.attributes.account, .attributes.name] | @tsv'
```

**Step 2.** [`GET /v1/customers/{id}`](https://developer.kustomer.com/api/core-resources/get-customer-by-id.md). Read the customer's `emails` to choose the recipient.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/customers/$CUSTOMER_ID | jq -r '.data.attributes.emails[0].email'
```

**Step 3.** [`POST /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/create-draft-for-customer.md). Create an email draft in the conversation with `"sendAt": "now"`, which sends it straight away. `to` and `from` are `{ email, name }` objects. `app` picks the sending integration, `postmark` or `gmail`; use the one your sending address is connected through. Once it's sent, Kustomer removes the draft and adds the delivered email to the conversation as an `out` message.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID/drafts" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"channel\": \"email\", \"app\": \"postmark\", \"conversation\": \"$CONVERSATION_ID\", \"from\": {\"email\": \"$FROM_EMAIL\", \"name\": \"Acme Support\"}, \"to\": [{\"email\": \"$TO_EMAIL\"}], \"subject\": \"Re: Return request for order 4417\", \"body\": \"Your refund for order 4417 has been issued.\", \"sendAt\": \"now\"}"
```

```bash title="kusty"
kusty api POST /v1/customers/$CUSTOMER_ID/drafts \
  --field channel=email --field app=postmark --field conversation=$CONVERSATION_ID \
  --field from.email=$FROM_EMAIL --field from.name="Acme Support" \
  --field to.0.email=$TO_EMAIL --field subject="Re: Return request for order 4417" \
  --field body="Your refund for order 4417 has been issued." --field sendAt=now
```

> For SMS, send `"channel": "sms"` with `to` and `from` as phone-number strings and a `body` of up to 1,600 characters. A client can create 120 drafts per customer per minute. Creating a [message](https://developer.kustomer.com/api/core-resources#messages) instead would only record the email; it would never reach the customer.

#### 2. Leave a suggested reply for an agent to review

Put a prepared answer, such as an AI-generated reply, in the conversation as an unsent draft so an agent can edit it and press send.

**Step 1.** [`POST /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/create-draft-for-customer.md). Create the draft in the conversation without `sendAt`, so it stays a `draft`. Use the channel the conversation is on, such as `chat`. Keep the draft's `data.id`.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID/drafts" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"channel\": \"chat\", \"conversation\": \"$CONVERSATION_ID\", \"body\": \"$SUGGESTED_REPLY\"}"
```

```bash title="kusty"
kusty api POST /v1/customers/$CUSTOMER_ID/drafts \
  --field channel=chat --field conversation=$CONVERSATION_ID --field body="$SUGGESTED_REPLY" \
  | jq -r .data.id
```

**Step 2.** [`GET /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/get-all-drafts-for-customer.md). Later, list the customer's drafts to see whether yours is still unsent. Drafts that were sent are gone from the list.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID/drafts" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/customers/$CUSTOMER_ID/drafts --all \
  | jq -r '[.data.id, .data.attributes.status, .data.relationships.conversation.data.id] | @tsv'
```

**Step 3.** [`PUT /v1/drafts/{id}`](https://developer.kustomer.com/api/core-resources/update-draft.md). If the customer writes again before the agent sends it, replace the suggestion. `channel` is required on every update; leaving `sendAt` out keeps the draft unsent.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/drafts/$DRAFT_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"channel\": \"chat\", \"body\": \"$NEW_SUGGESTION\"}"
```

```bash title="kusty"
kusty api PUT /v1/drafts/$DRAFT_ID --field channel=chat --field body="$NEW_SUGGESTION"
```

> To withdraw a suggestion, [delete the draft](https://developer.kustomer.com/api/core-resources/delete-draft). For an internal hint rather than a reply, use `"channel": "note"`; a conversation can have only one note draft.

#### 3. Schedule a follow-up and cancel it if the customer replies

Queue a check-in email for a few days from now, and take it back if the customer answers first.

**Step 1.** [`POST /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/create-draft-for-customer.md). Create the draft with a future `sendAt` and `"scheduled": true`, up to 30 days ahead. Without `scheduled: true` a future time is treated as now and the email goes out immediately. The draft's `status` becomes `scheduled`.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID/drafts" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"channel\": \"email\", \"app\": \"postmark\", \"conversation\": \"$CONVERSATION_ID\", \"from\": {\"email\": \"$FROM_EMAIL\"}, \"to\": [{\"email\": \"$TO_EMAIL\"}], \"subject\": \"Checking in on your return\", \"body\": \"Did the replacement arrive safely?\", \"sendAt\": \"$SEND_AT\", \"scheduled\": true}"
```

```bash title="kusty"
kusty api POST /v1/customers/$CUSTOMER_ID/drafts \
  --field channel=email --field app=postmark --field conversation=$CONVERSATION_ID \
  --field from.email=$FROM_EMAIL --field to.0.email=$TO_EMAIL \
  --field subject="Checking in on your return" --field body="Did the replacement arrive safely?" \
  --field sendAt=$SEND_AT --field scheduled:=true \
  | jq -r .data.id
```

**Step 2.** [`PUT /v1/drafts/{id}`](https://developer.kustomer.com/api/core-resources/update-draft.md). When the customer replies (for example on a `kustomer.message.create` webhook with `direction: "in"`), unschedule the draft by sending an empty `sendAt`. It goes back to `draft` and nothing is sent.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/drafts/$DRAFT_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"channel": "email", "sendAt": ""}'
```

```bash title="kusty"
kusty api PUT /v1/drafts/$DRAFT_ID --field channel=email --field sendAt=
```

**Step 3.** [`DELETE /v1/drafts/{id}`](https://developer.kustomer.com/api/core-resources/delete-draft.md). Or discard it outright. Scheduled drafts are locked, so deleting or otherwise editing one fails with `409 Conflict` unless you pass `force=true`.

```bash title="cURL"
curl --request DELETE "https://api.kustomerapp.com/v1/drafts/$DRAFT_ID?force=true" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api DELETE /v1/drafts/$DRAFT_ID --query force=true --confirm --yes
```

### Example object

A real record from [`GET /v1/customers/{id}/drafts`](https://developer.kustomer.com/api/core-resources/get-all-drafts-for-customer.md):

```json
{
  "id": "58210c6c2a8b9910002f6730",
  "type": "draft",
  "attributes": {
    "channel": "chat",
    "body": "",
    "payload": {
      "draftJs": {
        "blocks": [
          {
            "data": {},
            "entityRanges": [],
            "inlineStyleRanges": [],
            "depth": 0,
            "type": "unstyled",
            "text": "",
            "key": "dv926"
          }
        ],
        "entityMap": {}
      }
    },
    "status": "draft",
    "createdAt": "2016-11-07T23:21:16.945Z",
    "updatedAt": "2016-11-08T18:49:32.730Z",
    "modifiedAt": "2016-11-08T18:49:32.730Z"
  },
  "relationships": {
    "org": {
      "data": {
        "type": "org",
        "id": "57f29863a1dbf61100e6aa92"
      },
      "links": {
        "self": "/v1/orgs/57f29863a1dbf61100e6aa92"
      }
    },
    "customer": {
      "data": {
        "type": "customer",
        "id": "58210c3db0f09110006b7953"
      },
      "links": {
        "self": "/v1/customers/58210c3db0f09110006b7953"
      }
    },
    "createdBy": {
      "data": {
        "type": "user",
        "id": "57fd2d309d0ef811009cfdd6"
      },
      "links": {
        "self": "/v1/users/57fd2d309d0ef811009cfdd6"
      }
    },
    "modifiedBy": {
      "data": {
        "type": "user",
        "id": "58190b991f2932100010d683"
      },
      "links": {
        "self": "/v1/users/58190b991f2932100010d683"
      }
    },
    "conversation": {
      "data": {
        "type": "conversation",
        "id": "58210c3d728107110018662f"
      },
      "links": {
        "self": "/v1/conversations/58210c3d728107110018662f"
      }
    }
  }
}
```

Fields:

- `attributes.channel` (string): The channel the draft will be sent on: `email`, `sms`, `chat`, `whatsapp`, `facebook`, `instagram`, `twitter-dm`, `twitter-tweet`, or `note` for an unsent internal note. It decides which other fields apply, and you must send it on every `PUT`.
- `attributes.body` (string): The text to send. The limit depends on the channel, from 280 characters for a tweet to 10,240 for email, chat and notes. Empty while an agent hasn't typed anything yet, as here.
- `attributes.payload` (object): Rich-text editor state saved by the agent desktop while an agent composes the draft. Integrations can leave it out and send `body`.
- `attributes.payload.draftJs` (object): The editor's content blocks. Their `text` mirrors `body`.
- `attributes.status` (string): `draft` while it's saved but not sent, `scheduled` while it waits for its `sendAt` time, or `error` when sending failed. Once a draft is sent, Kustomer removes it and records an `out` message.
- `relationships.customer` (object): The customer the draft is addressed to. Drafts are always created for a customer.
- `relationships.createdBy` (object): The user or API key that started the draft.
- `relationships.conversation` (object): The conversation the reply goes into. Set it with `conversation` on create to reply in an existing conversation; for a note draft, `createConversation=true` opens a new one instead.

### Relationships

- Points to **Customers** via `relationships.customer`: The customer a draft will be sent to. Every draft is created for one customer, who can have several unsent drafts.
- Points to **Conversations** via `relationships.conversation`: The conversation a draft replies in. When it's sent, the delivered message is added to this conversation. A conversation can have at most one note draft.
- Points to **Attachments** via `relationships.attachments` (list): Files attached to a draft. Create them with `POST /v1/drafts/{id}/attachments` and upload each file to its signed URL before sending.

### Permissions

Fewest roles for a read-only integration: `org.permission.apps.read`, `org.permission.draft.read`. For every endpoint: `org.permission.apps.read`, `org.permission.draft.read`.

### Events

Workflow triggers:

- `kustomer.draft.create` (Draft Created): An agent starts a draft

Workflow actions:

- `kustomer.draft.internal-message-create` (Draft: Internal message): required inputs `customer`, `conversation`

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Unique draft ID. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `force` | boolean | no | Force the draft update or delete when supported by the draft service. |
| `deleteConversation` | boolean | no | Delete the associated conversation when deleting the draft. |

## Responses

### 204

No Content

### 401

Unauthorized

### 403

Forbidden

### 404

Not Found

## Example request

```bash
curl --request DELETE \
  --url 'https://api.kustomerapp.com/v1/drafts/5823e4d3bff98a100085320e' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```
