Zinevu
API reference

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

prices:read

Your grids, without their prices — axes, dimensions and dates.

Parameters
code
string
Exact match on your own identifier. ?code=zv_ovk_poly is how you fetch one grid without knowing our id.
updated_since
ISO 8601
Only grids changed at or after this instant.
limit
integer, 1–100
Defaults to 25.
cursor
string
From meta.next_cursor.
Request
curl "https://api.zinevu.com/api/public/v1/price-matrices?code=zv_ovk_poly" \  -H "Authorization: Bearer $ZINEVU_API_KEY"

GET/price-matrices/{id}

prices:read

One grid, as a table and as a flat list of cells.

Response
{  "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_price

Three shapes, one field to read#

matrix_typeMeans
grid_2dTwo axes — typically width against depth.
list_1dOne axis. col is null on every cell.
fixedOne 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

prices:write

Create or replace whole grids, addressed by code. Takes ?dry_run=1.

Parameters
matricesrequired
array
Up to 200 per request.
matrices[].coderequired
string
Letters, digits, underscore and hyphen. Your identifier, not ours.
matrices[].namerequired
string
What a person sees in the portal.
matrices[].matrix_typerequired
grid_2d | list_1d | fixed
Decides which of the fields below are required.
matrices[].row_axis
string
Required for grid_2d and list_1d.
matrices[].col_axis
string
Required for grid_2d.
matrices[].row_values
array
The axis values, in order.
matrices[].col_values
array
The axis values, in order.
matrices[].prices
array
A row per row_value, a number per col_value. null for a gap.
matrices[].fixed_price
number
For matrix_type fixed.
Request
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]]    }  ]}
Response
{  "data": {    "dry_run": true,    "created": 0,    "updated": 1,    "prices": 4,    "matrices": [ { "code": "example_roof", "action": "update", "prices": 4 } ]  }}
An upsert replaces the grid

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

prices:write

Change individual prices without resending a grid. Takes ?dry_run=1.

Parameters
updatesrequired
array
One entry per grid you are touching.
updates[].coderequired
string
The grid, by your own code.
updates[].cellsrequired
array
row, col and price. A value not already on the axis is an error, not an insertion.
Request
PATCH /price-matrices/cells{  "updates": [    { "code": "example_roof", "cells": [ { "row": 300, "col": 400, "price": 1650 } ] }  ]}