{"openapi":"3.1.0","info":{"title":"POST /api/v1/bills/{bill_id}/revert-to-draft","version":"1.0.0","description":"Revert bill to draft"},"servers":[{"url":"https://api.ondayzero.com","description":"Production"}],"paths":{"/api/v1/bills/{bill_id}/revert-to-draft":{"post":{"tags":["bills"],"summary":"Revert bill to draft","description":"Move a 'forecasted', 'pending_approval' or 'received' bill back to 'draft' so it can be edited. A received bill's journal entry is reversed on its original date (refused if that period is closed or any payment/credit is applied); a multi-account split is kept on the draft. Any in-flight approval run is cancelled. Bills raised by a purchase order or inventory transfer cannot be reverted.","operationId":"revert_bill_to_draft","parameters":[{"name":"bill_id","in":"path","required":true,"schema":{"type":"string","title":"Bill Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-business-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Business-Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope_BillResponse_"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"example":{"error":"validation_error","message":"Validation failed: due_date: Input should be a valid date","errors":{"due_date":"Input should be a valid date"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business","content":{"application/json":{"example":{"error":"unauthorized","message":"Authentication required","code":"AUTH_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"example":{"error":"forbidden","message":"You don't have permission to access this resource","code":"AUTH_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource does not exist","content":{"application/json":{"example":{"error":"not_found","message":"Resource not found","code":"NOT_FOUND_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or is in an incompatible state","content":{"application/json":{"example":{"error":"conflict","message":"Resource already exists","code":"CONFLICT_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"validation_error","message":"Validation failed: amount: Input should be a valid integer","errors":{"amount":"Input should be a valid integer"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"}}}}},"x-fastapi-operation-id":"revert_bill_to_draft_api_v1_bills__bill_id__revert_to_draft_post"}}},"components":{"schemas":{"BillPaymentHold":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why the bill is held."},"held_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Held At","description":"When the hold was placed."},"held_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Held By","description":"User id that placed the hold."},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At","description":"When the hold was released; null while active."},"released_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Released By","description":"User id that released the hold."}},"type":"object","title":"BillPaymentHold","description":"A payment hold (\"do not pay\") recorded on a bill."},"BillResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Bill UUID."},"business_id":{"type":"string","title":"Business Id","description":"Business UUID."},"currency":{"type":"string","title":"Currency","description":"Currency for the bill (USD, CAD, AUD, EUR, or GBP).","default":"USD"},"status":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Status","description":"Bill status (see schema description)."},"on_hold":{"type":"boolean","title":"On Hold","description":"True while a payment hold is active. Payments are refused (BUSINESS_157) unless override_hold is passed.","default":false},"payment_hold":{"anyOf":[{"$ref":"#/components/schemas/BillPaymentHold"},{"type":"null"}],"description":"The current or most recent payment hold; null if never held."},"payment_initiated_on":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Payment Initiated On","description":"When set, payment was initiated outside DayZero (e.g. a bank with no API) but no bank transaction has been linked yet. Cleared automatically when a payment is linked."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Bill description."},"bill_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bill Number","description":"Bill/invoice number from vendor."},"vendor_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Id","description":"Vendor UUID."},"vendor_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Name","description":"Vendor name (resolved)."},"vendor_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Email","description":"Vendor email (resolved)."},"payment_term_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Term Id","description":"Payment term the bill was entered under, if any."},"type":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Type","description":"Type: 'recurring' or 'one_time'."},"expected_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Amount","description":"Expected amount in cents."},"expected_paid_on_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expected Paid On Date","description":"Expected payment date."},"total_paid":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Paid","description":"Total amount paid so far in cents."},"amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount","description":"Actual bill amount in cents."},"s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"S3 Key","description":"S3 key of attached document."},"received_on":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Received On","description":"Date bill/goods received."},"due_on":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Due On","description":"Payment due date."},"paid_on":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paid On","description":"Date fully paid."},"payment_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Method","description":"Payment method (Wire Transfer, ACH, Check, Credit Card). Prefers the user-set override; otherwise inferred from a linked payment."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Creation timestamp."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"Last update timestamp."},"signed_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed Url","description":"Signed URL to download the attached document (Content-Disposition: attachment)."},"attachment_unavailable_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attachment Unavailable Reason","description":"Why `signed_url` is null despite the bill having an attachment (e.g. the malware scan is pending, or the file predates scanning and must be re-uploaded). Lets the UI say whether retrying will ever help. Populated on the bill-detail response only."},"view_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"View Url","description":"Signed URL to preview the attached document inline (Content-Disposition: inline). Populated on the bill-detail response; falls back to null elsewhere."},"payments":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Payments","description":"List of payments made.","default":[]},"vendor_credit_applications":{"items":{"$ref":"#/components/schemas/BillVendorCreditApplicationResponse"},"type":"array","title":"Vendor Credit Applications","description":"Vendor credits applied to this bill (reduces balance due)."},"total_credits_applied":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Credits Applied","description":"Sum of applied vendor credits in cents."},"balance_due":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Balance Due","description":"Remaining balance in cents (amount - total_paid - total_credits_applied). Zero for paid/canceled bills."},"journal_entries":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Journal Entries","description":"Associated accounting entries.","default":[]},"debit_line_items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Debit Line Items","description":"Multi-account split held on the bill (pending_debit_line_items): ledger_id, ledger_name, amount_cents, description per line. Empty when the bill has no split.","default":[]},"has_split":{"type":"boolean","title":"Has Split","description":"True when the bill carries a multi-account split.","default":false},"split_warnings":{"items":{"type":"string"},"type":"array","title":"Split Warnings","description":"Problems with the split, e.g. two lines on the same ledger, which blocks approval.","default":[]},"recurring_template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurring Template Id","description":"ID of recurring template if this bill was generated from one, or if one was created."},"source_inventory_order_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Inventory Order Id","description":"Source PO that produced this bill via the PO lifecycle. Non-null means this bill is visible on the Inventory -> Accounts Payable tab."},"match_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Match Status","description":"Three-way match outcome: matched, qty_variance, price_variance, qty_and_price_variance, unmatched, no_po. None until the matcher has run on the bill."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Origin channel for bills not created by a signed-in user, e.g. 'vendor_portal' for invoices submitted through a public bill request link. Null for in-app bills."},"submitter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Name","description":"Name typed by the anonymous submitter (vendor portal)."},"submitter_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Email","description":"Email typed by the anonymous submitter (vendor portal)."},"match_variance_qty":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Match Variance Qty","description":"Signed unit variance across all lines (received - ordered). Positive = over-received; negative = short."},"match_variance_amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Match Variance Amount Cents","description":"Signed amount variance in cents (bill amount - PO total). Positive = vendor billed more than ordered; negative = less."},"contract_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contract Match","description":"Vendor contract comparison: matched, over_contract, needs_review, no_contract, or unknown."},"vendor_contract_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Contract Id","description":"Vendor contract UUID used for the last contract comparison."},"thread":{"anyOf":[{"$ref":"#/components/schemas/BillThreadResponse"},{"type":"null"}],"description":"Discussion thread and comment summary for this bill"}},"type":"object","required":["id","business_id","status","type","created_at","updated_at"],"title":"BillResponse","description":"Response schema for a bill.\n\nContains all bill details including vendor info, payment status,\nand associated journal entries for accounting.\n\n**Status values:**\n- `draft`: Bill created but not yet approved\n- `forecasted`: Approved, expected to be paid\n- `received`: Bill/goods received, liability recorded\n- `partially_paid`: Some payments and/or vendor credits applied\n- `paid`: Fully paid (cash and/or vendor credits)\n- `canceled`: Cancelled, will not be paid","example":{"amount":250000,"business_id":"019ab37c-b051-7000-8000-000000000001","created_at":"2024-01-10T10:30:00Z","description":"Monthly office rent - January 2024","due_on":"2024-01-31T00:00:00Z","expected_amount":250000,"id":"019ab37c-b111-7000-8000-000000000001","journal_entries":[],"payments":[],"received_on":"2024-01-15T00:00:00Z","status":"received","type":"recurring","updated_at":"2024-01-15T14:00:00Z","vendor_email":"billing@abcproperty.com","vendor_id":"019ab37c-ae0d-7000-8000-000000000001","vendor_name":"ABC Property Management"},"examples":[{"amount":250000,"business_id":"019ab37c-b051-7000-8000-000000000001","created_at":"2024-01-10T10:30:00Z","description":"Monthly office rent - January 2024","due_on":"2024-01-31T00:00:00Z","expected_amount":250000,"id":"019ab37c-b111-7000-8000-000000000001","journal_entries":[],"payments":[],"received_on":"2024-01-15T00:00:00Z","status":"received","type":"recurring","updated_at":"2024-01-15T14:00:00Z","vendor_email":"billing@abcproperty.com","vendor_id":"019ab37c-ae0d-7000-8000-000000000001","vendor_name":"ABC Property Management"}]},"BillThreadResponse":{"properties":{"thread_id":{"type":"string","title":"Thread Id","description":"Thread UUID"},"comment_count":{"type":"integer","title":"Comment Count","description":"Number of comments on the thread"},"comments":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Comments","description":"Thread comments (detail view)"}},"additionalProperties":true,"type":"object","required":["thread_id","comment_count"],"title":"BillThreadResponse","description":"Thread summary embedded on bill detail responses."},"BillVendorCreditApplicationResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Application record ID"},"vendor_credit_id":{"type":"string","title":"Vendor Credit Id","description":"Source vendor credit ID"},"bill_id":{"type":"string","title":"Bill Id","description":"Bill the credit was applied to"},"amount_applied":{"type":"integer","title":"Amount Applied","description":"Amount applied in cents"},"amount_applied_dollars":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount Applied Dollars","description":"Amount applied in dollars"},"applied_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Applied At","description":"When the credit was applied"},"applied_by_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Applied By User Id","description":"User who applied the credit"},"vendor_credit_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Credit Number","description":"Vendor credit number (e.g. VC-0001)"},"journal_entry_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal Entry Id","description":"Journal entry posted when the credit was applied to this bill"}},"type":"object","required":["id","vendor_credit_id","bill_id","amount_applied"],"title":"BillVendorCreditApplicationResponse","description":"Vendor credit applied against a bill (embedded on bill detail/list)."},"SuccessEnvelope_BillResponse_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"data":{"anyOf":[{"$ref":"#/components/schemas/BillResponse"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"SuccessEnvelope[BillResponse]"},"ErrorResponse":{"title":"ErrorResponse","type":"object","description":"Envelope returned by every non-2xx response. Branch on `code` (stable) rather than `message` (human-readable, may change).","required":["error","message","code"],"properties":{"error":{"type":"string","description":"Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`."},"message":{"type":"string","description":"Human-readable explanation, safe to show to end users."},"code":{"type":"string","description":"Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`)."},"request_id":{"type":"string","description":"Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied."},"errors":{"type":"object","additionalProperties":{"type":"string"},"description":"Field-level validation messages keyed by field name. Present on 400/422 validation failures only."}}}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Token","description":"API token authentication. Format: `Bearer dz_...`"}}},"security":[{"BearerAuth":[]}]}