Price matrices
One matrix is one price grid — what your offer rules resolve against, which makes these the numbers your quotes are actually built from.
The list gives you axes and dimensions; ask for one matrix to get its prices. The flat per-unit add-ons a quote can also carry live separately under materials, because their price is a number rather than a function of width and depth.
GET/price-matrices
scopeprices:readYour grids, without their prices — axes, dimensions and dates.
?code=zv_ovk_poly is how you fetch one grid without knowing our id.meta.next_cursor.curl "https://api.zinevu.com/api/public/v1/price-matrices?code=zv_ovk_poly" \ -H "Authorization: Bearer $ZINEVU_API_KEY"GET/price-matrices/{id}
scopeprices:readOne grid, as a table and as a flat list of cells.
{ "data": { "id": 842, "code": "zv_ovk_poly", "name": "Overkapping — polycarbonaat dak", "matrix_type": "grid_2d", // or "list_1d", or "fixed" "is_active": true, "row_axis": "diepte_cm", "col_axis": "breedte_cm", "row_values": [250, 300], "col_values": [300, 400], "grid": [[1176, 1344], [1334, 1596]], "cells": [ { "row": 250, "col": 300, "price": 1176 }, { "row": 250, "col": 400, "price": 1344 }, { "row": 300, "col": 300, "price": 1334 }, { "row": 300, "col": 400, "price": 1596 } ], "fixed_price": null, "updated_at": "2026-09-05T13:22:41+00:00" }}// list_1d -> one cell per row, "col" is null// fixed -> exactly one cell, both "row" and "col" null, price in fixed_priceThree shapes, one field to read#
| matrix_type | Means |
|---|---|
grid_2d | Two axes — typically width against depth. |
list_1d | One axis. col is null on every cell. |
fixed | One price, whatever the size. Both axes null; the number is also in fixed_price. |
You do not have to branch on the type to read prices: cells is the same flat list in all three cases, and a missing axis is null rather than absent. Prices are plain numbers, never strings, and a cell with no price is null rather than zero — a gap in a grid is not a free product.
POST/price-matrices
scopeprices:writeCreate or replace whole grids, addressed by code. Takes ?dry_run=1.
POST /price-matrices?dry_run=1Idempotency-Key: 8f14e45f-ea8d-4b1f-9c2a-77bb0f2e6d31{ "matrices": [ { "code": "example_roof", "name": "Example — polycarbonate roof", "matrix_type": "grid_2d", "row_axis": "diepte_cm", "col_axis": "breedte_cm", "row_values": [250, 300], "col_values": [300, 400], "prices": [[1176, 1344], [1334, 1596]] } ]}{ "data": { "dry_run": true, "created": 0, "updated": 1, "prices": 4, "matrices": [ { "code": "example_roof", "action": "update", "prices": 4 } ] }}It does not merge into it. Read importing prices before the first write — in particular, use an example_ code for the first experiment rather than one your catalogue already quotes from.
PATCH/price-matrices/cells
scopeprices:writeChange individual prices without resending a grid. Takes ?dry_run=1.
PATCH /price-matrices/cells{ "updates": [ { "code": "example_roof", "cells": [ { "row": 300, "col": 400, "price": 1650 } ] } ]}