Skip to content

Purchase line items

MendriX calculates, per ride, what that ride is expected to cost when an operator (a charter, a subcontractor) drives it. Those calculated costs are the ride’s purchase line items. This guide reads them out of the Purchase service, so the invoices you receive from an operator can be reconciled against what MendriX expected to pay.

One call answers with the line items of one operator, narrowed to a ride or a period, plus the ride, task and operator data those lines refer to.

  • An API token exchanged for an access token — see Authentication.
  • The token’s user needs the Purchase invoicing permission. Without it the call answers 403.
  • The operator you are reconciling needs an operator number in MendriX (at most 12 characters). It defaults to the operator’s internal id but can be changed, and it is the value you identify the operator with. MendriX does not enforce that it is unique, so if two operators share one, the API says so rather than guessing (see Errors).

Every list call identifies exactly one operator, with either operatorNumber or operatorId — never both, never neither. Supplying both is rejected even when they point at the same operator.

ParameterUse it when
operatorNumberYou know the operator by the number your MendriX administration uses (the usual case).
operatorIdYou already store the internal id, as the operatorId fields in earlier responses carry it.

Next to the operator, a narrowing criterion is required: rideId, rideReference, or fromDate together with toDate. Without one the request is rejected with 400 — otherwise a single call could pull an operator’s entire purchase history. Supplying several narrows further; they combine with AND.

Terminal window
# All purchase line items of one ride.
curl "$MENDRIX_BASE/purchase/line-items/?operatorNumber=88&rideId=123" \
-H "Authorization: Bearer $MENDRIX_ACCESS_TOKEN" \
-H "Accept: application/json"
# Everything the operator drove in June 2026.
curl "$MENDRIX_BASE/purchase/line-items/?operatorNumber=88&fromDate=2026-06-01&toDate=2026-07-01" \
-H "Authorization: Bearer $MENDRIX_ACCESS_TOKEN"
# By the reference entered on the ride (ritkenmerk). It is not guaranteed to be unique, so this
# may return the lines of several rides.
curl "$MENDRIX_BASE/purchase/line-items/?operatorNumber=88&rideReference=PO-88123" \
-H "Authorization: Bearer $MENDRIX_ACCESS_TOKEN"

The period is half-open: fromDate is included, toDate is not. Pass the start of the next period as toDate — June is 2026-06-01 to 2026-07-01, not to 2026-06-30. Consecutive periods then neither overlap nor leave a gap.

The date matched is the planned start date of the ride the line was calculated for.

The lines are in data.items. The ride, task and operator data they refer to is not repeated on every line: it is returned once per response in data.context, as three lists to look up by the rideId, taskIds and operatorId on a line.

{
"data": {
"code": 200,
"items": [
{ "id": "556677", "rideId": 123, "operatorId": 88, "taskIds": [201, 202],
"code": "TRANSPORT", "description": "Purchase transport",
"revenueGroup": "TRANS",
"quantity": 2, "freeQuantity": 0.5, "unitPrice": 850,
"additionalAmount": 15, "minimumAmount": 100,
"amount": 1290, "currencyCode": "EUR",
"date": "2026-06-10T00:00:00+02:00", "status": "open" }
],
"itemCount": 1,
"maxSequence": "40155",
"nextCursor": "",
"hasMore": false,
"context": {
"rides": [
{ "rideId": 123, "date": "2026-06-10T08:00:00+02:00",
"reference": "PO-88123", "nameManual": "Fixed Tuesday ride",
"nameAutomatic": "Amsterdam - Rotterdam" }
],
"tasks": [
{ "taskId": 201, "type": "load", "dateTime": "2026-06-10T08:00:00+02:00",
"yourReference": "ORD-4711", "ourReference": "MX-2026-0456",
"location": { "name": "DC Amsterdam", "city": "Amsterdam", "country": "NL" } },
{ "taskId": 202, "type": "unload", "dateTime": "2026-06-10T12:00:00+02:00",
"yourReference": "ORD-4711", "ourReference": "MX-2026-0456",
"location": { "name": "Client Rotterdam", "city": "Rotterdam", "country": "NL" } }
],
"operators": [
{ "operatorId": 88, "operatorNumber": "88",
"vatNumber": "NL123456789B01", "name": "Jansen Transport BV" }
]
}
}
}
FieldMeaning
idId of the line item. Stable for as long as the line exists — see step 5.
rideIdRide this line belongs to; its details are in context.rides.
operatorIdOperator the purchase is owed to; details in context.operators.
taskIdsTasks this line covers; details in context.tasks. A leg line references its load and unload task, a ride-level line every task of the ride.
codeCode of the purchase article; empty for a manual line.
descriptionLine description as the planner sees it.
revenueGroupRevenue group code of the article; empty for a manual line.
quantity, freeQuantityThe quantity the unit price is charged over, and the part of it that is free of charge.
unitPrice, additionalAmount, minimumAmountPrice per unit, the surcharge on top of quantity times unit price, and the amount the line is raised to when it would otherwise fall below it.
amountThe expected amount, and the figure to reconcile against. It is net — the purchase calculation knows no VAT. In the example: (2 - 0.5) × 850 + 15 = 1290.
currencyCodeISO currency code of every amount on the line; always EUR.
datePlanned start date of the ride the purchase was calculated for, in local time.
statusopen while the line is not matched to a purchase invoice line, matched once it is.

