Developer

Items and stock

Products, services, materials and expenses — the catalogue, its stock, its movement and its prices.

Everything sellable or buyable is an item with a type discriminator. One resource, one scope: ops_products.

MethodEndpointPurpose
GET/itemsList — filter by type and status
POST/itemsCreate — name required
GET/items/typesThe item types this business uses
GET/items/categoriesCategories (POST to create, PATCH /categories/{id} to rename)
GET/items/{id}Detail
PATCH/items/{id}Update
DELETE/items/{id}Delete

Creating one

bash
curl -X POST https://api.trabalance.com/api/v1/items \
-H "Authorization: Bearer tk_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5a1c9e77-…" \
-d '{ "name": "Widget, 40 mm", "sku": "WID-040", "type": "Product",
      "rate": 50.00, "cost": 32.00, "measurement": "Unit", "reorder_point": 25 }'
FieldRequiredNotes
nameYesUnique within the business
sku, barcodeNosku is unique within the business — and SKU or barcode, never the name, is the identity to match on from your side
typeNoProduct (default), Service, Material, Expense
sub_typeNobuy (default), sell, both
rate, costNoSelling price and purchase cost
measurementNoUnit of measure; defaults to "Unit"
reorder_pointNoDrives the low-stock signal in the app
category_id, income_account_id, expense_account_id, inventory_account_idNoLedger accounts fall back to the business defaults
valuation_methodNoDefaults to the business's method

Stock, movement and figures

MethodEndpointPurpose
GET/items/{id}/stockQuantity on hand, by location
GET/items/{id}/movementWhat moved, when, and the running balance
GET/items/{id}/statsInventory statistics for the item
GET/items/{id}/adjustmentsAdjustments (POST to record one)
⚠️Never recompute an inventory figure

Quantities, values and running balances come from the inventory producer and are rendered as they arrive. Re-deriving a running balance from movement rows on your side produces a second answer — and a second answer is a wrong answer, because a per-location view has gaps another location's activity left behind. Ask for the scope you want and read the figure it returns.

Pricing

MethodEndpointPurpose
GET/items/{id}/pricingPrices, per location
PATCH/items/{id}/pricingUpdate pricing
GET/items/{id}/price-historyWhat the price has been
GET/items/{id}/discountsDiscounts (POST to save, DELETE /discounts/{discountId} to remove)

Reads need ops_products:read; creates need :create, updates :update, deletes :delete.