Skip to content
Knowledge ERP Docs

API Reference ↗
Purchasing

Vendor Returns

Track goods sent back to a supplier — from the initial RMA draft through submission, shipment, and completion — with a full line-item breakdown, and each unit you name taken out of stock when the return ships.

A vendor return (also called an RMA — Return Merchandise Authorization) is the formal record of goods you are sending back to a supplier. Whether the items arrived defective, were the wrong product, exceeded what you ordered, or were damaged in transit, a vendor return captures which items are going back, what they cost, and where the process stands — all the way from drafting the return through shipping it out and receiving credit.

Vendor returns complement vendor invoices: where an invoice records what you owe the supplier, a return records what the supplier owes back to you.

Creating a vendor return #

New returns are created from Purchasing → Vendor Returns → New Vendor Return. The header form is brief — the detail lives in the line items you add next.

  • Vendor — the supplier you are returning to. Required. Selecting a vendor links the return to that vendor's record in your vendor directory.
  • RMA Number — auto-generated in the format RMA-0001 if you leave it blank, or type your own if the vendor has assigned one. You can always update it later once the supplier responds.
  • Reason — the primary reason for the return: Defective, Wrong Item, Excess Inventory, Damaged in Transit, or Other. Optional but useful for reporting.
  • Notes — free-text field for any instructions, vendor contact details, or special handling requirements.
  • Status — set to Draft when the return is created, and shown on the edit form without being editable there. Buttons on the return's page move it; see Lifecycle below. The status is not shown on the creation form at all.
  • Total Amount — calculated automatically from the line items; displayed as a read-only field in the return's currency on the detail page.

Line items (items to return) #

Once the header is saved, use the Items to Return tab to add the individual Products going back. Each line captures:

  • Unit — the specific tracked unit being returned, looked up by name or barcode (I-xxxxxxxx). Selecting a unit fills in the Product and, on a return in your home currency, the Unit Cost: the unit's own cost, or its product's when the unit has none (left blank if neither has one). You can change the cost. A unit goes back whole when the return ships, so it can be on only one line of a return; the line form will not save the same unit twice.
  • Product — the Product for this line; auto-populated when you choose a unit, or set independently for returns not tied to a specific tracked unit.
  • Original PO Line — optionally link the line back to the purchase order line it was received on, for traceability.
  • Quantity — how many units (or what amount) are being returned. A line that names a unit must have a quantity of 1, because that unit goes back whole; neither the line form nor the API will save a line with any other quantity. A line with no unit can carry any quantity, including decimals for measured goods.
  • Unit Cost — the per-unit cost for this return line, in the return's currency. Over the API, unit_cost is sent and returned in the currency's smallest unit, such as cents (e.g. 2500 = $25.00). Adding or editing a line immediately recalculates the header Total Amount.
  • Notes — per-line remarks.

The table shows each line's Product name, the From Bin where the unit currently lives, quantity, unit cost, and notes. Lines can be edited or deleted at any time before the return is shipped; each change recalculates the running total.

Lifecycle: Draft to Completed #

Every vendor return moves through a predictable sequence of statuses shown as a color-coded badge:

  • Draft (gray) — the return is being assembled; no inventory movements have been recorded yet. You can add, edit, or remove lines freely.
  • Submitted (blue) — the return has been communicated to the vendor and is awaiting their approval or shipping instructions. The Mark as Shipped action becomes available.
  • Shipped (amber) — the return has left your warehouse. Triggering Mark as Shipped records a Return Out inventory movement for each line item that has a linked unit, and takes that unit out of stock.
  • Completed (green) — the supplier has acknowledged receipt and any credit or refund has been arranged.
  • Cancelled (red) — the return was closed without being completed.

Four buttons on the return's page move it, for anyone who can edit vendor returns:

  • Submit — moves a Draft return to Submitted.
  • Mark as Shipped — moves a Submitted return to Shipped, and is the only one that writes inventory movements or changes a unit's stock.
  • Mark as Completed — moves a Shipped return to Completed.
  • Cancel Return — closes a Draft, Submitted or Shipped return. The movements recorded by shipping stay, and so do the units they took out of stock.

Undo can reverse a Submit, a Cancel Return or a Mark as Completed, none of which touch stock.

Mark as Shipped is the only status transition that writes inventory movements or takes units out of stock. It is only available when the return is in Submitted status. Confirm the action in the modal. Undo does not reverse it: trying to undo a shipment from its change history is refused with "Unable to Undo", and nothing changes. If a return was shipped by mistake, put the unit back by hand — see below.

Inventory impact #

