On this page

Task Index — Find the Right Section Fast

How to use this repo without drowning in it: the numbered docs are the deep manual — most are over 1,000 lines. Don't read a whole doc for one task. Find your task below and open only the linked section. If you're an AI assistant: read CLAUDE.md, then this index, then just the sections your task needs.

Every task assumes you already have a token and (for Transaction/Interactive) the UI server URL — see Getting a token below.

Doing, not studying? The recipes cookbook has self-contained copy-and-run pages (complete payload + full script + gotchas) for the most common tasks — start there and fall back to the manual sections for depth.


First call of any session

Task Where
Get a bearer token (v2, credentials in body) 00 § Method 1: User Credentials
Authenticate with a consumer key 00 § Method 2: Consumer Key
Get the UI server URL (Transaction/Interactive base) — 307 redirect gotcha 00 § UI Server URL
Token TTL / reuse across APIs 00 § Token Lifetime and Reuse
Detect P21 server version / production flag (undocumented endpoint) 00 § Server Info Endpoint
Fix "not authorized" (P21 user permissions) 00 § P21 Permissionsor, if using a consumer key, its scope may simply exclude the table you asked for; decode the token's aud claim before assuming it's a permission gap
Pick which API to use for a task 01 API Selection Guide (short — read whole)
A write failed — will the other API get through? (usually no) 01 § Interactive Is Not an Escape Hatch

Read data (OData)

Task Where
Query a table or view 02 § Query Parameters
Filter syntax, operators, string functions 02 § Filter Expressions
Only active rows — row_status_flag or delete_flag, depending on the table 02 § Active Record Filter — soft-deleted rows keep their old values and dominate some tables
Compare two columns in a $filter (total_amount gt amount_paid) 02 § The right-hand side is always a literal — 404 on typed columns, silently zero rows on strings
Age open AR / build a receivables aging recipes/ar-aging — runnable, pages invoice_hdr, buckets on each invoice's own net_due_date
Age open AR / "how late is this invoice?" 02 § customer.terms_id is the default for the next document — age on the invoice's own net_due_date
Filter 404s on a value that looks right (Edm.Decimal vs Edm.String) 02 § Active Record Filter — many *_id columns are numeric; don't quote them
Company column is company_id on some tables, company_no on others 02 § Company Scoping
Read a customer/supplier/ship-to mailing or physical address over OData (address table) 02 § Common Tables — columns keep the mail_/phys_ prefix (mail_address1, not address1); 404 without it
Traverse relationships (no joins — chain by _uid) 02 § No Joins
Page through large result sets (no nextLink) 02 § Pagination Helper · 02 § Page Size Guidance
Date filters (now() is unsupported) 02 § now() Not Supported
New table/column missing from OData 02 § OData Schema Refresh
Empty-bodied 404 on a table you know exists 02 § The table/view split — views live on /view/, base tables on /table/; asking the wrong one 404s exactly like a missing object
Read a view (p21_view_*), or a user-defined table (*_ud, site-custom) 02 § The table/view split — views on /view/; *_ud are ordinary base tables on /table/
Table reads fine but is empty/inert (undeployed feature, e.g. zip→rep) 02 § Undeployed / Unlicensed Windows
Denormalized, search-friendly views (p21_view_es_*: customer, item, order, invoice, etc.) 02 § Enterprise/Global Search Views

Create / update records (Transaction API)

