Three filters returned the wrong rows
A literal % in a filter value dropped the filter. series_code matched any series containing the code. Sorting customers ignored the documented field names. Only series_code changes a response you may rely on today.
Three cases where a filter or an ordering you sent came back 200 having done something other than what you asked. A literal % in a value dropped the filter entirely; series_code matched any series containing the code you sent; and sorting customers only understood undocumented field names. All three now either work as documented or tell you they cannot.
Only series_code changes a response you may be relying on today. The other two turn a wrong 200 into a 400 that names the problem.
What else changed
- A literal
%in a filter value dropped that filter.?search=100%OFFor?status=DRAFT%came back200with the collection unfiltered — not an error, just every row. This is what any client that builds its query string without percent-encoding the values produces, so it did not take a strange request to hit it: asking for your drafts returned every invoice on the account. A value whose percent-encoding is malformed is now named and rejected. Encode the value and it works as before — a literal%is%25. - That rejection joins the date already announced. It travels on exactly the mechanism from the strict query parameters change: the canonical routes reject it today, the flat aliases answer
200with aBeeL-Warningheader naming the parameter until 2026-09-03, then reject too. No new date to track, and the header tells you which of your requests are affected before then. series_codenow means one series, not any series containing it. It was matching as a substring, so?series_code=Ralso returned everything filed underSTR— and there was no way at all to ask for a single series. It now matches the series code exactly, still ignoring case. This is the one change that can quietly return fewer rows than yesterday: if you were relying on the substring behaviour to sweep several series at once, usesearch, which is documented as a partial match across the invoice number, the recipient and the series code.- Sorting customers now takes the field names we document.
sort_by=city,province,activeandlegal_namewere accepted with200and then ignored, falling back to the default order — includinglegal_name, the example in our own reference. They now sort. The full vocabulary islegal_name,nif,email,phone,city,province,active,created_at; anything else is answered with400listing those. If you were sending the Spanish field names that happened to work, they are the ones that stop being accepted — the names above are the same ones the filters on that operation already use. - Paging through customers no longer repeats or skips anyone. The order had no tie-breaker, so customers sharing a legal name — the field sorted by default — could appear on two pages or on none. Ordering is now total, and a full walk of the collection returns each customer exactly once.
Endpoints
- GET/v1/companies/{company_id}/invoices
series_codematches one series exactly; a malformed%in any filter value is named and rejected - GET/v1/companies/{company_id}/customers
sort_bytakes the documented field names and pages without repeating rows
Where to go next
Resources under the NIF
An account can now hold several NIFs, each named in the path. The old flat routes are deprecated with a Sunset date and a successor — here's what moved where, when the old routes retire, and how to tell whether it affects you.
Rate limits now count per IP
The published global ceiling drops to 1000 req/60 s to match what was already enforced. Strict and Global count **per IP**, not per credential.