Morffeus Docs
morffeus.com

Pagination & filtering

List endpoints return one page at a time. You choose the page with offset and limit, and you have reached the end when a page comes back with fewer rows than you asked for. Lists do not tell you how many rows there are in total.

Paging#

limit is how many rows you want, offset how many to skip. The second page of 100 is offset=100&limit=100.

The response is the page under data and nothing else: no total, no page count, no link to the next page. Keep asking with a larger offset until a page is shorter than limit.

Each list has its own default page size, so always send limit. Page in a fixed order: when records change while you page, a row can move from one page to the next.

Every order, page by page
const limit = 100;
const orders = [];
for (let offset = 0; ; offset += limit) {
  const url = `https://api.morffeus.com/api/v2/orders?orderBy=id&offset=${offset}&limit=${limit}`;
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.MORFFEUS_TOKEN}` }
  });
  const { data } = await res.json();
  orders.push(...data);
  if (data.length < limit) break;
}

The lists#

EndpointPaging
GET /productsoffset and limit, default 10. Also pageNo and perPage: pageNo=3&perPage=20 is offset=40&limit=20. The products are in data.products; see Your first request.
GET /ordersoffset and limit, default 30, at most 10,000 per page.
GET /customersoffset and limit, default 30.
GET /warehousesoffset and limit, default 30.
GET /stocksoffset and limit, default 30.
GET /stock_movementsNot paged: you get every movement between dateFrom and dateUntil. Keep the range short.

Sorting#

EndpointHow to sort
GET /ordersorderBy with one field and an optional asc or desc, for example orderBy=order_date desc. Fields: id, order_number, order_date, invoice_number, sales, net_sales, discount, vat, paid, debt, customer_name. A field alone sorts ascending. Anything else falls back to the default, newest first, without an error. Rows with the same value are ordered by id, newest first.
GET /productsorderBy with name, price (the lowest price of the product), inserted_at or sales_quantity, followed by desc in lower case to reverse it: orderBy=price desc. Separate several with a comma and no space. Default: by name; with a search, best matches first.
GET /customersBy first name.
GET /warehousesBy name.
GET /stocksBy product.
GET /stock_movementsIn the order they were booked.

Filtering#

Filters are query parameters in camelCase. Ids are our ids; the codes are yours.

EndpointFilters
GET /productssearch (product names), searchAll (names, product and variant codes and barcodes), code, barcode, slug, id, priceFrom, priceTo, onlyOnStock. One of code, barcode, slug or id on its own returns a single product.
GET /orderssearch (order and invoice number, customer name, email and phone), customerId, appLocationId, dateTimeFrom, dateTimeTo.
GET /stockswarehouseId, productId, productVariantId. See Stock.
GET /stock_movementsdateFrom and dateUntil, both required; warehouseId, productId.

Dates#

Send dates as ISO 8601, a date alone or a date and a time: 2026-09-01 or 2026-09-01T14:30:00. Both ends are included. A date alone means midnight at the start of that day, so dateUntil=2026-09-30 ends as the 30th begins; send 2026-09-30T23:59:59 to include the whole day.

Last updated 30 September 2026 · API v2 Something wrong on this page?