Task Where
Payload anatomy (TransactionSet / DataElements / Edits) 03 § Request Structure
Payload rejected / values not landing (shape & type mistakes) 03 § Payload Anatomy
Validate a payload offline before posting (JSON or XML) scripts/validate_payload.py · 03 § Payload Anatomy
Copy-ready payload files (JSON and XML, validator-verified) examples/payloads/
Send/receive XML instead of JSON 03 § XML Payloads
Get a service's schema, template, defaults 03 § Endpoints · committed full-field JSON in definitions/
Update an existing record (Status "New" + keys; "Existing" is broken) 03 § Updating an Existing Contract
Insert new keyed rows (upsert) + one-tx-per-POST rule 03 § Upsert Semantics
Two lines came back as one — same item twice, only the last quantity landed 03 § Keys — Row Identity and the Collapse Trap
Pick the right Keys for an element (and what over-keying breaks) 03 § Choosing a key · 03 § What the definition already tells you
Child rows all attached to the last parent (extended info, lots, breaks) 03 § The general rule: repeat the element pair
Read one record whole / clone an existing record 03 § Reading One Record
Read several records in one /transaction/get call (no field/element subsetting exists) 03 § Reading several records in one call
Failed: 1 but part of my batch landed 03 § What Failed actually guarantees — a Transaction is atomic; Transactions in one POST are not
Create a purchase order 03 § PurchaseOrder Service
Create a direct-ship PO from a sales order (drive a wizard) 04 § Driving an In-Window Wizard — needs a Buyer ID; commits at cb_next
Change the salesrep on an order or quote 03 § Order Service — Reassigning the SalesrepTP_SALESREPS.tp_salesreps; oe_hdr has no salesrep column
Transaction Failed with no reason on the transaction 03 § Failure detail is in the top-level Messages
"may currently be edited by USER" — write refused 03 § oe_hdr.completed = 'T' — pre-screen WHERE completed <> 'T'; usually an abandoned lock
Telling quotes from live orders 02 § Quotes are projected_order = 'Y'quote_type is NULL everywhere
"When did the supplier say this would ship?" 02 § po_line.supplier_ship_datenot a promise on direct-ship POs; use date_due
Confirm a direct ship (DirectShipConfirmation) 04 § DirectShipConfirmation writes its ship date down — overwrites supplier_ship_date on every line; checkboxes take ON/OFF
Receive a PO / receipt won't post (bin errors) 03 § PurchaseOrderReceipt Service
Vouch a receipt against a vendor invoice 03 § ConvertPOToVoucher Service
Column is disabled for my service account but not for a person 03 § Column is disabled Can Mean "Disabled For You" — role/DynaChange-scoped; test with the account that will run it
Is the definition's Required flag trustworthy? 03 § What Required actually meansno, wrong in both directions
Sequence contains no matching element / Invalid column name on a keyed write 03 § Choosing a key — every Keys field must be a real column and be sent in Edits
Write a note on an order (header/line) 04 § Sales Order Notepad Writes · 04 § PurchaseOrder Notepad Writes — Interactive only; /transaction refuses (why)
Write a note on a production order (note_type_cd 2758) 04 § Production Order Notes — Interactive only; /transaction reports success and writes nothing (why)
Write an item / customer / supplier note 03 § Commands Endpoint — one stateless POST · or 04 § Standalone Notepad Windows, where the mandatory area picker is cb_selectall via /tools
Call a commands-only service (notepads, reverse payment, slab adjustment) 03 § Commands Endpoint — request shape and Action codes
Get an async callback instead of polling 03 § Callbacks instead of polling
Fetch one record by key over OData 02 § The other OData surface/data/erp/views/v1/{view}('key')
Consumer key 401s on a table you just granted it 00 § The OData allow-list is baked into the token — scope is fixed at issue time and the tokens last ~20 years; mint a new one
Which OData version / what's supported 02 § Protocol version · 02 § What the service supports — v4; no server-driven paging
Does my server have endpoint X? 05 § Discovering what your tenant actually exposesapiref.aspx + per-family /help
Valid P21 login rejected by the middleware admin site 00 § Application Security settings — needs Access to SOA Admin Page
Attribute API writes to a real user, not the service account 00 § Attributing writes to a real user
Who can read a consumer key's value (DynaChange rules) 00 § Method 2: Consumer KeyRuleState.ConsumerKey exposes it to any rule author
Update a specific order line deterministically (line handles) 03 § Design for updates: assign your own line handles · recipe: update-order-lines
You cannot retrieve an RMA from the Order Entry/Front Counter window 03 § RMA Service — use the RMA service; route on oe_hdr.rma_flag
A tool is missing from GET /v2/tools on a multi-tab window 04 § Sales Order Notepad Writes — tool lists are tab-scoped and accumulate; select the tab first
Which discovery endpoint — definition vs defaults vs basics 03 § Endpoints
Write through disabled columns/tabs (IgnoreDisabled) 03 § IgnoreDisablednot a universal unlock; it can report success and write nothing
Contract break tiers refuse to save / "Tab page is disabled" 03 § VALUES Writes Are Refused on 26.1 · 14 § entry 8
Field order silently changing values 03 § Field Order Matters
Labels vs code_no (UseCodeValues, code_p21) 03 § UseCodeValues
Check success properly (HTTP 200 lies; per-tx pass/fail) 03 § Response Format · 06 § Transaction API Errors
Read a record back / verify a write 03 § Endpoints — /transaction/get
Long-running / async transactions (no cancel path once queued; status 2 ≠ success — outcome is a JSON string inside Messages) 03 § Async Operations
DynaChange rules & popup suppression for the API user 03 § DynaChange and Popup Handling
Run a stored procedure via API 03 § Stored Procedure Executor