operatorId and date are null on a line whose purchase has not been calculated for a planned ride yet. Such a line cannot be found by operator, by period or with sort=date, so it never turns up in a list result — only in a lookup by id.

  • rides — date (planned start), reference (the ritkenmerk, empty when none was entered and not guaranteed unique), nameManual (the name the planner typed, empty when the name was left automatic) and nameAutomatic (the name MendriX derived from the route).
  • tasks — type (load, unload, or unknown for any other kind of task), dateTime (planned moment, or the realised one when no planned moment is known), yourReference (uw kenmerk), ourReference (ons kenmerk) and location (name, city, two-letter ISO country).
  • operators — operatorNumber (the value to identify the operator with), plus vatNumber and name as verification fields: check them against the invoice you received, but never use them as a search key.

A ride whose lines span two pages appears in the context of both pages.

This endpoint pages like the rest of the API (see Pagination & sync), but with lower page sizes: limit defaults to 10 and is capped at 100. A larger limit is accepted but clamped.

The reason is the context block: one line can pull in its whole ride and every task of that ride, and a ride can hold dozens of tasks, so the response grows with that context rather than with the number of lines. To cover more ground, narrow the query by ride or period and follow nextCursor.

sort supports id (the default) and date, each with a - prefix for descending. Keep the same sort for every page of one walk: a cursor resumed under a different ordering is rejected with 400.

For a recurring job, ask only for what changed: pass the maxSequence of your previous run back as since=.

Terminal window
curl "$MENDRIX_BASE/purchase/line-items/?operatorNumber=88&fromDate=2026-06-01&toDate=2026-07-01&since=$WATERMARK" \
-H "Authorization: Bearer $MENDRIX_ACCESS_TOKEN"
  • since= is a sequence number, not a date — the maxSequence from the response envelope. Store it after a successful cycle and pass it back next time. It is exclusive: you get the lines whose sequence is greater than the value you pass.
  • Bootstrap with since=1. Only a request carrying since= reports a maxSequence that is a real high-water mark, frozen for the whole cycle; without it the field is just the highest sequence on the page you fetched. So start with since=1 — it reads everything in the period and gives you a watermark to keep.
  • since= requires the default sort; combining it with sort= is rejected with 400.
  • Recalculating a ride’s purchase re-stamps all of that ride’s lines, so a sync run re-delivers lines that did not themselves change. Make your upsert idempotent.
  • Deletions are not visible in this feed. A removed line simply stops being returned; nothing marks it as gone. Run a periodic full resync — re-read the period with since=1 — and treat whatever it does not return as gone.
  • An id stays the same for as long as its line exists, which is what makes it usable to refer back to, but it is not a permanent reference. Treat the list as the source of truth and expect a stored id to stop resolving at some point.
Terminal window
curl "$MENDRIX_BASE/purchase/line-items/556677" \
-H "Authorization: Bearer $MENDRIX_ACCESS_TOKEN"

Answers the same envelope as the list — data.items holds that single line and data.context its ride, tasks and operator — and takes no parameters at all, not even an operator key: the id identifies the line on its own.

It answers 404 once the line is no longer part of the operator’s current purchase, for instance because it was removed or because the ride was replanned. Whatever the list no longer returns, this endpoint no longer returns either.

GET /purchase/line-items/ — the full contract is in the reference.

ParameterTypeNotes
operatorNumberstringOperator number as set up in MendriX, at most 12 characters. Exactly one of this and operatorId.
operatorIdintegerInternal id of the operator. Exactly one of this and operatorNumber.
rideIdintegerOnly line items of this ride.
rideReferencestringOnly line items of rides carrying this reference. Not unique; must not be empty.
fromDatedateStart of the period, inclusive. Requires toDate.
toDatedateEnd of the period, exclusive. Requires fromDate.
statusopen | matchedDefaults to both.
sinceintegerOnly lines changed after this sequence number.
sortid | date- prefix for descending. Default id.
limitintegerDefault 10, maximum 100.
cursorstringThe nextCursor of the previous page.

At least one of rideId, rideReference, or fromDate + toDate is required.

GET /purchase/line-items/{lineItemId} takes no parameters.

Next to the common status codes:

StatusCause
400Both operatorNumber and operatorId, or neither. No narrowing criterion. An empty rideReference. Only one of fromDate / toDate, a non-ISO date, or toDate not later than fromDate. An unknown status. A non-numeric since. since combined with sort, or a cursor resumed under a different sort.
403The token’s user lacks the Purchase invoicing permission.
404No operator with that number or id (a removed operator answers the same as an unknown one). Or, on the by-id endpoint, no such line item.
409The operator number is in use by more than one operator, so it does not identify one. Make the number unique in MendriX and retry.
  • Reconcile net. amount excludes VAT; an operator’s invoice total usually includes it.
  • Verify the party. Check context.operators[].vatNumber and name against the invoice before booking anything against the lines.
  • One invoice line rarely equals one purchase line item. An operator’s invoice line can cover one article of one ride, a whole ride, or one article across many rides — a diesel surcharge over a period, say. Match one invoice line to the set of purchase line items it covers.
  • Watermark after success, so a failed run safely re-reads next time.