Purchase Requests
Purchase requests: creation from a quote or an invoice, line items, attachments, comments, approval requests, and the purchases list with its filter options.
List all purchase requests
Retrieves all purchase requests for the current tenant with filters, grouping, sorting, and pagination. Permissions: requires purchase-requests:read. Results are scoped server-side: callers without the ADMIN or ACCOUNTANT role only receive purchase requests they own or may view.
Create a new purchase request
Creates a new purchase request in draft status. All fields are optional in draft state. Returns the full newly created purchase request so the caller does not need a follow-up GET. Permissions: requires purchase-requests:write (granted by can_buy). Setting payment_method=INVOICE additionally requires can_pay_on_invoice; setting buyer_code to another user requires can_purchase_on_behalf. Both yield 403 otherwise.
Request procurement help for a blocked supplier
Sends the buyer's message to the configured procurement group through its shared email address or member inboxes.
Read a quote out of a document without creating anything
Extracts structured quote data from a document and returns it. The format is read from the bytes rather than declared: a PDF, one of the accepted image formats, or e-invoice XML. Nothing is persisted, which is what separates this from the from-quote endpoints: they create a draft and extract asynchronously, so neither can answer a caller that must show the buyer what was found before anything exists.
Create a purchase request from an invoice PDF
Accepts an invoice PDF file, validates it, and triggers a workflow to create a purchase request and purchase order.
Create a draft purchase request from an uploaded quote or shopping basket
Accepts a quote document and creates a draft purchase request. A PDF or an image (PNG, JPEG, TIFF, WebP) is read alike, so a screenshot of a webshop basket goes through this endpoint too, under a from_basket purchase flow. The LLM extraction runs asynchronously on a River worker; the response includes the PR code and an extraction_status of "extracting". The dashboard subscribes to purchase_request.updated WebSocket events to learn when extraction completes (or fails).
Create a draft purchase request from pasted quote text
Accepts raw quote text, extracts structured quote data via LLM, and creates a draft purchase request prefilled from it. The optional `kind` field overrides the LLM-inferred one_time/subscription classification.
Validate an existing draft purchase request by code
Validates an existing draft purchase request without persisting changes. Returns field-level validation errors. Excludes the given code from uniqueness checks.
Delete a purchase request
Soft deletes a purchase request (marks as deleted). Permissions: requires purchase-requests:delete (granted by can_buy). Object-level: non-viewers get 404, viewers that are neither owner nor admin get 403.
Get a purchase request by code
Retrieves a specific purchase request by its unique code with optional includes. Codes that do not match a purchase request resolve through an exact purchase ORDER code match to the owning purchase request, so detail routes can be entered with either code. Comments are not exposed via a dedicated endpoint: set with_activities=true to receive them alongside system events in the activities field. Permissions: requires purchase-requests:read plus object-level visibility; purchase requests the caller may not view return 404 to avoid an existence oracle.
Update a purchase request
Updates an existing purchase request (only allowed in DRAFT status). All fields are optional. Permissions: requires purchase-requests:write (granted by can_buy). payment_method=INVOICE additionally requires can_pay_on_invoice; a foreign buyer_code requires can_purchase_on_behalf. Object-level: non-viewers get 404, viewers that are neither owner nor admin get 403, non-DRAFT requests get 409.
Get all attachments for a purchase request
Retrieves all file attachments for a purchase request.
Upload an attachment to a purchase request
Uploads a file attachment for a purchase request. The file must be a PDF; its content is validated, not just its name. Attachments are append-only: once uploaded they cannot be edited or deleted. The file will be stored in object storage.
Download the purchase case audit trail as a PDF
Renders the whole case-wide audit trail (purchase request, orders, credit cards, invoices, approval tasks, activities and comments) as a formal audit record carrying a QR deep link and a SHA-256 content hash. Permissions: requires the ACCOUNTANT or ADMIN role, purchase-requests:read and object-level visibility. A caller without the role, or a case the caller may not view, returns 404 rather than 403, so the response cannot confirm that a case exists to someone with no right to know. IP addresses appear only when the tenant setting audit/pdf_include_ip_addresses is enabled; the printed content hash folds that setting in, so a document's hash always matches what it shows.
Cancel a purchase request
Cancels a purchase request, moving it to CANCELED status. Permissions: requires purchase-requests:write (granted by can_buy). Object-level: non-viewers get 404, viewers that are neither owner nor admin get 403.
Create a comment for a purchase request
Creates a new comment activity for the specified purchase request. Comments are append-only: once created they cannot be edited or deleted.
Request approval for a purchase request
Submits a purchase request for approval, triggering the approval workflow. Permissions: requires purchase-requests:write (granted by can_buy). Object-level: non-viewers get 404, viewers that are neither owner nor admin get 403.