# Documents

### 5.1 Parties (customers): optional but recommended

A document may name an ad-hoc party inline (just `{"name": "..."}`), which is fine for walk-ins. For repeat customers create a party once and reference it, so the customer ledger stays coherent:

```bash
curl -X POST "$BASE/businesses/$BID/parties" -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{ "kind": "customer", "name": "דנה לוי", "phone": "0521111111", "email": "dana@example.com" }'
# → {"ok":true,"party":{"id":"...","key":"C00001",...}}

# list / update / record consent to digital documents:
curl -H "X-Api-Key: $KEY" "$BASE/businesses/$BID/parties?kind=customer"
curl -X PATCH "$BASE/businesses/$BID/parties/$PARTY_ID" -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d '{"phone":"0529999999"}'
curl -X POST "$BASE/businesses/$BID/parties/$PARTY_ID/consent" -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d '{"via":"checkout-checkbox"}'
```

`kind`: `"customer"` | `"supplier"` | `"both"`. The `consent` endpoint timestamps the party's agreement to receive documents digitally (מסמכים ממוחשבים). Record it once per customer if you deliver PDFs instead of paper.

### 5.2 Create a draft: `POST /businesses/:bid/documents`

```bash
curl -X POST "$BASE/businesses/$BID/documents" -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-8812" -d '{
  "docType": 320,
  "party": { "name": "דנה לוי", "phone": "0521111111" },
  "priceMode": "gross",
  "lines": [
    { "description": "איפור כלה", "quantity": 1, "unitPriceExVat": 120000 },
    { "description": "איפור מלווה", "quantity": 2, "unitPriceExVat": 35000 }
  ],
  "payments": [ { "method": 3, "amount": 190000 } ]
}'
# 201 → {"ok":true,"document":{"id":"...","status":"draft","docNumber":null,...}}
```

| Field | Notes |
|---|---|
| `docType` | 305 / 320 / 400 (330 only via the credit-note endpoint) |
| `party` | `{partyId}` to reference a saved party, or inline `{name, taxId?, phone?, email?, address?}`; omit entirely for an anonymous cash receipt |
| `lines` | Required for 305/320: `{description, quantity, unitPriceExVat}`. Optional per line: `sku`, `unit` (default "יחידה"), `lineDiscount` (agorot) |
| `priceMode` | `"net"` (the default: line prices are ex-VAT) or `"gross"`: the **same `unitPriceExVat`/`lineDiscount` fields carry VAT-inclusive amounts**, the document total anchors to the gross sum and VAT is derived. Gross is what a consumer-facing price list wants: in the example above the customer pays exactly ₪1,900.00 |
| `payments` | Required for 320/400: `{method, amount}` + optional `{dueDate, bankCode, branchCode, accountNumber, checkNumber, cardCompany, cardName, cardTxType}` |
| `note` | Free text (≤500 chars) printed on the document under the tables: remark, service context, terms. A credit note automatically carries its `reason` here |
| `documentDate`, `valueDate` | Default today (Asia/Jerusalem) |
| `discountAmount`, `withholdingAmount` | Document-level, agorot. Payments must cover the total **net of withholding** |
| `externalRef` | Idempotency (or the `Idempotency-Key` header) |

Payment `method` accepts a code or a string alias:

| Code | Alias | Label on the PDF |
|---|---|---|
| `1` | `"cash"` | מזומן |
| `2` | `"check"` / `"cheque"` | המחאה |
| `3` | `"card"` / `"credit"` | כרטיס אשראי |
| `4` | `"transfer"` / `"bank_transfer"` | העברה בנקאית |
| `5` | `"voucher"` | תווי קניה |
| `8` | `"standing_order"` | הוראת קבע |
| `9` | `"other"` | אחר |
| `91` | `"bit"` | ביט |
| `92` | `"paybox"` | פייבוקס |
| `93` | `"payment_app"` / `"app"` | אפליקציית תשלום |

Codes 91-93 are BillOS extensions so the printed document names the actual payment app; in the regulatory OPENFRMT export they are reported as `9` (אחר) per the ITA spec. Unknown values fall back to `9`.

Drafts are freely mutable: they are a "קובץ זמני", not a tax document; any rendering of a draft is watermarked "טיוטה" and carries no number:

```bash
curl -X PATCH  "$BASE/businesses/$BID/documents/$DOC_ID" -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d '{"lines":[...]}'
curl -X DELETE "$BASE/businesses/$BID/documents/$DOC_ID" -H "X-Api-Key: $KEY"
```

