Overview
The vendors module is your supplier CRM: it tracks the labs, synthesizers, and wholesalers you buy from. A vendor record has contact details, payment terms, contract documents, an order-routing rule (which SKUs you source from them), purchase orders, and a payout history.
It is a paid add-on under the Wholesalers billing package. Workspaces without the add-on see the vendors nav item as an upsell card; with it, the module enables across all stores in the workspace.
Suppliers vs marketplace vendors — not the same thing
The word “vendor” means two completely different things in {{COMPANY_SHORT_NAME}}. They live in different schemas, surface in different parts of the app, and have different docs.
- Vendor (this module) — a supplier that you buy from. Per-workspace, paid add-on. The page you’re reading now.
- Marketplace vendor — a seller that buyers buy from on the public {{COMPANY_SHORT_NAME}} marketplace. Platform-scoped, public profile, payouts via Stripe Connect. See Vendor storefront.
You may well be both: you sell on the marketplace and you buy from upstream labs whose payment terms you track here. The two systems do not share rows.
What working correctly looks like
If everything is wired up, you should see these things. If any one of them is missing, jump to Troubleshooting.
- Vendors appears in the sidebar with a numeric count of active vendors.
- Workspaces without the wholesalers add-on see an upsell card instead of the list page (and deep links redirect to the upsell).
- Creating a vendor with a duplicate name in the same workspace is rejected with a useful message, not a stack trace.
- The list page renders smoothly at 500+ vendors through a virtualized list.
- Every PO state transition (draft → submitted → received → closed) writes a row to
core.audit_log. - Cross-workspace data is invisible: org B cannot see org A’s vendors, payouts, or POs.
Enable the module
- Go to Settings → Billing → Modules.
- Find Vendors (Wholesalers add-on) and click Enable. The add-on bills monthly; the exact price is shown in the modal.
- The module enables across the workspace within a second. Vendors appears in the sidebar; deep links unlock.
Disabling the add-on hides the nav item and redirects deep links to the upsell page. Existing vendor data is preserved; re-enabling restores access without re-entering anything.
Create a vendor
- Go to Vendors, click New vendor.
- Enter a name (must be unique within the workspace), a primary contact (name, email, phone), and the vendor’s address.
- (Optional) Add a website, a tax id / EIN, and a short note (e.g. “Cold-chain only; lead time 10 business days”).
- Save. The vendor appears at the top of the list. You can immediately start attaching POs and uploading documents.
Profile fields
The detail page is organized into sections:
- Identity — name, legal name, tax id, website, primary contact, secondary contacts.
- Address — shipping origin (used as the from-address when buying labels from goods this vendor fulfills), billing address.
- Catalog — the list of SKUs you source from this vendor, with per-SKU lead times and last cost. Drives the order routing picker.
- Terms — payment terms and preferred methods. See below.
- Documents — signed contracts, COAs, MSAs, NDAs, insurance certificates.
- Activity — timeline of every PO, every payout, every document update.
Payment terms & preferred methods
Two structured fields drive how invoices from this vendor settle into your books:
- Payment terms — Prepaid, Net 15, Net 30, Net 45, Net 60. The PO due date is computed from the receipt date + the term.
- Preferred method — Wire, ACH, Check, Card, Other. This is informational on the vendor row, and it pre-fills the method on each new payout.
If a specific PO needs different terms (e.g. a one-off prepay on an otherwise Net-30 vendor), override on the PO itself. The vendor-level terms are the default, not a hard requirement.
Order routing — which vendor fulfills which products
The vendors module gives you a per-SKU routing map: “BPC-157 5mg comes from Acme Labs, BPC-157 10mg comes from Sigma Labs, TB-500 comes from either depending on lead time.”
- On a vendor’s detail page, open the Catalog tab and click + Add SKU.
- Pick the SKU from your product catalog. Enter the vendor’s cost, the lead time in business days, and (optionally) a minimum order quantity.
- Mark one vendor as the primary source for the SKU. Others become fallbacks — visible in the picker but not selected by default.
When you draft a PO from a low-stock alert (Inventory → Reorder), the routing rule pre-selects the primary vendor and pre-fills the unit cost. You can switch to a fallback at any time before submitting.
Purchase orders
POs are the document side of supplier orders. A PO walks through these states:
draft --submit--> submitted --receive--> received --close--> closed
| |
+--cancel--> cancelled +-- partial receipt --> partially_received --> received
- From the vendor detail page or from Inventory → Reorder, click New PO.
- Add line items: SKU, quantity, unit cost (pre-filled from the catalog), expected delivery date.
- (Optional) Attach a contract version, a quote PDF, or shipping instructions.
- Click Submit. The PO is locked from edits and a copy is emailed to the vendor’s primary contact (if you toggle “Notify vendor”).
- When goods arrive, open the PO, click Receive, and enter received quantities per line. Inventory updates atomically — one row in
inventory.stock_movementsper received SKU, all in one transaction. - Partial receipts are first-class. The PO stays in
partially_receiveduntil everything is in or you close it short.
Neither the PO form nor the underlying RPC accepts a negative quantity on a line. If you need to record a vendor return, use Create RMA from the receipt, not a negative-quantity PO.
Payout history
The Payouts tab is the running ledger of every payment you’ve sent to a vendor. Unlike a PO (which tracks goods received), a payout tracks money sent.
- Click Record payout to log a wire, ACH, check, or card payment. Enter amount, date, method, reference number (e.g. wire confirmation), and optionally attach a PO id so the PO’s outstanding balance updates.
- Multiple payouts can settle one PO (a 50% deposit + a 50% on-delivery is two rows).
- One payout can settle multiple POs — pick the PO ids in the form; the amount is allocated in the order you list them.
- The vendor’s Outstanding total at the top of the detail page is the sum of received-not-paid PO totals minus unallocated payout credits.
Payouts are operator-recorded today; there is no Stripe Connect-style push of money to suppliers (that’s a marketplace-vendor feature). Use the “reference number” field to tie each row back to your bank’s confirmation.
Vendor-side documents
The Documents tab on each vendor is a versioned store for:
- MSAs / master supply agreements — the umbrella contract.
- NDAs — mutual non-disclosure, often required for vendor onboarding.
- COAs (certificates of analysis) — per-lot, often per-PO. Drag the PDF onto the PO; we link it to both the PO and the vendor.
- Insurance certificates — with an expiry date that surfaces as a yellow chip on the vendor row when within 30 days of expiring.
For documents on the marketplace side (your storefront, terms, product COAs you publish to buyers), see Vendor storefront — that’s a separate documents store on the seller profile.
Settings & permissions
Where settings live:
- Settings → Billing → Modules — enable / disable the Wholesalers add-on.
- Settings → Modules — org-level module flag (separate from the billing add-on; both must be on).
- Vendors → vendor → Settings — per-vendor defaults: term, preferred method, default contract version.
Roles & permissions:
vendors:read— see the list and detail pages.vendors:write— create and edit vendors, draft POs, upload documents.vendors:submit_po— move a PO fromdrafttosubmitted(usually Manager+).vendors:record_payout— log a payout (usually finance / Owner).
API + automation
In v1, vendor data is exposed only through the read-only Public API:
GET /v1/vendors— list vendors. Keyset-paginated; supports filters by tag, term, primary contact.GET /v1/vendors/{id}— vendor detail including catalog, terms, and outstanding total.GET /v1/vendors/{id}/purchase_orders— PO history (status, totals, receipt dates).GET /v1/vendors/{id}/payouts— payout history.
Inbound writes (creating vendors, POs, payouts) via the Integration API are not in v1. Vendor records are operator-managed; if you need to bulk-import a vendor list, use the CSV import on the list page rather than the API.
Troubleshooting
The full symptom-to-fix table lives at Troubleshooting. Common vendors-specific issues:
- “Vendors” not in the sidebar — the Wholesalers add-on isn’t enabled. Go to Settings → Billing → Modules.
- “Duplicate vendor name” — vendor names are unique per workspace. Append a qualifier (city, division) or archive the old row.
- Receipt didn’t update inventory — the PO line’s SKU must match an active row in your product catalog. If you’ve archived the SKU, the receipt rejects with “sku not found.”
- Marketplace vendor confusion — if you’re trying to onboard a seller on the public marketplace, that’s Vendor storefront, not this module.
Related
- Vendor storefront (marketplace seller) — the other meaning of “vendor.”
- Orders & invoicing — the customer-facing side of the same money flow.
- Shipping — buy labels from a vendor’s shipping origin once goods are received and re-routed.
- Public read API —
GET /v1/vendorsreference.