BillOS v1
Console llms.txt OpenAPI
POST/businesses/{bid}/documents

Create a draft

POST /businesses/{bid}/documents

Requires the documents scope.

A draft is a קובץ זמני, not a tax document: no number is consumed and any rendering of it is watermarked "טיוטה". Patch and delete it freely until you issue.

Always send an idempotency key. A double-click or a network retry then returns the same draft with deduped: true instead of opening a second one.

Path parameters

NameTypeDescription
bidstringrequiredBusiness id, from POST /businesses.

Headers

NameTypeDescription
Idempotency-KeystringYour own stable id for this call. A retry returns the same row with deduped: true instead of creating a duplicate. Interchangeable with externalRef in the body.

Body

FieldTypeDescription
docTypeintegerrequired300 (proforma, חשבונית עסקה: a demand for payment, numbered and immutable but not a tax document and never income) / 305 / 320 / 400. A 330 is created only through the credit-note endpoint. One of: 300, 305, 320, 400.
partyobject{partyId} to reference a saved party, or an inline {name, taxId?, phone?, email?, address?}. Omit entirely for an anonymous cash receipt.
party.partyIdstring
party.namestring
party.taxIdstring
party.phonestring
party.emailstring
party.addressstring
priceModestringnet (the default: line prices are ex-VAT) or gross (line prices include VAT; the total anchors to the gross sum and VAT is derived). Gross is what a consumer-facing price list wants. One of: net, gross. Default net.
linesarray of DocumentLineRequired for 305/320.
paymentsarray of PaymentRequired for 320/400.
notestring≤500 chars.
documentDatestringDefaults to today, Asia/Jerusalem.
valueDatestringDefaults to today.
discountAmountintegerDocument-level discount. Integer agorot (₪1 = 100).
withholdingAmountintegerניכוי במקור. Integer agorot (₪1 = 100).
currencystringDenominate the document in a foreign currency. Then every amount in this body (lines, discounts, payments) is in that currency's minor unit (cents, not agorot) and the ledger converts to shekels at issue. One of: ILS, USD, EUR, GBP, CHF, AUD, CAD. Default ILS.
fxRatenumberILS per 1 unit of currency: your own rate (the bank's conversion, a contract rate). Omit to use the Bank of Israel שער יציג of the document date, fetched at issue; if none can be had the issue answers fx_rate_required.
fxRateDatestringThe day your fxRate is from, printed beside it.
zeroVatbooleanState מע"מ בשיעור אפס (סעיף 30(א) לחוק מע"מ: a service to a foreign resident, export). Lines carry 0% VAT and the document prints the legal basis. Your claim; BillOS does not check the conditions. Ignored on a receipt or for a עוסק פטור.
langstringPrint the document in English (en): an LTR page, English labels, dates as September 4, 2026, the email that carries it in English too. The legal marks (מסמך ממוחשב, מקור/העתק, the signature line) stay in Hebrew beside their English. Line descriptions and notes print as you send them. One of: he, en. Default he.
brandingThemeIdstringThe branding theme it prints in (GET /businesses/{bid}/branding-themes). Omit or null for the customer's default, else the main design; "main" for the main design whatever the customer's default. Frozen at issue: the issued row names the theme it used, null for the main design.
allocationNumberstringמספר הקצאה, when you already hold one.
dueDatestringThe payment term (לתשלום עד) to print on a 305/300; ages the receivable.
settlesarray of objectOn a receipt (400): the issued invoices (305) or proformas (300) this receipt pays, each with an optional agorot amount; without one the receipt covers as much of the balance as it can, in order. Checked at issue against the balances of that moment. Printed on the receipt as "על חשבון". Same customer only.
externalRefstringIdempotency key, interchangeable with the Idempotency-Key header.

Response

201: { "ok": true, … }

FieldTypeDescription
okbooleanrequired
documentDocumentrequiredA draft is freely mutable. An issued document is immutable forever, blocked at the database engine, not merely in application code.
dedupedbooleanPresent and true when this call matched an earlier one.

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).

POST /businesses/{bid}/documents
curl -X POST "$BASE/businesses/$BID/documents" \
  -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "docType": 320,
    "party": {
      "name": "דנה לוי",
      "taxId": "514667426",
      "phone": "0521111111",
      "email": "dana@example.com",
      "address": "הרצל 12, תל אביב"
    },
    "priceMode": "gross",
    "lines": [
      {
        "description": "איפור כלה",
        "quantity": 1,
        "unitPriceExVat": 120000
      }
    ],
    "payments": [
      {
        "method": 3,
        "amount": 120000
      }
    ],
    "externalRef": "order-8812"
  }'
const res = await fetch(`${BASE}/businesses/${BID}/documents`, {
  method: 'POST',
  headers: {
    'X-Api-Key': KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "docType": 320,
    "party": {
      "name": "דנה לוי",
      "taxId": "514667426",
      "phone": "0521111111",
      "email": "dana@example.com",
      "address": "הרצל 12, תל אביב"
    },
    "priceMode": "gross",
    "lines": [
      {
        "description": "איפור כלה",
        "quantity": 1,
        "unitPriceExVat": 120000
      }
    ],
    "payments": [
      {
        "method": 3,
        "amount": 120000
      }
    ],
    "externalRef": "order-8812"
  }),
})
const data = await res.json()
if (!data.ok) throw new Error(data.reason)
import requests
res = requests.post(
    f"{BASE}/businesses/{BID}/documents",
    headers={"X-Api-Key": KEY},
    json={
      "docType": 320,
      "party": {
        "name": "דנה לוי",
        "taxId": "514667426",
        "phone": "0521111111",
        "email": "dana@example.com",
        "address": "הרצל 12, תל אביב"
      },
      "priceMode": "gross",
      "lines": [
        {
          "description": "איפור כלה",
          "quantity": 1,
          "unitPriceExVat": 120000
        }
      ],
      "payments": [
        {
          "method": 3,
          "amount": 120000
        }
      ],
      "externalRef": "order-8812"
    },
)
data = res.json()
Set BASE to https://api.billos.co.il/v1 and KEY to your bk_live_… key, or a bk_test_… key to run it against the sandbox.
Manage your businesses, keys and webhooks in the BillOS Console.