### 5.3 List / read

```bash
curl -H "X-Api-Key: $KEY" "$BASE/businesses/$BID/documents?status=issued&docType=320&from=2026-07-01&to=2026-07-31"
curl -H "X-Api-Key: $KEY" "$BASE/businesses/$BID/documents/$DOC_ID"
```

### 5.3½ Preview a draft: `POST /businesses/:bid/documents/:id/preview`

Returns the draft rendered as a **"טיוטה"-watermarked PDF** (raw `application/pdf` bytes) so your user can see exactly how the document will look **before** the irreversible issue. Nothing is recorded and no number is consumed. Optional body `{"branding": {...}}` overrides the stored branding for this render. Drafts only: an issued document's PDFs are frozen; download those via `prints` (`409 not_draft` otherwise).

```bash
curl -X POST "$BASE/businesses/$BID/documents/$DOC_ID/preview" -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" -d '{}' -o preview.pdf
```

### 5.4 Issue: `POST /businesses/:bid/documents/:id/issue`

The point of no return. Assigns the next gapless document number, freezes a full snapshot, renders the PDF and signs it digitally.

```bash
curl -X POST "$BASE/businesses/$BID/documents/$DOC_ID/issue" -H "X-Api-Key: $KEY"
# 201 → {"ok":true,"document":{"docNumber":1071,"status":"issued","totalIncVat":190000,"vatAmount":28983,...}}
```

- Totals are recomputed server-side at issue from the frozen lines, so what you get back is authoritative.
- Issuing twice is safe: the second call returns the same document with `"deduped": true`.
- Optional body `{"branding": {...}}` overrides the business's stored branding for this document only (same fields as the branding section above); omit it to use the stored defaults.
- If PDF rendering hiccups, the document is **still legally issued** (numbering never rolls back); the PDF is rendered by a background retry, and `prints` returns `pdf_pending` until it's ready.

### 5.5 Correct: `POST /businesses/:bid/documents/:id/credit-note`

The only way to "cancel" an issued 305/320. Issues a linked חשבונית מס זיכוי (330) mirroring the original amounts; for a receipt (400) it issues a negative receipt.

```bash
curl -X POST "$BASE/businesses/$BID/documents/$DOC_ID/credit-note" -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" -d '{"reason":"הזמנה בוטלה"}'
# 201 → the new credit document, back-linked to the original
```

### 5.6 Get the PDF: `POST /businesses/:bid/documents/:id/prints`

Returns raw `application/pdf` bytes. `kind` is one of:

- `"auto"`: **recommended.** The origin (מקור) on the first ever print, a copy (העתק) on every print after; never errors on a repeat request. The `X-Print-Variant` response header (`origin` | `copy`) says which one you got, so deliver an `origin` straight to the end customer.
- `"origin"`: explicitly the מקור. Succeeds exactly once per document; a second call returns `400 {"error":"origin_already_printed"}`.
- `"copy"` (default): a העתק-watermarked copy, any number of times.

```bash
# a "download PDF" button can always just send auto:
curl -X POST "$BASE/businesses/$BID/documents/$DOC_ID/prints" -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" -d '{"kind":"auto"}' -o invoice.pdf
```

`409 {"reason":"pdf_pending"}` → the PDF isn't rendered yet (rare, right after issue); retry with backoff; the origin is **never consumed** by a `pdf_pending` response. PDFs are PAdES-signed with a per-business certificate chained to the BillOS CA. Fetch the CA certificate at `GET https://api.billos.co.il/ca.pem` to verify signatures.

### 5.7 Allocation numbers (מספר הקצאה, חשבוניות ישראל)

Under the חשבוניות ישראל reform, a tax invoice (305/320) needs an allocation number from the Tax Authority when **all** of these hold: the amount before VAT exceeds the statutory threshold (**₪5,000 since June 2026**), the invoice carries VAT, and the buyer is an identified business, which needs the number to deduct input VAT. Credit notes (330) don't require one.

BillOS applies the same conditions at issue: by default it issues with an `allocation_missing` warning; if the business opts into strict mode (`PATCH /businesses/:bid {"requireAllocation": true}`), issue returns `422 allocation_required` instead. Obtain the number (today: via the Tax Authority's website or your own ITA API integration) and supply it as `allocationNumber` on the draft, and it prints on the document under "מספר הקצאה". Most consumer-facing flows (B2C, receipts) never hit the threshold.