API reference

Read one factory's production, stock and costs from another program. Every endpoint reads. None writes.

Tokens

The factory owner creates a token in the app under More, Connections. Kamna shows it once. It starts with kmn_ and reads only that factory.

Send it on every request:

Authorization: Bearer kmn_your_token

A missing, wrong or revoked token answers 401. A revoked token stops working within about a minute. The owner can hold up to 10 tokens and sees when each was last used.

Base address

https://api.kamna.app

Responses are JSON. The version is in the path; /v1 does not change shape underneath you.

Endpoints

RequestReturns
GET /v1/lotsLots, in the order they were created. Filter ?status=open or closed.
GET /v1/lots/{id}One lot with its sizes, colours, cutting and stages.
GET /v1/stagesMaking stages. Filter ?lot=, ?status=, ?from=YYYY-MM-DD, ?to=YYYY-MM-DD.
GET /v1/closed-outputClosed lots: first-quality pieces per size and colour, and the cost per piece frozen at close.
GET /v1/fabric-runsFabric production runs.
GET /v1/fabric-runs/{id}One run with its stages; each stage names the unit it was sent and received in.
GET /v1/stock/yarnYarn stock with its lines.
GET /v1/stock/fabricFabric stock with its lines. Filter ?status=active or exhausted.
GET /v1/stock/trimsTrims stock with its lines. Filter ?status=.
GET /v1/vendorsVendors and the jobs they do.
GET /v1/stylesStyles and their per-piece requirement.

Any method other than GET answers 405.

Pages

A list answers { "data": [...], "next": 123 }. Pass next back as ?after=123 for the following page. next is null on the last page. ?limit= takes 1 to 500 and defaults to 100.

Units and money

Every fabric quantity carries unit: kg for knit, m for woven. A fabric run stage names sent_unit and received_unit, because a woven run goes into the loom as yarn by weight and comes out as fabric by length.

Every stage carries bill_basis: sent when the job was billed on the quantity sent, received when billed on the quantity received. A fabric run stage gives its rate as rate_per_sent_unit or rate_per_received_unit, whichever the basis names; the other is null.

Costs are included. Money figures are plain numbers in the factory's currency. An empty field is null, never an empty string.

Rate limit

120 requests per minute per token. Past it, the answer is 429 with Retry-After: 60.

Example

curl -H "Authorization: Bearer kmn_your_token" \
  "https://api.kamna.app/v1/lots?status=closed&limit=2"
{
  "data": [
    { "id": 41, "lot_number": "1041", "style_name": "Romper A",
      "status": "closed", "first_quality_pieces": 480,
      "raw_cost_per_pc": 62.4, "closed_at": "2026-09-12" },
    { "id": 44, "lot_number": "1044", "style_name": "Vest B",
      "status": "closed", "first_quality_pieces": 950,
      "raw_cost_per_pc": 38.1, "closed_at": "2026-09-18" }
  ],
  "next": 44
}