---
title: "Hang up a leg (asynchronous)"
method: DELETE
path: "/legs/{id}"
tags: ["Legs"]
---

# Hang up a leg (asynchronous)

`DELETE /legs/{id}`

Validates the leg exists and queues a hangup. The HTTP call returns 202 as soon as the leg is found; the SIP work and cleanup run in the background, and the eventual disconnection is observed via the `leg.disconnected` event.

Without a request body the legacy behavior is preserved: SIP BYE on connected legs (`cdr.reason: "api_hangup"`), or dialog cancel on unanswered inbound legs (`cdr.reason: "caller_cancel"`).

With `{"reason": "<value>"}` and an unanswered SIP inbound leg (state `ringing` or `early_media`), VoiceBlender sends a final non-2xx response instead of BYE/cancel: `busy`→486, `declined`/`rejected`→603, `unavailable`→480, `not_found`→404, `forbidden`→403, `server_error`→500. The reason value is passed through to `leg.disconnected`'s `cdr.reason`.

For connected legs the request body is ignored.

## Request body

- DeleteLegRequest
  - `reason` 'busy' | 'declined' | 'rejected' | 'unavailable' | 'not_found' | 'forbidden' | 'server_error' — Disconnect reason. Only honored for unanswered SIP inbound legs (state `ringing` or `early_media`); on connected legs the body is ignored and the leg is hung up with the legacy `api_hangup` reason. The value flows through to `leg.disconnected`'s `cdr.reason` and selects the SIP final response: `busy`→486, `declined`/`rejected`→603, `unavailable`→480, `not_found`→404, `forbidden`→403, `server_error`→500.

## Response `202`

Hangup queued

## Other responses

- `400` — Unknown reason value
- `404` — Leg not found

---

[API](https://skmtc.net/voiceblender/apis/voiceblender-api.md) · [All operations](https://skmtc.net/voiceblender/apis/voiceblender-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/voiceblender/voiceblender-api/versions/ad30827d3b57/schema)
