NutraSoft food manufacturing ERP software
Esc
  • GuideGetting startedThree steps to your first call and your first order, then the two shapes every response takes.
  • GuideAuthentication and keysBearer keys, test and live environments, rotation without an outage, and what each scope grants.
  • GuideTest modeA second NutraSoft account of your own, seeded with realistic data, that you can safely break.
  • PageErrorsEvery error code the API returns, what it means, what to do about it and whether to retry.
  • PageConventionsThe rules every operation follows: money, time, paging, sorting, nulls, PATCH and identifiers.
Menu

Writing documents

Sales orders, purchase orders and bills: 1 to 200 lines, replace semantics, totals, idempotency and status changes.
Updated

In short

  • A document takes 1 to 200 lines. Bills count distinct products instead, with up to 1000 lines.
  • Sending lines in a PATCH replaces the set: a line with an id is updated, one without is added, one left out is removed.
  • Only POST /bills and POST /purchase-orders are idempotent, with an Idempotency-Key header.
  • subtotal is computed from the lines, before tax. Tax amounts, totals and price lists are not applied for you.

The API writes sales orders, purchase orders and bills through the same rules as NutraSoft's own forms. This page covers what those writes have in common.

Line limits

  • lines accepts 1 to 200 lines on sales orders and purchase orders. One more is refused with 400 INVALID_REQUEST, and details points at body.lines.
  • Bills count distinct products, since several lines of the same product, such as different lots, count once: a bill takes up to 1000 lines for at most 200 different products.
  • A purchase order needs at least one line when it is created, and sending lines as an empty list on an update is refused.

Replace semantics for lines

  • Omit lines in a PATCH to leave the lines as they are.
  • Send lines to replace the whole set: a line with an id updates that line in place, a line without one is added, and every existing line you leave out is removed.
  • Read the current lines from the detail GET first. Lines are returned by the detail and write operations, and are null on list operations.
  • An id that is not a line of this document is refused with 400.
  • Line round trips need cost:read. Without it price reads null, and a line sent back without its price loses it.

Totals, tax and prices

  • subtotal is computed from the lines and is not accepted in a request. It is before tax.
  • v1 does not calculate or publish tax amounts or document totals. Documents carry tax1 and tax2, whether each tax applies, with their rates tax1_rate and tax2_rate.
  • Prices are stored exactly as sent. The API does not apply the customer's price list.
  • Quantities follow Units and quantities: sales order lines are in their uom_type, purchase order and bill lines in purchase units.

Idempotency

POST /bills and POST /purchase-orders accept an Idempotency-Key header: your own unique string, up to 200 characters. Replaying a request with the same key and the same body returns the document the first request created, with 200, instead of creating a second one. Reusing a key with a different body is refused with 409 CONFLICT.

Every other write is not idempotent. Retrying a request whose response you never saw can create a duplicate, so check whether it landed before you retry.

Status changes

Sales orders

A sales order is created OPEN. The only status change the API makes is cancelling it; shipping and invoicing in NutraSoft move an order through its other statuses. An order that was paid through your NutraSoft online store cannot be cancelled over the API and returns 409: cancel it in NutraSoft, which refunds the payment.

Purchase orders

The status operation publishes the ordering path only: SENT, CONFIRMED, CANCELLED and CLOSED. RECEIVED and BACK_ORDER are written by receiving in NutraSoft.

If your account blocks unapproved suppliers, creating an order for a suspended or rejected supplier, or moving an order to one, is refused with 409. A supplier whose approval is pending or has expired is not blocked.

The two closed statuses are spelled differently: a sales order uses CLOSE, a purchase order uses CLOSED.

Production runs

The status operation can set PLANNED, ON_HOLD, QUARANTINE and CANCELLED. Starting a run (IN_PROGRESS, IN_PROGRESS_TRANSFORMATION) and completing it (COMPLETED) happen on the shop floor, where signatures, equipment calibration and pre-operational checks are enforced, so the API refuses them with 409.

Bills receive stock

  • Each bill line creates or tops up a lot for its product, lot number and location, so lot_number is required. A lot that already exists with a different expiration date is refused with 409.
  • quantity and cost are per purchase unit; the lot is recorded in base units.
  • Linking a bill to an order with purchase_order_id does not advance or close the order. Use the purchase order status operation for that.
  • Bills created through the API are not sent to QuickBooks in v1. If you use the QuickBooks integration, link them from NutraSoft afterwards.

What every write checks

  • Unknown fields in a request body, including inside lines and addresses, are refused with 400.
  • Every id in a body must belong to your account, or be shared reference data your account can use. Anything else is 400 INVALID_REQUEST. An id in the path that is not in your account is 404 NOT_FOUND.
  • Shared reference rows, marked is_global, are read-only: changing one is 403 READ_ONLY.
  • Sending null for a field that cannot be null is refused with 400. See Conventions.
  • Each request is one transaction: it applies completely or not at all.