By record type

Task Recipe Manual
Create a sales order + gotchas (source_loc_id, dates, DynaChange) create-sales-order 03 § Create Order · 03 § Order Service Gotchas
Order with an assembly line (explode / spawn prod order) order-with-assembly 04 § Sales Order Entry with Assembly Lines
Job contract: create, lines, breaks 03 § JobContractPricing Service
Job contract: update / add lines / commission costs update-contract-lines 03 § Updating an Existing Contract · 03 § Upsert Semantics · 03 § Commission Costs
Job contract: bin quantities edit-contract-bins 03 § Editing Bin Quantities (Interactive fallback: 04 § Tab Unlock Sequences)
Assembly / BOM definition 03 § Assembly Service
Item: primary bin / primary supplier at a location set-primary-bin-supplier 03 § Item Service
Create a brand-new itemItem service alone 500s with ...tabpage: TABPAGE_2 or A Default Sales Unit... Must Each Be Specified 03 § Item Service Gotchas — use 11 § Minimum Create Payload instead
Inventory REST create 500s — what does the error actually mean, is anything left behind 11 § An incomplete create payload 500s — message names the missing block; nothing persists on failure
Item: add a supplier to a location's list (the flip's prerequisite — both keys + IgnoreDisabled) set-primary-bin-supplier 03 § Adding a Location Supplier Row
Item: enable bin tracking at a location (track_bins, and the bin it auto-assigns) 03 § Enabling Bin Tracking
Create warehouse bins create-bins 03 § BinLocation Service
Sales price pages (codes, breaks, field order) 08 SalesPricePage Codes · 08 § Transaction API Alternative
Purchase-side pricing pages (supplier / item / discount group) 08 § Purchase-Side Pricing Services
Break fields named differently per service (calculation_value1 vs value1) 08 § Cross-Service Break-Field Names
Set a carrier tracking number on a pick ticket (and why not after invoicing) 03 § Shipping Service — Carrier Tracking Number
Reassign a salesrep (customer + ship-to) reassign-salesrep 03 § Payload Anatomy
Remove a rep from a customer's grid (no delete_flag — it's row_status_flag: "Delete") reassign-salesrep 03 § Customer Service — Removing a Salesrep Grid Row
A grid row looks undeletable — no delete_flag in the definition 03 § Read ValidValues before assuming a grid can't delete
Edit a salesrep's name/email (contact_id key; email on TABPAGE_2) 03 § Salesrep Service
Update a supplier's contact details (central email/phone live on Address, not Supplier) update-supplier-contact 03 § Salesrep Service
Modify an existing sales order (edit a line in place, add a line) update-order-lines 03 § Design for updates: line handles
Item Defaults per location (required before location-appends on fresh locations) 03 § ItemDefaults Service
Create bin zones (fresh-location prereq for bins) 03 § PutawayZone / PickZone Services
Create a customer (salesrep_id + default_branch gotchas, no zip→rep cascade) create-customer 03 § Common Services
Create a requisition PO (po_type 'R'; disabled po_hdr_po_type; vendor vs supplier) create-requisition-po 03 § Purchase Order Types
GL dimensions via API (voucher services carry them; POs don't) 03 § GL Dimensions in the API
Customers / vendors / contacts / addresses (simple CRUD) 05 § CRUD Operations
Read/create sales orders via REST (/api/sales/orders) 05 § Other REST Endpoint Families · 05 § Creating an Ordertrailing slash required; lines nest under Lines.list
Inventory items: read / create / update locations 11 § Reading Items · 11 § Minimum Create Payload · 11 § Updating Existing Location Fields
Append locations at scale (supplier-x-loc primary, GL requireds, kit Buy, OP/OQ, retries, PrimaryBin) 11 § Location-Append & Update Gotchas
Customer-specific price + availability lookup 11 § Pricing Endpoints
Batch price + availability lookup (multiple items in one call, JSON or XML) 11 § Batch Pricing
User-defined tables (UDT) rows 13 § Insert · 13 § Update · 13 § Deleteupdate/delete need a row_uid column; 2026.1-created UDTs don't have one
UDT delete "succeeds" but nothing is deleted 06 § [0] rows deleted · 14 § entry 7
Bulk-load a UDT from CSV (2026.1+) 13 § Bulk Data API — CSV upload; headerless file silently inserts nothing

Drive a window (Interactive API)

Task Where
Session → window → change → save lifecycle 04 § Session Lifecycle
v2 payload shapes (save body is the bare GUID, etc.) 04 § v1 vs v2 API Differences
Find field / tab / datawindow names 04 § Finding Field Names · 04 § Window Discovery
Open a window (use ServiceName — Name/Title can 400) · map window→service 04 § Open Window · 04 § Window→Service Discovery
The window has no service name (frame_menu.service_name NULL) — drive it by menu class instead 04 § The ui/full Surface
"Cannot open window ** ** because is not available" — the name came back blank 04 § Open Window — blank means the ServiceName never resolved
Handle popups / response windows (Status 3, windowopened) 04 § Response Windows · 04 § Response Window Types
Answer a rule-callback dialog ("Item Issues Detected") 04 § Worked Example — but fix the data first: 03 § Root Cause and Data Fix
Answer a w_message dialog — it's fully controllable, not just auto-answered 04 § Worked Example: w_message
Fill fields in a popup (TabName: null) 04 § Response Window Handling (Tabless)
Buttons / tools (?windowId=, not ?id=) 04 § Running Tools
Unlock a disabled tab 04 § Tab Unlock Sequences
Row selection traps (sync bug, detail-form rebind, row 0) 04 § Known Issues and Workarounds
Key field silently swallowing later edits 04 § Key Fields Commit the Cursor
Verify a save actually persisted 04 § Verifying Writes
PO notepad notes (header vs line) 04 § PurchaseOrder Notepad Writes
Bulk/batch interactive work (session reuse, error recovery) 09 Batch Processing Patterns
Intermittent "Unexpected Response Window" in production 07 Session Pool Troubleshooting

Production & manufacturing

Task Where
Service catalog & schemas (ProductionOrder, TimeEntry, …) 12 § Available Services
Assembly behavior flags (prod-order vs kit vs build-to-stock) 12 § Assembly Behavior Flags
Full runbook: create → print → confirm → complete → ship recipe: production-order-runbook · 12 § Production Order Lifecycle
Pick ticket won't generate (make loc vs stock loc) 12 § Printing the Pick Ticket · 03 § m_picktickets example
Confirm a pick (shell-confirm trap — use Interactive) 12 § Confirming the Pick
Complete / production receipt (+ per-component cost override) 12 § Completing the Production Order
Record labor hours recipe: record-labor-time · 12 § Recording Labor Hours · 12 § Time Entry Against a Production Order
Ship + invoice 12 § Shipping and Invoicing
Inventory write-off / adjustment recipe: inventory-adjustment · 12 § Inventory Adjustment
Why COGS doesn't match the receipt 12 § Cost Model

Documents & reports (PDF)

Task Where
Generate any m_* report as PDF recipe: generate-pick-ticket-pdf · 03 § PDF Report Generation
Discover callable report names (hidden from /services) 03 § PDF Report Generation (Discovery note — includes the right-click SQL Help path)
Report returns nothing / runs forever / works for one user only 03 § Report windows are still windows — permissions, DynaChange date caps, cancelling the request does not stop the run
Production pick ticket at a specific location 03 § m_picktickets example
PDFs from print flags on a normal transaction 03 § PDFs from the /transaction endpoint

When something breaks

Task Where
Upgrading P21? What breaks between versions 14 Breaking Changes — registry re-run unchanged on 26.1.5950.0; 2026.1 (sequential fail-fast batched changes, silent-false-success loads, IgnoreDisabled, bad-DatawindowName poison) · resolved in 5940.0 (Accept-header 500, ghost sessions) · 25.2 (DatawindowName)
Empty HTTP 500, no body, on an interactive call 14 § entry 9 — a bad DatawindowName on the previous request; not the Accept header on current builds
What user-defined fields exist in this P21? 15 § extensibility/userdefinedfields — every UDF with type metadata, grouped by table; {tableId} is the *_ud name, not the base table
Read a whole GL journal entry in one call 15 § accounting/glGET /api/accounting/gl/{transactionNumber} returns every line, balanced; Source walks back to the originating document
Create or update a CRM task / activity 15 § sales/tasks — verified round trip; "Customer ID is required" means LinkId
A REST family's list route hangs or returns tens of MB 15 § The bare collection GET is an unbounded full-table dump — no paging, and $top is silently ignored; key off OData instead
Post a balanced GL entry over REST 15 § accounting/gl § Posting a journal entryPOST /api/accounting/gl/ takes an array of lines; an unbalanced batch is refused server-side with "Records do not balance"
Create a PO over REST and the price comes back 0.00 15 § purchasing/purchaseorders § Creating a POUnitPrice is not honored on create, PriceEdit: "N" routes it through pricing lookup instead; use the Transaction API PurchaseOrder service when the price must be exact
PO create fails Buyer ID... Invalid buyer ID / an unmatched Sales/Production/PO Intersection 15 § purchasing/purchaseorders § Creating a POBuyerId empty is the real cause of both messages; the create is built on P21's Import/Export engine, hence the escaped XML error body
createWmsAdjustment fails Bin is required or can't find the adjustment reason 15 § inventory/inventoryadjustments § createWmsAdjustmentbinCd is mandatory on a bin-tracked location; reason must name a currently-active reason record, not a historical one
GET /odataservice/odata/table/bin (or /view/bin) 404s with an HTML page, not JSON 02 § One object name is unreachable regardless of surface: bin — likely an IIS routing collision with the reserved bin/ folder name; read inv_loc.primary_bin or bin_ud instead
Upload/download/delete a real file over REST 15 § filehandler — full round trip verified; this is a real network file share, not a sandbox
Read the middleware's build/config without the serverinfo XML trap 15 § environment/systems — JSON directly; no /ping on this family, and needs a trailing slash in C#
Move stock bin-to-bin without changing on-hand quantity 15 § inventorymovementY/N not booleans, toBin must already be a real association, "success" doesn't guarantee a nonzero move
Stage a cycle count without touching live on-hand 15 § externalcountsItemId must be repeated on the bin sub-record, not just the line
Resolve a scan term / barcode / customer part number to an item 15 § partscanSource names which identifier matched
Set a customer's invoice/RMA/packing-list report template 15 § customerformtemplatesPUT is not a blind upsert; a null uid against an existing row fails "data already exists"
A "service order" REST family that looks like it should be separate from Order Entry 15 § service/serviceorders — it resolves against any oe_hdr.order_no; the family is a view, not a distinct object
sales/opportunities / consignmentusageorders / exchangerates create fails with a confusing error 15 §§ each family — check the tenant's own lookup tables (opportunity status/stage/type/step, a consignment contract, a second currency) before assuming the API is broken
Which REST endpoints/families does my tenant actually have? 05 § Discovering what your tenant actually exposes/docs/apiref.aspx lists every family (takes a bearer token); confirm one with /help, never /ping. Plus /api/v2/services (Transaction) and the OData service document
Token call returns HTTP 500 Unable to generate client token. 06 § Token Endpoint Errors — the consumer key is not registered on that tenant; read InnerException, not ErrorMessage. Common after a test-tenant refresh from production (00)
Status: "Existing" / "Update" rejected on a transaction 03 § Status: "New" is the only value — one-member enum; 400 on 5940.0 and later, 500 on older builds
Which .NET runtime do P21 business rules need? 14 § The middleware runtime — both .NET and .NET Framework, for now
Which middleware build am I on? 14 § Reading the middleware version — no version endpoint; it rides the session-create response
Error catalog by API 06 Error Handling (per-API sections)
Write refused for being too long / how long is a field? 06 § Field Length Limits — the API exposes no lengths; measured values + how to measure safely
Quick symptom → cause table 06 § Common Issues Quick Reference
Invalid column name: {field} — is the capability really missing? 06 § Common Transaction Errors — sometimes the sibling field does the job; check ValidValues
Invalid {field} value: 700 on an enum 06 § Common Transaction Errors — send the label, not the code_p21 integer
OData 404 saying Edm.Decimal / Edm.String 06 § Incompatible Operand Types — numeric key column, drop the quotes
Auth failures 06 § Authentication Errors
401 right after a token call that worked (Authorization header was not present) 06 § 401 Authorization header was not present — a 307 stripped the header; send the trailing-slash router URL
Intermittent interactive failures under load 07 Session Pool Troubleshooting
What changed in these docs recently 10 Changelog

Doc inventory (what each file is)

Doc Scope Size
00-Authentication Tokens (v2/consumer key), permissions, UI server URL large
01-API-Selection-Guide Which API for which job small — read whole
02-OData-API Read-only queries large
03-Transaction-API Stateless create/update + service reference + PDF reports very large — use anchors
04-Interactive-API Stateful window driving, popups, traps very large — use anchors
05-Entity-API REST CRUD on 4 entities medium
06-Error-Handling Errors across all APIs large
07-Session-Pool-Troubleshooting One deep-dive: session pool contamination medium — single topic
08-SalesPricePage-Codes SalesPricePage field codes/order medium — single service
09-Batch-Processing-Patterns Interactive bulk patterns + async client very large
10-Changelog Doc change history small
11-Inventory-REST-API /api/inventory/parts read/append/update large
12-Production-Labor-API Production services + end-to-end lifecycle large
13-UDT-Service-API User-defined table CRUD large
14-Breaking-Changes P21 version breaking-change registry (check before upgrading) small — read whole
15-Other-REST-Families Sixteen more REST families: UDF metadata, GL, CRM tasks/opportunities/consignment orders, PO headers, inventory (adjustments/movement/counts/scan/serial info), file storage, system info, customer form templates, service orders, exchange rates large
definitions/ Full-field service definition JSONs (every DataElement, field, key, label + payload template) load one file per service