Skip to content

Filtering and sorting

Open .md

To find records that match conditions, use a resource’s filter operation. Filters use POST because they carry a body, but they only read.

Terminal window
curl https://secure.yoprint.com/v2/api/store/your-team/v2/sales_order/filter \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "X-Yoprint-Decimal-Format: exact-v1" \
-H "Content-Type: application/json" \
-d '{
"filters": [
{ "key": "is_rush", "operator": "eq", "value": true },
{ "key": "due_date", "operator": "lte", "value": 7 }
],
"sort": [{ "key": "due_date", "direction": "asc" }]
}'

This returns rush sales orders due before the 7th day from today starts in UTC (overdue ones included), soonest first, one page at a time. Date values count UTC days, and v1 filters count them differently. See Dates.

Field Meaning
filters A list of conditions. Each has a key, an operator and a value. A record must match every condition.
sort A list of sort objects, each with a key and direction (asc or desc).
page The page number to return. See Pagination.

Each resource allows filtering and sorting only on specific supported fields. To find the exact keys and allowed operators for a resource:

  • Open that resource’s filter operation in the API reference, such as List sales orders, Search customers with filters or Filter jobs.
  • The operation’s reference page lists every accepted filter key, its value type, its supported operators, and every accepted sort key.
  • Sending an unlisted or misspelled key, or using an operator not supported by that field’s type, is refused with HTTP 422.

The operators a condition can use depend on the type of its key:

Field type value Operators
Boolean, such as is_rush true or false eq, neq
Date, such as due_date A whole number of days from today, not a date eq, gte, lte
Number or amount A number eq, gte, lte
Reference to other records, such as statuses, tags, customers or users A list of hash ids in, nin (not in)
Single option, such as payment_status (paid or unpaid) A string eq
Multiple option A list of strings in, nin

A condition with a missing or null value, an unknown key or an operator its type doesn’t allow is refused with 422.

Dates are days from today, and v1 and v2 count differently

Section titled “Dates are days from today, and v1 and v2 count differently”

A date condition’s value is a whole number of days from today: 0 is today, 7 is a week from today and -30 is 30 days ago. A date such as "2026-11-12" isn’t accepted: it’s refused with 422. Days are UTC days, not your shop’s days. The two filter versions also count from different points, and v1 counts lte backwards:

Filters Count from lte N matches
v2: sales orders, quotes and invoices 00:00 UTC at the start of day N Everything before day N starts. Day N itself is left out.
v1: customers, jobs, tasks, shipments, packages, approvals and integrations Now On or before now minus N days
The production control calendar (a v1 path that counts forward, like v2) Today’s UTC date On or before the date N days from today, counting the whole day
  • v2 · lte 7Everything before the 7th day from today starts, overdue included
  • v1 · lte 7Only dates 7 or more days ago
  • v1 · lte -7Everything up to 7 days from now: in v1, a negative number reaches forward
The same condition finds next week's work in v2, and only work from over a week ago in v1.

YoPrint turns N into a date, today’s UTC date plus N days, and compares the record’s date and time with 00:00 UTC on that day:

Operator Matches
gte N From 00:00 UTC on day N onwards.
lte N Up to 00:00 UTC on day N. Day N itself is left out: send N + 1 to include it.
eq N Only a date stamped exactly 00:00:00 UTC on day N. It matches almost nothing, so use a gte and lte pair instead.

Dates the web app sets are stored as the end of the shop’s day, in UTC. A due date of 12 November in New York is stored as 2026-11-13T04:59:59Z, on the next UTC day. So a UTC day and your shop’s day don’t line up, and a filter can’t pick your shop’s days exactly. Ask for a slightly wider range, then keep the right rows in your code:

  • Your shop’s days A to B (in days from today): ask gte A-1 and lte B+2, then keep the rows whose date falls on those days in your shop’s time zone. The extra day at the start covers time zones ahead of UTC. The two extra days at the end cover time zones behind UTC and the left-out day N.
  • Overdue (the date is before now): ask lte 1, then keep the rows whose date is before now.

Worked example: due today and tomorrow in New York

Section titled “Worked example: due today and tomorrow in New York”

