{"openapi":"3.1.0","info":{"title":"BillOS API","version":"1.0.0","summary":"Israeli tax documents and bookkeeping, as a JSON HTTP API.","description":"BillOS is a bookkeeping service registered with the Israel Tax Authority software registry (תעודה 269101). It issues legally valid Israeli tax documents with gapless numbering, digital signatures, an immutable audit trail, and the regulatory OPENFRMT (מבנה אחיד) export.\n\nYour app talks JSON; BillOS takes care of the compliance.","contact":{"name":"BillOS","url":"https://docs.billos.co.il"}},"servers":[{"url":"https://api.billos.co.il/v1","description":"Production"}],"tags":[{"name":"Businesses","description":"One business per end user. Every other path is nested under its id."},{"name":"Parties","description":"Saved customers. Optional: a document may carry an inline party instead."},{"name":"Documents","description":"The tax documents themselves: draft, issue, correct, print."},{"name":"Expenses","description":"The purchase side of the ledger, including receipt OCR."},{"name":"Exports & Reports","description":"מבנה אחיד, continuity, management reports, backups, file downloads."},{"name":"Webhooks","description":"Events pushed to your URL: the trigger side of Make/Zapier-style automations. Signed, retried with backoff, testable."}],"security":[{"ApiKey":[]}],"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Keys look like `bk_live_…` (production) or `bk_test_…` (the sandbox: a separate database, see the Sandbox guide) and are shown exactly once when issued, because only a hash is stored. Every response carries `X-BillOS-Mode: live|sandbox`. **Server-side only**: never ship a key in a mobile app or a browser bundle.\n\nScopes: `businesses`, `documents`, `expenses`, `export`, `ocr`. `ocr` is granted separately because every scan runs a billed AI call."}},"schemas":{"Error":{"type":"object","description":"Every failure answers with this shape and the matching HTTP status.","properties":{"error":{"type":"string","description":"Human-readable message. Safe to log, not to show a user verbatim."},"reason":{"type":"string","description":"Stable machine code. Branch on this, never on `error`.","enum":["not_found","validation","doc_type_not_allowed","payments_mismatch","not_draft","conflict","pdf_pending","allocation_required","rate_limited","quota_exceeded","too_large","forbidden","unconfigured","provider","internal"]}},"required":["reason"]},"Business":{"type":"object","description":"One Israeli dealer (עוסק), one of your end users.","properties":{"id":{"type":"string","description":"Business id, the `:bid` in every other path."},"name":{"type":"string","description":"Legal business name, printed on every document."},"taxId":{"type":"string","description":"ח.פ / ע.מ / ת.ז. Checksum-validated on write."},"dealerType":{"type":"string","description":"Decides which document types are allowed.","enum":["patur","murshe","company","ngo"]},"address":{"type":"string","description":"Printed on documents."},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"defaultVatRateBp":{"type":"integer","description":"VAT rate in basis points. 1800 = 18%."},"requireAllocation":{"type":"boolean","description":"Strict mode: issue fails with `allocation_required` instead of warning."},"branding":{"$ref":"#/components/schemas/Branding"},"approvalStatus":{"type":"string","description":"Account standing, set by BillOS. Businesses created under an API key are `approved`; `pending` was never approved and `suspended` was shut by us. Both answer `approval_required` (403) on issue, expense recording and uploads.","enum":["approved","pending","suspended"]},"planKey":{"type":"string","description":"The named tier this business is on, or null for the free defaults. A plan supplies the ceilings below; an account-level override wins over it."},"maxDocsPerMonth":{"type":"integer","description":"Monthly ceiling on issued documents actually in force. null = unlimited. At the ceiling, issue answers `limit_reached` (429) until the next calendar month."},"maxExpensesPerMonth":{"type":"integer","description":"Monthly ceiling on expense rows opened (uploads included). null = unlimited; `limit_reached` (429) at the ceiling."},"deactivatedAt":{"type":"string","description":"Set by your own deactivate call. While set, every write on the business is refused; reads keep working.","format":"date-time"},"createdAt":{"type":"string","description":"","format":"date-time"}},"required":["id","name","taxId","dealerType"]},"Branding":{"type":"object","description":"Appearance of the rendered PDF. Stored once per business; a logo is stored as a file and referenced by hash, never re-frozen into each document.","properties":{"logo":{"type":"string","description":"Base64 data URI, ≤400KB. Write-only: reads return `logoRef`."},"logoRef":{"type":"object","description":"What a stored logo reads back as.","properties":{"fileId":{"type":"string","description":""},"sha256":{"type":"string","description":""},"mime":{"type":"string","description":""}}},"accentColor":{"type":"string","description":"Hex, e.g. `#1F6B4A`. The classic design paints the table head with it; the minimal one spends it on links only."},"tagline":{"type":"string","description":"One line under the business name (≤120 chars)."},"website":{"type":"string","description":"Printed as a link in the business block (≤200 chars)."},"footerText":{"type":"string","description":"Printed at the bottom of every document."},"template":{"type":"string","description":"The page design. `classic` (the default: the business header, accent table head and stamp) or `stripe` (the minimal Stripe-receipt layout: hairlines, one headline amount, no fills). Frozen into each document at issue, like the rest of the branding.","enum":["classic","stripe"]}}},"Party":{"type":"object","description":"A saved customer. Optional: a document may carry an inline party instead.","properties":{"id":{"type":"string","description":""},"key":{"type":"string","description":"Human-facing running key: `C00001` for customers, `S00001` for suppliers."},"kind":{"type":"string","description":"","enum":["customer","supplier","both"]},"name":{"type":"string","description":""},"taxId":{"type":"string","description":"Required for an identified buyer on an allocation-eligible invoice."},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"address":{"type":"string","description":""},"digitalDocConsentAt":{"type":"string","description":"When the party consented to receiving documents digitally (מסמכים ממוחשבים).","format":"date-time","nullable":true}},"required":["id","name"]},"DocumentLine":{"type":"object","properties":{"description":{"type":"string","description":"Printed line text."},"quantity":{"type":"number","description":"May be fractional."},"unitPriceExVat":{"type":"integer","description":"Unit price. Under `priceMode: \"gross\"` this field carries the VAT-INCLUSIVE price despite the name. Integer agorot (₪1 = 100)."},"sku":{"type":"string","description":"Optional catalogue code."},"unit":{"type":"string","description":"Default `יחידה`."},"lineDiscount":{"type":"integer","description":"Optional per-line discount. Integer agorot (₪1 = 100)."}},"required":["description","quantity","unitPriceExVat"]},"Payment":{"type":"object","description":"How the money arrived. Required for 320 and 400.","properties":{"method":{"description":"Code or string alias. 91-93 are BillOS extensions so the PDF can name the actual app; they are reported as `9` in the OPENFRMT export.","oneOf":[{"type":"integer","enum":[1,2,3,4,5,8,9,91,92,93]},{"type":"string","enum":["cash","check","cheque","card","credit","transfer","bank_transfer","voucher","standing_order","other","bit","paybox","payment_app","app"]}]},"amount":{"type":"integer","description":"Amount paid by this method. Integer agorot (₪1 = 100)."},"dueDate":{"type":"string","description":"","format":"date"},"bankCode":{"type":"string","description":""},"branchCode":{"type":"string","description":""},"accountNumber":{"type":"string","description":""},"checkNumber":{"type":"string","description":""},"cardCompany":{"type":"string","description":""},"cardName":{"type":"string","description":""},"cardTxType":{"type":"string","description":""}},"required":["method","amount"]},"Document":{"type":"object","description":"A draft is freely mutable. An issued document is immutable forever, blocked at the database engine, not merely in application code.","properties":{"id":{"type":"string","description":""},"status":{"type":"string","description":"","enum":["draft","issued"]},"docType":{"type":"integer","description":"305 tax invoice · 320 invoice/receipt · 330 credit note · 400 receipt.","enum":[305,320,330,400]},"docNumber":{"type":"integer","description":"Assigned at issue, gapless per type. `null` while draft.","nullable":true},"allocationNumber":{"type":"string","description":"מספר הקצאה from the Tax Authority. Set once, never changed.","nullable":true},"party":{"$ref":"#/components/schemas/Party"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/DocumentLine"}},"payments":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"note":{"type":"string","description":"Free text ≤500 chars, printed under the tables."},"documentDate":{"type":"string","description":"","format":"date"},"valueDate":{"type":"string","description":"","format":"date"},"totalExVat":{"type":"integer","description":"Recomputed server-side at issue, and authoritative. Integer agorot (₪1 = 100)."},"vatAmount":{"type":"integer","description":" Integer agorot (₪1 = 100)."},"totalIncVat":{"type":"integer","description":" Integer agorot (₪1 = 100)."},"discountAmount":{"type":"integer","description":"Document-level discount. Integer agorot (₪1 = 100)."},"withholdingAmount":{"type":"integer","description":"Payments must cover the total net of this. Integer agorot (₪1 = 100)."},"linkedDocumentId":{"type":"string","description":"For a credit note: the document it corrects.","nullable":true},"externalRef":{"type":"string","description":"Your idempotency key, echoed back.","nullable":true},"issuedAt":{"type":"string","description":"","format":"date-time","nullable":true},"createdAt":{"type":"string","description":"","format":"date-time"}},"required":["id","status","docType"]},"DocumentDraftInput":{"type":"object","description":"Create or patch a draft. Everything is optional on PATCH.","properties":{"docType":{"type":"integer","description":"305 / 320 / 400. A 330 is created only through the credit-note endpoint.","enum":[305,320,400]},"party":{"description":"`{partyId}` to reference a saved party, or an inline `{name, taxId?, phone?, email?, address?}`. Omit entirely for an anonymous cash receipt.","type":"object","properties":{"partyId":{"type":"string","description":""},"name":{"type":"string","description":""},"taxId":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"address":{"type":"string","description":""}}},"priceMode":{"type":"string","description":"`net` (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.","enum":["net","gross"],"default":"net"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/DocumentLine"},"description":"Required for 305/320."},"payments":{"type":"array","items":{"$ref":"#/components/schemas/Payment"},"description":"Required for 320/400."},"note":{"type":"string","description":"≤500 chars."},"documentDate":{"type":"string","description":"Defaults to today, Asia/Jerusalem.","format":"date"},"valueDate":{"type":"string","description":"Defaults to today.","format":"date"},"discountAmount":{"type":"integer","description":"Document-level discount. Integer agorot (₪1 = 100)."},"withholdingAmount":{"type":"integer","description":"ניכוי במקור. Integer agorot (₪1 = 100)."},"allocationNumber":{"type":"string","description":"מספר הקצאה, when you already hold one."},"externalRef":{"type":"string","description":"Idempotency key, interchangeable with the `Idempotency-Key` header."}},"required":["docType"]},"Expense":{"type":"object","description":"The purchase side of the ledger. A recorded expense is immutable; correct it with a storno.","properties":{"id":{"type":"string","description":""},"status":{"type":"string","description":"","enum":["draft","recorded"]},"supplierName":{"type":"string","description":""},"supplierTaxId":{"type":"string","description":""},"documentDate":{"type":"string","description":"","format":"date"},"documentNumber":{"type":"string","description":"The supplier's own document number."},"amountIncVat":{"type":"integer","description":"GROSS, VAT included. Israeli prices include VAT. Integer agorot (₪1 = 100)."},"vatAmount":{"type":"integer","description":"The portion INSIDE the gross. Never add it to `amountIncVat`. Integer agorot (₪1 = 100)."},"deductibleVatBp":{"type":"integer","description":"How much of the VAT is deductible, in basis points. 10000 = all of it."},"currency":{"type":"string","description":"Currency of `amountIncVat`, ISO 4217. Always ILS for what the ledger records."},"docAmount":{"type":"integer","description":"For a document in another currency: its own gross, in that currency's minor unit (cents). Null for a shekel document.","nullable":true},"docCurrency":{"type":"string","description":"ISO 4217 code of `docAmount`. Null for a shekel document.","nullable":true},"fxRate":{"type":"number","nullable":true,"description":"ILS per unit of `docCurrency` used to derive `amountIncVat`. Evidence, never recomputed."},"categoryKey":{"type":"string","description":"Ledger category."},"fileId":{"type":"string","description":"Attached receipt image or PDF.","nullable":true},"extracted":{"$ref":"#/components/schemas/OcrExtraction"},"createdAt":{"type":"string","description":"","format":"date-time"}},"required":["id","status"]},"OcrExtraction":{"type":"object","description":"What the vision model read off the receipt. Advisory: the operator confirms before recording.","properties":{"supplierName":{"type":"string","description":""},"supplierTaxId":{"type":"string","description":""},"documentNumber":{"type":"string","description":""},"documentDate":{"type":"string","description":"","format":"date"},"amountIncVat":{"type":"integer","description":" Integer agorot (₪1 = 100)."},"vatAmount":{"type":"integer","description":" Integer agorot (₪1 = 100)."},"currency":{"type":"string","description":""},"confidence":{"type":"string","description":"","enum":["high","medium","low"]},"notes":{"type":"string","description":"What the model was unsure about."}}},"ExportRun":{"type":"object","description":"One OPENFRMT (מבנה אחיד) generation, with its verification summary.","properties":{"id":{"type":"string","description":""},"fromDate":{"type":"string","description":"","format":"date"},"toDate":{"type":"string","description":"","format":"date"},"summary":{"type":"object","description":"Record counts and control totals, per the spec.","additionalProperties":true},"createdAt":{"type":"string","description":"","format":"date-time"}}},"FileMeta":{"type":"object","properties":{"id":{"type":"string","description":""},"kind":{"type":"string","description":"e.g. `document_pdf_origin`, `export_zip`, `expense_receipt`."},"mime":{"type":"string","description":""},"size":{"type":"integer","description":"Bytes."},"sha256":{"type":"string","description":"Of the stored bytes."},"createdAt":{"type":"string","description":"","format":"date-time"}}},"ApiKey":{"type":"object","description":"One of the keys under your client. Never the hash. `current` marks the key this request used.","properties":{"id":{"type":"string","description":""},"keyPrefix":{"type":"string","description":"The first 12 characters: enough to tell keys apart, never enough to use one."},"label":{"type":"string","description":"Set by us at mint time (e.g. `initial`, `rotation 2026-09`)."},"current":{"type":"boolean","description":"This is the key that made the request."},"createdAt":{"type":"string","description":""},"lastUsedAt":{"type":"string","description":"Touched at most hourly."},"revokedAt":{"type":"string","description":""},"expiresAt":{"type":"string","description":""}}},"WebhookEndpoint":{"type":"object","description":"A webhook subscription. Deliveries are POSTed to `url`, signed with `secret` (see the Webhooks guide).","properties":{"id":{"type":"string","description":""},"url":{"type":"string","description":"HTTPS, publicly reachable."},"secret":{"type":"string","description":"HMAC-SHA256 signing secret (`whsec_…`). Retrievable: it signs deliveries, it does not authenticate you."},"events":{"type":"array","items":{"type":"string","enum":["document.issued","document.pdf_ready","document.allocation_assigned","expense.recorded","export.completed","business.status_changed"]},"description":"Events this endpoint receives. Empty = all."},"businessId":{"type":"string","description":"Present when narrowed to one business; null = every business under the key."},"active":{"type":"boolean","description":""},"consecutiveFailures":{"type":"integer","description":"Failures in a row across deliveries; any 2xx resets it."},"disabledAt":{"type":"string","description":"Set when auto-disabled after sustained failure. `PATCH {\"active\": true}` re-arms."},"lastSuccessAt":{"type":"string","description":""},"createdAt":{"type":"string","description":""}}},"WebhookDelivery":{"type":"object","description":"One attempt-tracked event delivery. The wire envelope carries this row's `id`. Dedupe on it.","properties":{"id":{"type":"string","description":"Also the envelope `id`."},"event":{"type":"string","description":""},"businessId":{"type":"string","description":""},"status":{"type":"string","description":"","enum":["pending","delivered","failed"]},"attempts":{"type":"integer","description":""},"nextAttemptAt":{"type":"string","description":"When the next retry is due (while pending)."},"lastStatus":{"type":"integer","description":"Last HTTP status from your endpoint; null = network error or timeout."},"lastError":{"type":"string","description":""},"deliveredAt":{"type":"string","description":""},"payload":{"description":"The event data, as sent under the envelope's `data`."},"createdAt":{"type":"string","description":""}}}}},"paths":{"/businesses":{"post":{"tags":["Businesses"],"operationId":"createBusiness","summary":"Create a business","description":"One business per end user. Everything else is nested under the id this returns.\n\nA business created with `lastInvoiceNumber` continues an existing numbering sequence. That is how you migrate a dealer off their previous software without restarting their document numbers.","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Legal business name."},"taxId":{"type":"string","description":"Checksum-validated."},"dealerType":{"type":"string","description":"","enum":["patur","murshe","company","ngo"]},"address":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"defaultVatRateBp":{"type":"integer","description":"Basis points. Defaults to the current statutory rate."},"lastInvoiceNumber":{"type":"integer","description":"Continue an existing sequence from this number."},"branding":{"$ref":"#/components/schemas/Branding"}},"required":["name","taxId","dealerType"]}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"business":{"$ref":"#/components/schemas/Business"}},"required":["ok","business"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Businesses"],"operationId":"listBusinesses","summary":"List your businesses","description":"Every business created under your key, newest first. Signing-key material is never included.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"businesses":{"type":"array","items":{"$ref":"#/components/schemas/Business"}}},"required":["ok","businesses"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"get":{"tags":["Businesses"],"operationId":"getBusiness","summary":"Read a business","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"business":{"$ref":"#/components/schemas/Business"}},"required":["ok","business"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Businesses"],"operationId":"updateBusiness","summary":"Update a business","description":"Profile, branding and `requireAllocation`. The tax id and dealer type of a business that has already issued documents are not editable.","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":""},"address":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"requireAllocation":{"type":"boolean","description":"Strict mode for allocation numbers."},"branding":{"$ref":"#/components/schemas/Branding"}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"business":{"$ref":"#/components/schemas/Business"}},"required":["ok","business"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/deactivate":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Businesses"],"operationId":"deactivateBusiness","summary":"Deactivate a business","description":"Your own pause switch on a tenant. A deactivated business keeps its data and its reads, but every write (drafts, issuing, expenses, uploads) is refused until you reactivate it. Distinct from `approvalStatus`, which only BillOS sets. Idempotent.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"business":{"$ref":"#/components/schemas/Business"}},"required":["ok","business"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/reactivate":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Businesses"],"operationId":"reactivateBusiness","summary":"Reactivate a business","description":"Clears a deactivation you set. Reactivating never grants anything `approvalStatus` does not: if BillOS suspended the account, writes stay refused. Idempotent.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"business":{"$ref":"#/components/schemas/Business"}},"required":["ok","business"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/parties":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Parties"],"operationId":"createParty","summary":"Create a party","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":""},"taxId":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"address":{"type":"string","description":""},"kind":{"type":"string","description":"Decides which running-key series the party gets: customers are numbered `C00001`, suppliers `S00001`.","enum":["customer","supplier","both"],"default":"customer"}},"required":["name"]}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"party":{"$ref":"#/components/schemas/Party"}},"required":["ok","party"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Parties"],"operationId":"listParties","summary":"List parties","security":[{"ApiKey":["businesses"]}],"parameters":[{"name":"kind","in":"query","schema":{"type":"string","enum":["customer","supplier","both"]},"description":"Filter by party kind. Omit for all."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"parties":{"type":"array","items":{"$ref":"#/components/schemas/Party"}}},"required":["ok","parties"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/parties/{id}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Party id."}],"patch":{"tags":["Parties"],"operationId":"updateParty","summary":"Update a party","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":""},"taxId":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"address":{"type":"string","description":""}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"party":{"$ref":"#/components/schemas/Party"}},"required":["ok","party"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/parties/{id}/consent":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Party id."}],"post":{"tags":["Parties"],"operationId":"recordPartyConsent","summary":"Record digital-document consent","description":"Stamps the party as having consented to receiving documents digitally (מסמכים ממוחשבים) rather than on paper. Required before you deliver a document by link or email.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"party":{"$ref":"#/components/schemas/Party"}},"required":["ok","party"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Documents"],"operationId":"createDocument","summary":"Create a draft","description":"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.\n\n**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.","security":[{"ApiKey":["documents"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Your 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."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDraftInput"}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"document":{"$ref":"#/components/schemas/Document"},"deduped":{"type":"boolean","description":"Present and true when this call matched an earlier one."}},"required":["ok","document"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Documents"],"operationId":"listDocuments","summary":"List documents","security":[{"ApiKey":["documents"]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","issued"]}},{"name":"docType","in":"query","schema":{"type":"integer","enum":[305,320,330,400]}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive, on document date."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive."},{"name":"take","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"},"description":"Time cursor: rows created strictly before this instant, newest first. To page, start with now and pass the last row's `createdAt`."},{"name":"externalRefPrefix","in":"query","schema":{"type":"string"},"description":"Only documents whose `externalRef` starts with this (every document filed under one of your own references, e.g. a job)."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Free-text search: party name, exact document number (digits), or a line description."},{"name":"partyId","in":"query","schema":{"type":"string"},"description":"Only documents filed against this party."},{"name":"skip","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Offset paging: rows to skip before `take`. Combine with `counts=1` for totals."},{"name":"counts","in":"query","schema":{"type":"string","enum":["1"]},"description":"Adds `counts: { total, byStatus }` over the same filters (minus `status`), so pages and count boxes agree."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}},"required":["ok","documents"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"get":{"tags":["Documents"],"operationId":"getDocument","summary":"Read a document","security":[{"ApiKey":["documents"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"document":{"$ref":"#/components/schemas/Document"}},"required":["ok","document"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Documents"],"operationId":"updateDocument","summary":"Update a draft","description":"Drafts only. An issued document answers `409 not_draft`; it is immutable at the database engine.","security":[{"ApiKey":["documents"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDraftInput"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"document":{"$ref":"#/components/schemas/Document"}},"required":["ok","document"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Documents"],"operationId":"deleteDocument","summary":"Delete a draft","description":"Drafts only. Issued documents are corrected with a credit note, never deleted.","security":[{"ApiKey":["documents"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/issue":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"issueDocument","summary":"Issue a document","description":"The point of no return. Assigns the next gapless number, freezes a full snapshot, renders the PDF and signs it.\n\nTotals are recomputed server-side from the frozen lines, so what comes back is authoritative. Issuing twice is safe and returns the same document with `deduped: true`. If rendering hiccups the document is still legally issued and `prints` answers `pdf_pending` until a background retry finishes; numbering never rolls back.","security":[{"ApiKey":["documents"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"branding":{"$ref":"#/components/schemas/Branding"}},"description":"Optional per-document branding override."}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"document":{"$ref":"#/components/schemas/Document"},"deduped":{"type":"boolean","description":""}},"required":["ok","document"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`allocation_required`: Invoice over the threshold needs an allocation number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/credit-note":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"issueCreditNote","summary":"Correct with a credit note","description":"The only way to undo an issued 305 or 320: issues a linked חשבונית מס זיכוי (330) mirroring the original amounts. For a receipt (400) it issues a negative receipt. Nothing is ever deleted (הוראה 23).","security":[{"ApiKey":["documents"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Printed on the credit note as its note."}}}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"document":{"$ref":"#/components/schemas/Document"}},"required":["ok","document"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/preview":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"previewDocument","summary":"Preview a draft as PDF","description":"The draft rendered as a \"טיוטה\"-watermarked PDF so your user sees exactly what they are about to issue. Nothing is recorded and no number is consumed. Drafts only.","security":[{"ApiKey":["documents"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"branding":{"$ref":"#/components/schemas/Branding"}}}}}},"responses":{"200":{"description":"Raw PDF bytes.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/prints":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"printDocument","summary":"Download the PDF","description":"Israeli law delivers the origin (מקור) exactly once, per הוראה 18(ב)2. `auto` is what a download button should send: it serves the origin on the first ever print and a copy forever after, so a repeat click never errors, and the `X-Print-Variant` header tells you which one you got.\n\nA `pdf_pending` response never consumes the origin.","security":[{"ApiKey":["documents"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","description":"`auto` recommended. `origin` succeeds exactly once per document. `copy` is watermarked העתק and unlimited.","enum":["auto","origin","copy"],"default":"copy"}}}}}},"responses":{"200":{"description":"Raw PDF bytes.","headers":{"X-Print-Variant":{"schema":{"type":"string","enum":["origin","copy"]},"description":"Which variant these bytes are."}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Expenses"],"operationId":"createExpense","summary":"Create an expense","description":"Opens a draft, or records in one call when the body is complete. `amountIncVat` is the GROSS (Israeli prices include VAT) and `vatAmount` is the portion inside it. Never add the two.","security":[{"ApiKey":["expenses"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Your 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."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"supplierName":{"type":"string","description":""},"supplierTaxId":{"type":"string","description":""},"documentDate":{"type":"string","description":"","format":"date"},"documentNumber":{"type":"string","description":""},"amountIncVat":{"type":"integer","description":"Gross, VAT included. Integer agorot (₪1 = 100)."},"vatAmount":{"type":"integer","description":"The portion inside the gross. Integer agorot (₪1 = 100)."},"deductibleVatBp":{"type":"integer","description":"Basis points; 10000 = fully deductible."},"currency":{"type":"string","description":"ISO 4217, default ILS."},"amountIls":{"type":"integer","description":"Required to record a non-ILS expense. Integer agorot (₪1 = 100)."},"fxRate":{"type":"number","description":"Rate used for `amountIls`."},"categoryKey":{"type":"string","description":""},"externalRef":{"type":"string","description":"Idempotency key."},"record":{"type":"boolean","description":"Record immediately instead of leaving a draft."}}}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"},"deduped":{"type":"boolean","description":""}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Expenses"],"operationId":"listExpenses","summary":"List expenses","security":[{"ApiKey":["expenses"]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","recorded"]}},{"name":"categoryKey","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}},{"name":"take","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"},"description":"Time cursor: rows created strictly before this instant, newest first. To page, start with now and pass the last row's `createdAt`."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Free-text search: supplier name or document number."},{"name":"skip","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Offset paging: rows to skip before `take`."},{"name":"counts","in":"query","schema":{"type":"string","enum":["1"]},"description":"Adds `counts: { total, byStatus }` over the same filters (minus `status`)."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expenses":{"type":"array","items":{"$ref":"#/components/schemas/Expense"}}},"required":["ok","expenses"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/share":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"shareDocument","summary":"Get the public PDF link","description":"The no-login link to the same PDF `prints` serves, for a WhatsApp or email hand-off: the host streams it at `path` (`/api/docs/<slug>/d.pdf`). It IS a print: `auto` hands out the origin exactly once and the copy after that (הוראה 18(ב)2), so `variant` says which one the link carries.","security":[{"ApiKey":["documents"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","description":"`auto` recommended.","enum":["auto","origin","copy"],"default":"auto"}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"variant":{"type":"string","description":"","enum":["origin","copy"]},"fileId":{"type":"string","description":""},"slug":{"type":"string","description":"The public capability."},"path":{"type":"string","description":"Host path that streams the PDF."}}}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/documents/{id}/email":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document id."}],"post":{"tags":["Documents"],"operationId":"emailDocument","summary":"Email the document link","description":"Sends the public PDF link to up to 5 addresses in a BillOS-branded email, one email per address. Sending IS a print (`auto`): the origin exactly once, the copy after (הוראה 18(ב)2). Issued (or cancelled) documents only; not available in sandbox; rate-limited (BOOKS_EMAIL_RATE_PER_MIN, default 10/min).","security":[{"ApiKey":["documents"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to"],"properties":{"to":{"type":"array","maxItems":5,"items":{"type":"string","format":"email"},"description":"Recipient addresses (1-5)."}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"sent":{"type":"array","items":{"type":"string","description":""}},"failed":{"type":"array","items":{"type":"string","description":""}},"variant":{"type":"string","description":"","enum":["origin","copy"]},"url":{"type":"string","description":"The public PDF link the email carries."}}}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/parties/find-or-create":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Parties"],"operationId":"findOrCreateParty","summary":"Find a party or create it","description":"Matches an existing party by phone (last nine digits) and then by exact name; creates one otherwise. 201 when created, 200 when found; `created` says which.","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"kind":{"type":"string","description":"","enum":["customer","supplier","both"],"default":"customer"},"name":{"type":"string","description":""},"taxId":{"type":"string","description":""},"phone":{"type":"string","description":""},"email":{"type":"string","description":""},"address":{"type":"object"}}}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"party":{"$ref":"#/components/schemas/Party"},"created":{"type":"boolean","description":"True when this call created the party."}},"required":["ok","party"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses/record":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Expenses"],"operationId":"recordExpenseDirect","summary":"Create and record in one call","description":"A complete receipt in hand and no draft to keep: the same `input` the record step takes, recorded in one round-trip. Idempotent on the key.","security":[{"ApiKey":["expenses"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Your 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."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["input"],"properties":{"input":{"type":"object","description":"Same fields as creating an expense."}}}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses/{id}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Expense id."}],"delete":{"tags":["Expenses"],"operationId":"deleteExpenseDraft","summary":"Discard a draft","description":"A draft is yours to discard. A recorded expense is a ledger entry and can only be corrected (storno), so this answers 404.","security":[{"ApiKey":["expenses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Expenses"],"operationId":"getExpense","summary":"Read an expense","description":"Includes the raw OCR extraction when the row came from a scan.","security":[{"ApiKey":["expenses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Expenses"],"operationId":"updateExpense","summary":"Update a draft expense","security":[{"ApiKey":["expenses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Expense"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses/{id}/record":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Expense id."}],"post":{"tags":["Expenses"],"operationId":"recordExpense","summary":"Record an expense","description":"Writes the immutable ledger row. A non-ILS expense without `amountIls` is refused: the ledger sums agorot without looking at currency, and the row cannot be edited afterwards.","security":[{"ApiKey":["expenses"]}],"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses/{id}/correction":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Expense id."}],"post":{"tags":["Expenses"],"operationId":"correctExpense","summary":"Correct with a storno","description":"A recorded expense is immutable; a correction writes a reversing row (הוראה 23). Pass `redraft: true` to also open a fresh DRAFT carrying the same fields and a copy of the receipt file: fix it and record again. The storno stands even if the draft fails.","security":[{"ApiKey":["expenses"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"redraft":{"type":"boolean","description":"Also return a `draft` cloned from the corrected row."}}}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"},"draft":{"$ref":"#/components/schemas/Expense"}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_draft`: Tried to modify or delete an issued (immutable) document. `conflict`: State conflict (e.g. numbering). `pdf_pending`: PDF not rendered yet. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/expenses/ocr":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Expenses"],"operationId":"ocrExpense","summary":"Open a draft from a receipt photo","description":"POST the raw image or PDF bytes with the matching `Content-Type`. A vision model reads the receipt and opens a draft expense from what it found; your user confirms and records.\n\nRequires the `ocr` scope, which is granted separately, because every scan runs a billed AI call. Bodies are capped at 5MB and there is a daily quota per key.","security":[{"ApiKey":["ocr"]}],"requestBody":{"required":true,"content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"expense":{"$ref":"#/components/schemas/Expense"},"extracted":{"$ref":"#/components/schemas/OcrExtraction"},"fileId":{"type":"string","description":"The stored receipt."}},"required":["ok","expense"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`too_large`: Request body over the size limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/exports/openfrmt":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Exports & Reports"],"operationId":"exportOpenfrmt","summary":"Generate a מבנה אחיד export","description":"The regulatory filing artifact (OPENFRMT v1.31): one zip holding INI.TXT and BKMVDATA.TXT under the exact directory tree the spec mandates. This is what an accountant or an auditor asks for. Download the zip through `GET /files/{id}`.","security":[{"ApiKey":["export"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","description":"","format":"date"},"to":{"type":"string","description":"","format":"date"}},"required":["from","to"]}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"exportRun":{"$ref":"#/components/schemas/ExportRun"},"file":{"$ref":"#/components/schemas/FileMeta"}},"required":["ok","exportRun"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/reports/continuity":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"get":{"tags":["Exports & Reports"],"operationId":"continuityReport","summary":"Numbering-continuity report","description":"Gap check per document type: the evidence that numbering is unbroken.","security":[{"ApiKey":["export"]}],"parameters":[{"name":"docType","in":"query","schema":{"type":"integer","enum":[305,320,330,400]},"description":"Check one type. Omit for all."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"report":{"type":"object","additionalProperties":true}},"required":["ok","report"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/reports/{kind}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["incomes","expenses","profit"]},"description":"הכנסות / הוצאות / רווח והפסד."}],"get":{"tags":["Exports & Reports"],"operationId":"managementReport","summary":"Management report","description":"Cash-basis, mirroring the OPENFRMT semantics exactly: income is payment-bearing documents, expenses count at record. Default is a rendered Hebrew PDF carrying the business branding; `?format=json` returns the aggregates for your own dashboard. The `profit` report includes a VAT block (עסקאות / תשומות / נטו) for VAT-registered dealers.\n\nThese are management reports; the regulatory filing artifact remains the OPENFRMT export.","security":[{"ApiKey":["export"]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}},{"name":"format","in":"query","schema":{"type":"string","enum":["pdf","json"],"default":"pdf"}}],"responses":{"200":{"description":"A rendered PDF, or the aggregates when `format=json`.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"report":{"type":"object","additionalProperties":true}},"required":["ok","report"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/backup":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Exports & Reports"],"operationId":"createBackup","summary":"Initiated backup","description":"The גיבוי יזום the regulations require: an archive of the ledger rows, with the full file index and each blob sha256, so the blob store can be audited against it.","security":[{"ApiKey":["export"]}],"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"file":{"$ref":"#/components/schemas/FileMeta"}},"required":["ok","file"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/files/thumbs":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."}],"post":{"tags":["Exports & Reports"],"operationId":"fileThumbnails","summary":"Batched receipt thumbnails","description":"Small data-URI JPEG previews for up to 60 stored image files in ONE call, built for list views, where a request per row would burn the rate limit. Non-image files (PDFs) are simply absent from the answer.","security":[{"ApiKey":["export"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","maxItems":60,"items":{"type":"string","description":""}}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"thumbs":{"type":"object","additionalProperties":{"type":"string","description":"data:image/jpeg;base64,…"},"description":"fileId → data URI. Missing key = no thumbnail for that file."}}}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/businesses/{bid}/files/{id}":{"parameters":[{"name":"bid","in":"path","required":true,"schema":{"type":"string"},"description":"Business id, from `POST /businesses`."},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"File id."}],"get":{"tags":["Exports & Reports"],"operationId":"getFile","summary":"Download a file","description":"Streams the stored bytes: export zips, backups, receipts. Issued document PDFs are served by `prints` instead, so the once-only origin rule is enforced.","security":[{"ApiKey":["export"]}],"responses":{"200":{"description":"The stored bytes.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/keys":{"get":{"tags":["Businesses"],"operationId":"listKeys","summary":"List your API keys","description":"Every key under your client: the one you are using and any others, live or revoked. Keys are minted and revoked by us (the Authentication guide explains rotation); this is how you see that a key you did not ask for exists.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["ok","keys"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"tags":["Businesses"],"operationId":"getUsage","summary":"Your API usage","description":"Your key's own request rollups per endpoint: requests and error counts over the window. Days are Asia/Jerusalem calendar days.","security":[{"ApiKey":["businesses"]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer"},"description":"Window in days (default 30, max 365)."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"days":{"type":"integer","description":""},"usage":{"type":"array","items":{"type":"object","properties":{"endpoint":{"type":"string","description":"`METHOD /route/pattern`."},"requests":{"type":"integer","description":""},"errors":{"type":"integer","description":"Responses with status >= 400."}}}}},"required":["ok","days","usage"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"post":{"tags":["Webhooks"],"operationId":"createWebhook","summary":"Create a webhook endpoint","description":"BillOS POSTs subscribed events to `url` as they happen: signed (HMAC-SHA256), retried with backoff, at-least-once. The full envelope, verification code and retry schedule are in the Webhooks guide.\n\nEndpoints belong to your KEY: one endpoint can cover every business under it, or be narrowed with `businessId`.","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"HTTPS only, publicly reachable (internal and private hosts are refused)."},"events":{"type":"array","items":{"type":"string","enum":["document.issued","document.pdf_ready","document.allocation_assigned","expense.recorded","export.completed","business.status_changed"]},"description":"Subset to receive. Omitted or empty = all events."},"businessId":{"type":"string","description":"Narrow to one business under your key."}},"required":["url"]}}}},"responses":{"201":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"webhook":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["ok","webhook"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Webhooks"],"operationId":"listWebhooks","summary":"List webhook endpoints","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["ok","webhooks"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook endpoint id."}],"patch":{"tags":["Webhooks"],"operationId":"updateWebhook","summary":"Update a webhook endpoint","description":"`{\"active\": true}` also re-arms an endpoint that was auto-disabled after sustained failure.","security":[{"ApiKey":["businesses"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":""},"events":{"type":"array","items":{"type":"string","enum":["document.issued","document.pdf_ready","document.allocation_assigned","expense.recorded","export.completed","business.status_changed"]}},"businessId":{"type":"string","description":"Set null to widen back to every business under the key."},"active":{"type":"boolean","description":"false pauses the endpoint: new events are not queued for it, pending ones stop delivering."}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"webhook":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["ok","webhook"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","summary":"Delete a webhook endpoint","description":"Removes the endpoint and its delivery history.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/deliveries":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook endpoint id."}],"get":{"tags":["Webhooks"],"operationId":"listWebhookDeliveries","summary":"List recent deliveries","description":"Newest first, the debugging view: what was sent, when, and what your endpoint answered.","security":[{"ApiKey":["businesses"]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max rows (default 50, cap 200)."}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}},"required":["ok","deliveries"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/test":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook endpoint id."}],"post":{"tags":["Webhooks"],"operationId":"testWebhook","summary":"Send a test event now","description":"Delivers one synthetic `webhook.test` event immediately, regardless of the endpoint's event filter: how you wire up a Make/Zapier trigger without issuing anything. `delivered` says whether your endpoint answered 2xx.","security":[{"ApiKey":["businesses"]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"delivered":{"type":"boolean","description":"Your endpoint answered 2xx."},"delivery":{"$ref":"#/components/schemas/WebhookDelivery"}},"required":["ok","delivered"]}}}},"400":{"description":"`validation`: Bad input. The message says what. `doc_type_not_allowed`: This dealer type may not issue this document type. `payments_mismatch`: Payments don't cover the document total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden`: Key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`: No such resource under your key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limited`: Slow down; honor `Retry-After`. `quota_exceeded`: Daily OCR quota exhausted. Resets at midnight Asia/Jerusalem.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}