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

# Delete Endpoints

> Move deletes from DELETE requests to POST /delete, and record why something was deleted

> [!NOTE]
>
> All requests in this guide assume you have a valid access token attached in your request headers. See our [authentication guide](https://docs.campfire.ai/quickstart.md) for more information.

Some objects are now deleted with a `POST` to `/delete` on the object's path, instead of a `DELETE` request. The new route works the same way as the old one, and it lets you send a reason for the delete. Campfire saves that reason on the audit log entry for the delete.

> [!WARNING]
>
> The `DELETE` routes below are deprecated and will be removed on `{{REMOVAL_DATE}}`. We'll email you at least a week before they're removed. Move your integration to the `POST` routes before then.

## Which endpoints changed

In every case the new route is the object's path with `/delete` added to the end.

### Settings

| Object | Deprecated | Use instead |
| - | - | - |
| Department | `DELETE /coa/api/department/{id}` | `POST /coa/api/department/{id}/delete` |
| Custom dimension (tag) | `DELETE /coa/api/tag/{id}` | `POST /coa/api/tag/{id}/delete` |
| Product | `DELETE /rr/api/v1/product/{id}` | `POST /rr/api/v1/product/{id}/delete` |
| Fixed asset automation rule | `DELETE /coa/api/fixed-asset-automation/{id}` | `POST /coa/api/fixed-asset-automation/{id}/delete` |

### Accounts and accounting records

| Object | Deprecated | Use instead |
| - | - | - |
| Chart of accounts account | `DELETE /coa/api/account/{id}` | `POST /coa/api/account/{id}/delete` |
| Bank account | `DELETE /ca/api/account/{id}` | `POST /ca/api/account/{id}/delete` |
| Journal entry | `DELETE /coa/api/journal_entry/{id}` | `POST /coa/api/journal_entry/{id}/delete` |
| Intercompany journal entry | `DELETE /coa/api/intercompany-journal-entry/{id}` | `POST /coa/api/intercompany-journal-entry/{id}/delete` |
| Fixed asset | `DELETE /coa/api/fixed-asset/{id}` | `POST /coa/api/fixed-asset/{id}/delete` |

### Bills, invoices and memos

| Object | Deprecated | Use instead |
| - | - | - |
| Bill | `DELETE /coa/api/v1/bill/{id}` | `POST /coa/api/v1/bill/{id}/delete` |
| Debit memo | `DELETE /coa/api/v1/debit-memo/{id}` | `POST /coa/api/v1/debit-memo/{id}/delete` |
| Invoice | `DELETE /coa/api/v1/invoice/{id}` | `POST /coa/api/v1/invoice/{id}/delete` |
| Credit memo | `DELETE /coa/api/v1/credit-memo/{id}` | `POST /coa/api/v1/credit-memo/{id}/delete` |

### Revenue and contracts

| Object | Deprecated | Use instead |
| - | - | - |
| Contract | `DELETE /rr/api/v1/contracts/{id}` | `POST /rr/api/v1/contracts/{id}/delete` |
| Contract subscription | `DELETE /rr/api/v1/contracts/{contract_id}/subscriptions/{id}` | `POST /rr/api/v1/contracts/{contract_id}/subscriptions/{id}/delete` |
| Contract milestone | `DELETE /rr/api/v1/contracts/{contract_id}/milestones/{id}` | `POST /rr/api/v1/contracts/{contract_id}/milestones/{id}/delete` |
| Contract usage revenue | `DELETE /rr/api/v1/contracts/{contract_id}/usage/{id}` | `POST /rr/api/v1/contracts/{contract_id}/usage/{id}/delete` |
| Prepaid commit | `DELETE /rr/api/v1/contracts/{contract_id}/prepaid-commits/{id}` | `POST /rr/api/v1/contracts/{contract_id}/prepaid-commits/{id}/delete` |
| Revenue transaction | `DELETE /rr/api/v1/transactions/{id}` | `POST /rr/api/v1/transactions/{id}/delete` |

### Payees

| Object | Deprecated | Use instead |
| - | - | - |
| Payee (vendor, customer or employee) | `DELETE /coa/api/vendor/{id}` | `POST /coa/api/vendor/{id}/delete` |

A payee delete returns `202 Accepted` and finishes in the background, the same as the `DELETE` route.

Other delete endpoints don't change yet. When more of them move to `POST /delete`, we'll announce them in the [changelog](https://docs.campfire.ai/changelog.md) with the same notice.

The new routes need the same permissions as the `DELETE` routes they replace.

## Updating your requests

**1. Change the method and path**

Send `POST` instead of `DELETE`, and add `/delete` to the end of the object's path.

```bash theme={null}
# Before
curl -X DELETE https://api.meetcampfire.com/coa/api/department/5 \
  -H "Authorization: Token $CAMPFIRE_API_KEY"

# After
curl -X POST https://api.meetcampfire.com/coa/api/department/5/delete \
  -H "Authorization: Token $CAMPFIRE_API_KEY"
```

Query parameters carry over unchanged: `new_account`, `new_department`, `new_tag`, `new_product` and `new_vendor` work on the `POST` routes just as they did on the `DELETE` routes. For example, to reassign a department's records to department 7 before deleting it:

```bash theme={null}
curl -X POST "https://api.meetcampfire.com/coa/api/department/5/delete?new_department=7" \
  -H "Authorization: Token $CAMPFIRE_API_KEY"
```

**2. Add a reason (optional)**

To record why the object is being deleted, send a JSON body with a `reason`. The body is optional: leave it out, or send an empty `reason`, to delete without one.

| Field | Description | Example |
| - | - | - |
| `reason` | Why the object is being deleted (optional). Up to 500 characters, and it can't contain NUL characters. | `"Duplicate of the Sales department"` |

```bash theme={null}
curl -X POST https://api.meetcampfire.com/coa/api/department/5/delete \
  -H "Authorization: Token $CAMPFIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Duplicate of the Sales department"}'
```

A reason longer than 500 characters, or one containing NUL characters, returns `400 Bad Request`, and nothing is deleted.

**3. Handle the response**

The responses are the same as for the `DELETE` routes:

| Status | Meaning |
| - | - |
| `204 No Content` | The object was deleted. |
| `202 Accepted` | An approval workflow sent the delete to the draft queue. The object isn't deleted until the request is approved. |

Payee deletes are the exception: they always return `202 Accepted` with `{"detail": "Vendor deletion in progress"}`, and Campfire deletes the payee in the background.

## Approving a pending delete

When a delete returns `202`, approve it the same way as before: send the request again with `?draft_queue_id=<id>`, this time to the `POST` route. `<id>` is the `id` of the pending draft in the `202` response.

```bash theme={null}
curl -X POST "https://api.meetcampfire.com/coa/api/department/5/delete?draft_queue_id=123" \
  -H "Authorization: Token $CAMPFIRE_API_KEY"
```

## Where the reason shows up

Campfire saves the reason on the audit log entry for the delete. The Audit Log CSV export includes it in a **Reason** column.

> [!NOTE]
>
> **Need help?** Contact your Campfire support team and we're happy to help you build your best Campfire workflow!