Today and tomorrow are days 0 and 1. Ask for gte -1 and lte 3, then keep the orders whose due_date, read in New York time, is today or tomorrow. With the yoprint helper from Calling the API:

const zone = 'America/New_York';
// A date as YYYY-MM-DD, on the shop's calendar.
const shopDay = (date) => new Intl.DateTimeFormat('en-CA', { timeZone: zone }).format(date);
const today = shopDay(new Date());
const [y, m, d] = today.split('-').map(Number);
const tomorrow = new Date(Date.UTC(y, m - 1, d + 1)).toISOString().slice(0, 10);
const page = await yoprint('POST', '/v2/api/store/{team_slug}/v2/sales_order/filter', {
filters: [
{ key: 'due_date', operator: 'gte', value: -1 },
{ key: 'due_date', operator: 'lte', value: 3 },
],
sort: [{ key: 'due_date', direction: 'asc' }],
});
const dueTodayOrTomorrow = page.data.filter(
(order) => order.due_date && [today, tomorrow].includes(shopDay(new Date(order.due_date))),
);

Read every page of the answer the same way. See Pagination.

You want v2 filters v1 filters
Due from today through the 7th day from now gte -1 and lte 9, then keep your shop’s days in code gte 0 and lte -7 (now to 7 days from now)
Overdue lte 1, then keep the dates before now lte 0 (before now)
Created in the last 30 days gte -30 (from 00:00 UTC 30 days ago) gte -30 (from now minus 30 days)
v1 date operators, exactly
Operator v1: matches a date…
gte N on or after now + N days
lte N on or before now − N days (counts backwards)
eq N anywhere in UTC day today + N

The invoice filter’s order dates count whole days. On the v2 invoice filter, the keys that read the invoice’s order (order_issue_date, full_amount_due, deposit_due, order_cust_due_date and order_ship_due_date) compare whole UTC days. lte N includes all of day N, and eq 0 matches anywhere in today’s UTC day. The invoice’s own created_at follows the v2 rule above. Asking for a wider range and narrowing it in your code works here too.

References take a list of hash ids, even for one value:

{ "key": "status_id", "operator": "in", "value": ["BkzhmfgkK2HFTs", "ZXhN3KtjHgQZFz"] }

Get status ids from the status lists, such as:

GET List sales order statuses /v1/api/store/{team_slug}/setting/status/sales_order

The sort array controls the order of returned records. Each sort item is an object with a field key and a direction:

{
"sort": [
{ "key": "created_at", "direction": "desc" }
]
}
  • direction: "asc" for ascending (earliest date first, lowest number first, A to Z) or "desc" for descending (latest date first, highest number first, Z to A).
  • v2 filters (sales orders, quotes, invoices): apply only the first entry in sort. Any subsequent entries in the array are ignored.
  • v1 filters (jobs, customers, shipments and others): apply every entry in order, sorting by the first key and breaking ties with the second.
  • Default order: on a v2 filter, an omitted or empty sort uses the resource’s default order (typically created_at descending). v1 filters have no default order: send sort whenever the order matters.
  • Pagination stability: sort by a field that doesn’t change, such as created_at. See Pagination.
  • Allowed keys: You can only sort by keys listed on that resource’s filter reference page. Unrecognized sort keys are refused with 422.
Feature v1 filters v2 filters
Applicable resources Customers, jobs, tasks, shipments, packages, approvals, integrations Sales orders, quotes, invoices
Empty filters Refused (422). Send at least one condition. Allowed: returns every record, a page at a time.
Sort entries used All entries in order (multi-field sort) The first entry only (single-field sort)
lte date operator Counts backwards into the past (now - N) Counts forwards into the future (start of day + N)
Count only No "count_only": true returns the pagination block without records.

To find an order from a few words, such as its number, its name or the customer’s name, use search:

GET Search sales orders and quotes /v2/api/store/{team_slug}/search/orders

It takes q, and optionally customer_id and quote (1 for quotes only, 0 for sales orders only, or leave it out for both). true or false for quote is refused with 422. It returns up to 30 matches.

Many reads accept with, a list of related records to include, and only, a list of fields to return. Use them where an operation’s reference page documents them. The v2 filters accept only some related records.