Every claim in this release was checked against a live P21 tenant (build 26.1.5910.3), and several were checked against two production integrations that run these APIs daily. Where something could not be verified, it now says so.
Every example is a complete program
Paste it into a file, edit the constants in its EDIT THESE block, run it. No repo clone, no .env, no helper imported from another page. Python needs only httpx; C# targets net9.0 with System.Text.Json and no NuGet packages, so dotnet new console + paste + dotnet run works. Every write ends with a read-back that prints what actually landed — in this API a 200 routinely lies.
Verified mechanically: 111 Python blocks parse, 80 complete C# programs compile, and both auth preambles plus a sample of converted programs were run against a live tenant. The convention is now written down in CONTRIBUTING so it survives the next contribution.
Corrections — things this documentation had wrong
- The OData
inoperator is accepted and silently ignored.id in (2,3,4)returned all 50,077 rows of the view. A genuine syntax error 404s loudly, so this fails in the one way you cannot notice. The N+1 section previously recommended IN clauses while its own example still looped per id. row_status_flagdoes not exist oncustomer,supplierorinv_mast— those usedelete_flag. The doc's own example (supplier_id eq 10050 and row_status_flag eq 704) returns a 404. Where the column does exist: 704 Active, 705 Inactive, 700 Delete.- The company column has two names —
company_noonpo_hdr/po_line/invoice_hdr,company_idonoe_hdr/customer/inv_loc/contacts, neither onsupplier/inv_mast/address. JobContractPricing's first break tier iscalculation_value1, not the unsuffixed name both create examples were sending.sales_price_pageis not an OData table (it 404s) — it isprice_page.po_line_notesdoes not exist — the table ispo_line_notepad.- A session can only be deleted by the token that created it. Every other form returns
400 Invalid session, orphaning it until cleanup expiry. IgnoreDisabled: truecan report success and write nothing — on a disabled tab and a disabled column. Its two outcomes are indistinguishable in the response.GET /v2/windowreturns only the active tab's datawindows, as a map keyed by name — not the array the previous helper iterated.
New
Shipping carrier tracking numbers (and why they cannot be set post-invoice), the purchase-side pricing services, the cross-service break-field naming split, "Item Issues Detected" root-caused to a DynaChange rule with a SQL data fix, field length limits and how to measure one without fooling yourself, and a reassign-salesrep recipe. Closes #103, #105, #106, #107.
The site no longer scrolls sideways
At any width, on any page. Tables fit rather than scroll, and three further causes of page-level horizontal scroll were removed — a flex item that could not shrink, a mobile breakpoint that fired too late, and a fixed button that widened the layout it was measured against. Verified across 320 combinations: all 32 pages at ten viewport widths from 320px to 1440px, zero page scroll, zero table overflow.
Full detail in the changelog.