When a return is marked as shipped, Knowledge ERP records a Return Out movement against every line item that points to a specific unit. The movement captures the Product, quantity, source location, and source bin, with the RMA number noted in the movement notes. You can review these in the unit's movement history on Inventory → Units.

Each of those units also leaves stock, whole: it is left Out of Stock with nothing on it and out of its bin, and the movement records how much of it was there. That is the same thing a sale, a discard or a donation does to a unit. So the goods stop counting as on hand and towards the product's reorder point, and the unit is no longer offered for sale or check-out.

A unit goes back whole, so before anything is written Mark as Shipped checks every line, and refuses the whole return — changing nothing — if any of these is true:

  • a line that names a unit has a quantity other than 1;
  • the same unit is named on more than one line;
  • a named unit is not In Stock (it is on hold, checked out, in transit, missing, already out of stock or sold), or has since been deleted.

A message names each line and unit that needs fixing. Fix them and mark the return as shipped again.

A line that names only a Product, without a specific unit, still records no movement and changes no unit's stock, so the product's on-hand count does not drop for that line. Name the unit on the line if the stock should come off.

Returns shipped before this change are not touched: their units keep the quantity and status they had.

If a return was shipped by mistake, Undo will not help, and cancelling the return does not put stock back. Put each unit back by hand: set its Status back to In Stock on its own page and choose a Bin for it (an In Stock unit has to be in one), then post a stock adjustment giving it its quantity back — setting the status alone leaves it In Stock with nothing on it.

The return list and filters #

The return list (Purchasing → Vendor Returns) shows each return's RMA number, vendor, status, reason, total, and creation date, sorted newest first. Filter by Status to focus on returns that need action — for example, all Submitted returns awaiting shipment. Soft-deleted returns are hidden by default; use the Trashed filter to include them.

What lives on the return page #

Open a return to find its header details plus tabs for everything attached:

  • Items to Return — the line items, editable until the return ships.
  • Attachments — packing slips, vendor correspondence, photos of damage.
  • Change History — a full audit trail of every edit, showing who changed what and when.

Printing #

The view page includes a Print action that opens a formatted PDF of the return in a new tab with your browser's print dialogue over it — useful for including in the physical shipment. If the dialogue does not appear, the Print button on that tab opens it. Download PDF on the same tab saves the file, for emailing to the vendor.

How vendor returns relate to other modules #

  • Vendors — the parent vendor record stores contact details and purchase history. See Vendors & Contacts.
  • Purchase Orders — each return line can reference the original PO line it was received on, keeping the inbound and outbound paper trail linked. See Purchase Orders.
  • Vendor Invoices — once a return is completed, any vendor credit should be reconciled against open vendor invoices. See Vendor Invoices & Payments.
  • Units — shipment creates Return Out movements on the specific units sent back and takes them out of stock. See Units.

Doing it from the API #

# List returns, filtered by vendor and status
curl "https://your-domain.com/api/v1/vendor-returns?vendor_id=<id>&status=submitted" \
  -H "Authorization: Bearer $TOKEN"

# Create a new vendor return
curl -X POST "https://your-domain.com/api/v1/vendor-returns" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_id": "<vendor-id>",
    "reason": "defective",
    "notes": "Batch arrived with cracked housings — RMA requested per email 2026-06-01"
  }'

# Add a line item (unit_cost in the return currency's minor unit: 4500 = $45.00 in USD)
curl -X POST "https://your-domain.com/api/v1/vendor-return-items" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_return_id": "<return-id>",
    "product_id": "<product-id>",
    "quantity": 3,
    "unit_cost": 4500
  }'

# Submit it (Draft to Submitted); /cancel and /complete move it on
curl -X POST "https://your-domain.com/api/v1/vendor-returns/<return-id>/submit" \
  -H "Authorization: Bearer $TOKEN"

Status is read-only on create and update. A request that includes status is refused with 422. Use POST /vendor-returns/{id}/submit, /cancel and /complete. Shipped is reached only by Mark as Shipped in the panel, which records the stock movements and takes the units the return names out of stock; there is no API endpoint for shipping a return, and the API cannot name a unit on a line, so a line created there moves no stock when the return ships.

Money fields (unit_cost, total_amount) are integers in the return's smallest unit over the API, such as cents (4500 = $45.00). A return is in its vendor's currency, and its currency can't be changed once it is made. On a return in another currency, a line's unit cost is not filled in from the product's cost, which is in US dollars: the cost is shown under the field as a guide. A vendor return also returns currency, exchange_rate, rate_date and rate_source over the API; in your home currency the rate is 1 and the source is identity. See Currency.