secured gets one commercial invoice, owned and issued by LMN. It is the amount the partner owes LMN for that order — the settlement document that was previously shared out-of-band as a payment-due report. Four read-only routes expose it; nothing about an invoice is mutable through the partner API.
Every order response also carries an
invoice summary (null when none), and issuing fires the invoice.issued webhook.
Lifecycle
draft— created automatically the moment the order transitions tosecured. Drafts are visible on every route above (and asOrder.invoicewithstatus: draft), withnumber: nullanddocument_url: null. Draft amounts track the order and may change between reads — treat them as indicative until issued.issued— LMN ops reviewed the draft, entered the consignee and shipment month, and published it: the number is assigned,versionbecomes1, the PDF is available, andinvoice.issuedfires. Amounts are frozen.- Re-issue — LMN may correct an issued (or paid) invoice, e.g. to complete the packing list once the container is loaded. The number never changes;
versionincrements, a new PDF is published, andinvoice.issuedfires again withdata.previous_version. Earlier versions’ PDFs remain downloadable. paid— LMN ops recorded the payment (paid_at). No webhook — read it fromOrder.invoiceor these routes.void— terminal. The record stays readable withvoid_reason; a new draft may then be created for the same order and receives the next number on issue. No webhook.
One live invoice per order.
GET /v1/orders/{id}/invoice and Order.invoice always return the order’s newest invoice, so after a void you see the voided record until LMN creates a fresh draft.Invoice numbers
{prefix}_{YYYY}_{MM}_{seq} — a per-partner prefix, the four-digit year and two-digit month of shipment_month, and a sequence per (partner, environment, shipment month) starting at 001: SKL_2026_09_001, SKL_2026_09_002, … The sequence may exceed three digits (_1000) and is never zero-padded beyond three. Sandbox and production sequences are independent, so the same number can exist in both environments. Gaps are possible (a numbered draft that was voided) and carry no meaning.
Pricing is bundled
amounts.price is one figure. LMN’s commission and the partner discount from pricing.discount_config are realised inside it — against the actual hammer price, which may be lower than max_bid_amount_usd — but are not itemised on the API or the PDF, exactly as on the paper invoice. ocean_freight appears as its own line only when LMN lists it separately (otherwise it is inside price); insurance is an optional additional line. total = price + ocean_freight + insurance.
Amounts are numbers in major units with at most 2 decimals, unlike the whole-USD integers on Order.amounts. Partners recomputing from Order.amounts may see a ≤$1 difference from FX rounding — the invoice is authoritative.
Document URLs are pinned
Everydocument_url — on the invoice, on Order.invoice, and inside the webhook — ends in ?version=N for the version that payload describes. A URL you stored from version 1 keeps returning the version-1 PDF after a re-issue. Call the route without version for the current PDF.
GET /v1/invoices — List
created_at first. Same envelope and cursor rules as GET /v1/orders. Drafts are included unless you exclude them with status. Filters combine with AND semantics.
Response — 200 OK
Errors
GET /v1/invoices/{invoice_id} — Detail
Response — 200 OK
status: "draft", number: null, version: 0, document_url: null, issued_at: null, and possibly consignee: null, shipment_month: null, or amounts.price: null while LMN ops are still completing it.
Errors
GET /v1/invoices/{invoice_id}/document — PDF
Content-Type: application/pdf, Content-Disposition: inline; filename="{number}_v{N}.pdf".
This is the only way to obtain the PDF: there are no signed or public URLs, and the route requires your API key like every other. Every published version keeps its own immutable PDF. Sandbox PDFs carry a diagonal
SANDBOX — NOT A TAX DOCUMENT watermark. The route counts against the shared /v1 per-key quota like every other call — store the bytes rather than re-downloading per page view.
Errors
GET /v1/orders/{id}/invoice — Invoice for an order
secured), same shape as GET /v1/invoices/{invoice_id}. For a quick existence/status check you don’t need this call — read invoice on the order itself.
Errors
Sandbox
Drive a sandbox order tosecured with POST /v1/orders/{id}/sandbox-status — LMN drafts the sandbox invoice the same way it does in production, and it shows up on the order and on these routes. Issuing is an LMN-side action in both environments; contact LMN to have a sandbox invoice issued so you can exercise the PDF route and the invoice.issued webhook end-to-end. Sandbox and production invoices are fully separate (numbers, PDFs, webhooks).