# Withdraw a quote

`POST /businesses/{bid}/quotes/{id}/cancel`

Requires the `documents` scope.

The public link stops answering (the token is cleared, not kept: a withdrawn offer whose link still renders it is the customer's evidence that it stood). The row and its history stay, and `reopen` puts it back.

## Path parameters

| Name | Type | | Description |
|---|---|---|---|
| `bid` | string | **required** | Business id, from `POST /businesses`. |
| `id` | string | **required** | Quote id. |

## Response

`200`: `{ "ok": true, … }`

| Field | Type | | Description |
|---|---|---|---|
| `ok` | boolean | **required** |  |
| `quote` | Quote | **required** | הצעת מחיר: an OFFER, and deliberately not a document: it carries no statutory number, it is freely editable and deletable, and it appears in no export, no VAT return and no income report. What it becomes when the customer accepts is an ordinary draft document (`POST .../convert`). |

Errors: `400`, `401`, `403`, `404`, `429`. Every failure answers `{ "error", "reason", "hint", "param", "doc_url", "retryable", "request_id" }`: branch on `reason`, and read `hint` for what to change (https://docs.billos.co.il/errors.md).

## Examples

### cURL

```bash
curl -X POST "$BASE/businesses/$BID/quotes/$DOC_ID/cancel" \
  -H "X-Api-Key: $KEY"
```
### Node

```node
const res = await fetch(`${BASE}/businesses/${BID}/quotes/${DOC_ID}/cancel`, {
  method: 'POST',
  headers: {
    'X-Api-Key': KEY,
  },
})
const data = await res.json()
if (!data.ok) throw new Error(data.reason)
```
### Python

```python
import requests
res = requests.post(
    f"{BASE}/businesses/{BID}/quotes/{DOC_ID}/cancel",
    headers={"X-Api-Key": KEY},
)
data = res.json()
```