# Import a document from your previous software

`POST /businesses/{bid}/legacy-documents`

Requires the `documents` scope.

Files one document the business issued with the system it used before BillOS: the metadata as that system printed it, then (a second call) the original file. Re-runnable: the same `source` + `docNumber` under a business updates the row and answers `200` with `deduped: true` instead of creating a second one, so an import that stopped halfway is simply run again.

A legacy document is NOT a BillOS document: it takes no number from any series, is never signed or re-rendered, and never enters the מבנה אחיד, the VAT return, the reports or a credit note. It was issued by another registered software under its own numbering; the one bridge is `startNumbers` on `POST /businesses`, which continues that numbering here.

## Path parameters

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

## Body

| Field | Type | | Description |
|---|---|---|---|
| `source` | string | **required** | Slug of the system: `morning`, `icount`, `greeninvoice`, `ezcount`, `rivhit`, `sumit`, `hashavshevet`, `priority`, or any `a-z0-9_-` slug. |
| `docNumber` | string | **required** | Their number, as printed (up to 40 characters). |
| `issuedOn` | string | **required** | YYYY-MM-DD, not in the future. |
| `docType` | integer |  | The ITA code when you know it (305 tax invoice, 320 invoice-receipt, 400 receipt, 330 credit note, 300 proforma). |
| `docKind` | string |  | Otherwise, the previous system's own label for the kind (up to 60 characters). One of docType / docKind is required. |
| `partyName` | string |  |  |
| `partyTaxId` | string |  |  |
| `currency` | string |  | Default ILS. |
| `totalIncVat` | integer | **required** | Minor units, VAT included; negative for a refund. |
| `vatAmount` | integer |  | Minor units. |
| `note` | string |  | Up to 500 characters. |

## Response

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

| Field | Type | | Description |
|---|---|---|---|
| `ok` | boolean | **required** |  |
| `document` | LegacyDocument | **required** | A document issued by the software the business used before BillOS: its metadata as that system printed it, and the original file. Not a BillOS document: no number from any series, no signature, absent from every export and report. |
| `deduped` | boolean |  | true when the row existed and was updated (then the status is 200). |

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/legacy-documents" \
  -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "string",
    "docNumber": "string",
    "issuedOn": "2026-07-15",
    "totalIncVat": 0
  }'
```
### Node

```node
const res = await fetch(`${BASE}/businesses/${BID}/legacy-documents`, {
  method: 'POST',
  headers: {
    'X-Api-Key': KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "source": "string",
    "docNumber": "string",
    "issuedOn": "2026-07-15",
    "totalIncVat": 0
  }),
})
const data = await res.json()
if (!data.ok) throw new Error(data.reason)
```
### Python

```python
import requests
res = requests.post(
    f"{BASE}/businesses/{BID}/legacy-documents",
    headers={"X-Api-Key": KEY},
    json={
      "source": "string",
      "docNumber": "string",
      "issuedOn": "2026-07-15",
      "totalIncVat": 0
    },
)
data = res.json()
```