Three changes to how a product is written. None of them affect an existing
integration — the API is not live yet — but they change what a correct POST /v1/products looks like, so read this before you write the mapper.
shipping.ship_with_us is always on, and no longer yours to set#
Every listing created through this API ships with Biklo. We quote the courier, the buyer pays delivery at checkout, and we book the waybill.
It used to default to false and honour whatever the payload said. That meant an ERP
which simply omitted the shipping object published a catalogue nobody could order
from — the listings looked fine, and nothing in the response said why no orders
arrived. There was never a good reason to switch it off, because a listing a courier
cannot be booked for is unbuyable here.
Sending ship_with_us still succeeds; it is ignored. You can drop it from your
payload. A listing that somehow has it off is repaired by the next write.
The field is still returned, and is still worth reading: an older listing created in
the dashboard can read false until it is next written through this API.
external_id is required#
It is the only thing tying a listing here back to a row in your system, and it is what a repeated push matches on. Without it, a retry after a timeout creates a second listing instead of updating the first — and you have no way to find either.
It was optional, which made the safe path the one you had to know about. Now the safe path is the only one.
This matters most on POST /v1/products/batch: a retried batch without it would
duplicate every product in it.
stock is required#
Send 0 for something you are out of — that is a real answer and it is accepted. The
field is rejected only if it is negative or not a number (invalid_stock).
Previously a create could omit it and the listing carried no stock figure at all, which is not a state worth being able to reach.
PATCH /v1/products/{id}/stock is still the cheaper way to move it afterwards.
Corrections to the documentation, not to the API#
Separately, a large number of response examples were wrong — they showed two to four
fields where the endpoint returns the whole object. POST /v1/products, PUT /v1/products/{id} and both PATCH routes all return the complete product, and always
did. PUT /v1/company/shipping-absorption documented country_id and
min_amount_cents, which no response has ever contained.
Every endpoint now documents every field it returns, with its type and meaning. If you built against an example rather than against what came back, it is worth a second look.
