# Priority Cloud (Priority ERP) — integration documentation

> Machine-readable rendition of Priority Cloud (Priority ERP) simulator documentation. The machine contract named in the overview below is the authority on request and response shapes; this page carries what a schema cannot say — what is deliberately unsupported, what the real product documents that this simulator does not implement, what each error code means, and the workflows.

API version: `OData v4`

A tenant-isolated simulation of Priority ERP's OData v4 REST surface, wire-verified against the official Priority sandbox. Served under https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo — the real product's /odata/Priority/{config-file}/{company} shape, where both segments are instance configuration. Discovery is OData-native: the service document lists every entity set, and $metadata is the machine-readable contract, with every property name and EDM type taken from the real instance's own document.

Every wire behaviour reproduces a measurement of the official sandbox, recorded with its evidence in the conformance ledger. Where the shared sandbox itself answers identical requests differently by backend version (eighteen such surfaces are known), this simulator commits to one coherent version and documents the choice. Where Priority could not be verified, the capability is absent and the ledger says why — nothing here is guessed.

## Terminology

| Term | Definition |
| --- | --- |
| {environmentKey} | A PLACEHOLDER, not a literal: SUBSTITUTE {environmentKey} in every URL below with your own environment's key — 'env_' followed by 32 hexadecimal characters — or nothing on this page runs. The concrete value is on the ERP simulator page in the app, under Connection configuration → Environment key; that in-app copy of this document renders every URL with your key already filled in, so copying from there is the shortest path. The key ROUTES the request and is not a credential: it is safe in a URL, and it is checked BEFORE authentication, so an unknown one answers a 404 problem document (application/problem+json, code SIM-1000) whatever credential accompanies it. SIM-1000 therefore always means a wrong key, never a wrong password — a real key with a bad password answers the empty 401 instead, and so does a valid credential sent to a DIFFERENT existing environment's key. |
| Entity set / form | Priority exposes its FORMS as OData entity sets; names are the internal form names (CUSTOMERS, AINVOICES, TINVOICES). |
| Subform | A child collection navigation, suffixed _SUBFORM (AINVOICEITEMS_SUBFORM = invoice lines). |
| IVNUM / DEBIT / IVTYPE | The composite key of financial documents. IVTYPE 'A' = sales invoice, 'T' = receipt. Drafts carry temporary T-prefixed IVNUMs; finalization assigns the book number (IN..., RC...). |
| FINAL / STATDES | FINAL 'Y' with STATDES 'Final' marks a finalized document; drafts have FINAL null and STATDES 'Draft'. Cancellation adds a REVERSING row (negative totals, STATDES 'Canceled') beside the surviving original. |
| TFNCITEMS (applications) | A receipt's application rows: each CREDIT is applied against the invoice named by FNCIREF1. No rows = an UNAPPLIED receipt; several rows = one receipt settling several invoices. |

## Base URLs

| Purpose | Template |
| --- | --- |
| OData service root | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo` |
| $metadata | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/$metadata` |
| Entity set | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS` |

## Authentication

### HTTP Basic authentication (REST)

Every request. There is no token endpoint — the real product authenticates each OData call with Basic credentials (an API user).

Required:

- API username
- API password (minted once in Settings → ERP; stored as a hash)

**Call any resource with -u**

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS?$top=1'
```

Success response:

```json
{"@odata.context":"...$metadata#CUSTOMERS","value":[{"CUSTNAME":"100001", "...": "..."}]}
```

Credentials do not expire; revoke them in Settings → ERP.

| Status | Meaning |
| --- | --- |
| 401 | Missing or wrong credential. The body is EMPTY and WWW-Authenticate: Basic is set (no realm) — measured; do not expect a JSON envelope. |

### Personal Access Token (PAT) (REST)

Automated server-to-server integrations (real product v19.1+). A PAT belongs to a Priority USER: requests authenticate AS that user (OWNERLOGIN on written rows, GetLoginName).

Required:

- A token minted in Settings → ERP (shown once; only a digest is stored)

**Send the token as the Basic USERNAME with the literal password PAT — every example in this document works unchanged with a PAT in place of API_USER:API_PASSWORD**

```bash
curl -u API_PAT:PAT 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/GetLoginName'
```

Success response:

```json
{"@odata.context":"...$metadata#Edm.String","value":"<the Priority user the token belongs to>"}
```

Tokens do not expire; revoke them in Settings → ERP. A revoked or unknown token answers the same empty 401.

| Status | Meaning |
| --- | --- |
| 401 | The same empty-body 401 as Basic, and it covers THREE indistinguishable cases: an unknown token, a revoked token, and a token that belongs to a DIFFERENT environment (credentials are per-environment — a valid token on the wrong environment key answers this too). The password must be the LITERAL string PAT; anything else is treated as an ordinary Basic credential. |

## First request

Substitute {environmentKey} before running anything (see Terminology); a 404 SIM-1000 means you have not. Discover the surface from the service document, then read a collection. Everything — including $metadata — requires Basic auth. SINGLE-QUOTE the URL in a shell: OData options start with $, and a double-quoted "?$top=5" is expanded by bash to "?=5", which the wire silently ignores — you get every row and no error. And PERCENT-ENCODE spaces: the parameter tables print filters like $filter=CUSTNAME eq '100001' with literal spaces for readability, but a URL cannot carry raw spaces (curl rejects it outright) — send %20 (quotes may stay literal or be %27).

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo'
```

Response:

```json
{"@odata.context":"https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/$metadata","value":[{"name":"ACCOUNTS_RECEIVABLE","kind":"EntitySet","url":"ACCOUNTS_RECEIVABLE"}, {"name":"AINVOICES","kind":"EntitySet","url":"AINVOICES"}, "..."]}
```

Page with $top and $skip against a stable $orderby. There is no server cursor and $count is silently ignored — walk until a page comes back short.

## Pulling data

**List**

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES?$top=10&$orderby=IVDATE%20desc'
```

**Single record**

```bash
curl -u API_USER:API_PASSWORD "https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='IN254000001',DEBIT='D',IVTYPE='A')"
```

**Filter**

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES?$filter=FINAL%20eq%20%27Y%27%20and%20TOTPRICE%20gt%20500'
```

**Page loop**

```bash
# $count is ignored: page until short
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS?$orderby=CUSTNAME&$top=50&$skip=0'
```

**Field projection**

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS?$select=CUSTNAME,CUSTDES,PAYCODE'
```

**Embedded children**

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES?$expand=TFNCITEMS_SUBFORM,TPAYMENT2_SUBFORM&$top=5'
```

Response envelope:

| Field | Description |
| --- | --- |
| @odata.context | The $metadata fragment describing the payload; narrows with $select (…#CUSTOMERS(CUSTNAME,CUSTDES)) with DUPLICATE entries deduped, echoes $select=* as (*), and echoes each expanded navigation with its nested projection — $expand=CUSTPERSONNEL_SUBFORM($select=NAME) yields …#CUSTOMERS(CUSTPERSONNEL_SUBFORM(NAME)), an unnarrowed expand CUSTPERSONNEL_SUBFORM() (all measured). |
| value | The row array on COLLECTION reads. Item reads put properties at the top level with a …/$entity context and no value wrapper. |

## Writing data

### Create a customer (draft numbering, server fills)

POST to the collection. With no CUSTNAME the form assigns a TEMPORARY number (T-...) and STATDES 'Potential'; with an explicit CUSTNAME the record lands 'Active'. The 201 carries the FULL entity — OWNERLOGIN (the caller), CREATEDDATE/STATUSDATE (today, date-only midnight Z) and the CUST auto-unique are server-filled — plus a Location header with quotes percent-encoded. Children may ride along as subform arrays and are echoed back (context #CUSTOMERS(CUSTPERSONNEL_SUBFORM())). Re-running this exact command answers the measured 409, because the key already exists.

```bash
# answers: 201 or 409
curl -u API_USER:API_PASSWORD -X POST -H 'Content-Type: application/json' -d '{"CUSTNAME":"DOCS-EXAMPLE-1","CUSTDES":"Docs example"}' 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS'
```

Response:

```json
{"@odata.context":"...$metadata#CUSTOMERS/$entity","CUSTNAME":"DOCS-EXAMPLE-1","CUSTDES":"Docs example","STATDES":"Active","OWNERLOGIN":"<caller>","CREATEDDATE":"<today>T00:00:00Z", "...": "..."}
```

- An EMPTY payload answers the measured missing-required refusal (InterfaceErrors, instance language: שורה 1- - חסר מס. לקוח).
- An unknown property answers 400 'The property 'X' does not exist on type ...'; a wrong JSON type answers the Cannot-convert envelope with a populated innererror.
- STATDES must be a status this instance carries ('Active', 'Potential') — anything else answers the measured value-not-in-table refusal.

### Update (PATCH) — and the read-back rule

PATCH a keyed item with the columns to change; the response is 200 with the full entity. WRITABLE columns apply (the field tables mark them); SERVER-OWNED columns — keys, computed amounts, INACTIVEFLAG, FINAL — are SILENTLY IGNORED while the response still answers 200 (measured). A 200 PATCH is therefore NOT proof a property changed: read back. There is a THIRD outcome the Read-only flag does not distinguish: a column the FORM validates against another table refuses the WHOLE write with an InterfaceErrors 400 instead of ignoring it. There are two, and they belong to DIFFERENT forms: on AINVOICES, REFERENCE is validated against a customer-orders table this book does not carry, so every value that reaches the lookup is refused — the two that do NOT reach it are the empty string and an explicit null, which both answer 200 and leave the column null (so clearing REFERENCE works while setting it cannot); on CUSTOMERS, STATDES is validated against the instance's status list, so a value outside it is refused the same way (REFERENCE is not a CUSTOMERS column at all — sending it there draws the ordinary 'property does not exist' 400). Read the flag as 'your value may not survive', never as 'your write will be accepted'.

```bash
# answers: 200
curl -u API_USER:API_PASSWORD -X PATCH -H 'Content-Type: application/json' -d '{"CUSTDES":"Docs example updated"}' "https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('DOCS-EXAMPLE-1')"
```

Response:

```json
{"@odata.context":"...$metadata#CUSTOMERS/$entity","CUSTNAME":"DOCS-EXAMPLE-1","CUSTDES":"Docs example updated", "...": "..."}
```

- PATCH of a missing key answers 400 'A record with the specified key was not found' (not 404 — measured).

### Create an invoice draft with lines

POST to AINVOICES with a CUSTNAME that EXISTS (an unknown customer answers the measured value-not-in-table refusal) and optionally AINVOICEITEMS_SUBFORM lines (PARTNAME required — this book publishes no parts catalog, so any PARTNAME is accepted as given; the REAL product validates it against its parts table). The draft gets a T-number, STATDES 'Draft', FINAL null, CDES echoing the customer description, and header totals = Σ lines. Each run of this example creates a NEW draft.

```bash
# answers: 201
curl -u API_USER:API_PASSWORD -X POST -H 'Content-Type: application/json' -d '{"CUSTNAME":"100001","AINVOICEITEMS_SUBFORM":[{"PARTNAME":"DOC-PART","TQUANT":2,"PRICE":10}]}' 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES'
```

Response:

```json
{"@odata.context":"...$metadata#AINVOICES(AINVOICEITEMS_SUBFORM())/$entity","IVNUM":"T123459...","STATDES":"Draft","FINAL":null,"TOTPRICE":20,"AINVOICEITEMS_SUBFORM":[{"KLINE":1,"PARTNAME":"DOC-PART","TQUANT":2,"QUANT":2,"QPRICE":20,"TOTPRICE":20, "...": "..."}]}
```

- Line ops on a draft you created: POST <draft-key>/AINVOICEITEMS_SUBFORM adds a line (201, Location ...AINVOICEITEMS_SUBFORM(<KLINE>)); PATCH .../AINVOICEITEMS_SUBFORM(<KLINE>) recomputes QUANT and the amount identity; DELETE .../AINVOICEITEMS_SUBFORM(<KLINE>) answers 204 — the ONE deleting write. Header totals follow every line change.
- PATCHing REFERENCE answers the measured refusal: the form validates it against customer orders, and this book has none.
- THE DRAFT->FINAL TRANSITION IS NOT SUPPORTED: PATCH FINAL is silently ignored, so no API call turns a draft into a finalized document. That is NOT the same as 'API writes cannot move money': an already-finalized document IS writable, as the real form is (it validates fields, not lifecycle), and because the AR balance derives from finalized documents such a write DOES move it. Deliberately unprobed on the shared sandbox — finalizing there would create irreversible book entries.

### Deletion is refused where the real form refuses it

DELETE of a customer or an invoice answers the measured InterfaceErrors refusal, and BOTH forms split the message by the row's state: a named customer is pointed at the customer-ledger deletion program and a temporary one at the temporary-customer program, while a DRAFT invoice is pointed at the temporary-invoice deletion program and a FINALIZED one is told it cannot be deleted at all and pointed at the CANCELLATION program instead. Four messages, all verbatim; do not match on one of them. Separately, a well-formed key with no row answers the ordinary OData 400 'A record with the specified key was not found' rather than any InterfaceErrors document, so a DELETE has two different 400 BODIES. DELETE of a customer CONTACT answers the bare 404 (measured). Invoice LINES delete (204).

```bash
# answers: 400
curl -u API_USER:API_PASSWORD -X DELETE "https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('DOCS-EXAMPLE-1')"
```

Response:

```json
{"?xml":{"@version":"1.0","@encoding":"utf-8","@standalone":"yes"},"FORM":{"@TYPE":"CUSTOMERS","InterfaceErrors":{"@XmlFormat":"0","text":"שורה 1- למחיקת הלקוח יש להשתמש בתכנית \"מחיקה מכרטסת לקוחות\" (התכנית מופעלת מתפריט \"כרטיסי חשבונות\")."}}}
```

### $batch (JSON format) executes

POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/$batch with the JSON body the portal documents (v19.1+): {"requests":[{id, method, url, headers, body}]}. An inner url is either service-root-relative (CUSTOMERS?$top=1, a leading slash is fine) or the FULL published service base plus a path — the base must match exactly, scheme included, so http:// against an https base is refused like any other foreign base. The bare service root IS addressable from inside a batch — a bare slash, the base itself, or the base with its trailing slash all answer the service document (an EMPTY url is not: it answers the missing-method-or-url refusal). Inner METHOD names are case-insensitive. An inner id is echoed with the JSON TYPE you sent (a numeric id comes back a number). Requests run IN ORDER against the same surface with the caller's identity, and the response is {"responses":[{id, status, headers, body}]} (measured shape). At most 100 operations; there is NO rollback (portal). Back-references ($1, $2) never resolve — not with a correct OData dependsOn either — and the refusal depends on where the reference is declared: a $N NOT listed in the item's dependsOn refuses the WHOLE batch with a top-level 400 'Request Id reference [N] in Uri [URL] is not found in effective depends-on-Ids [LIST] of the request.' (LIST is the literal null when there is no dependsOn, otherwise the ids comma-separated), so nothing executes; a $N that IS listed answers that item alone with a 424 'A request dependency failed: N — content-id reference could not be resolved (dependency has no Location mapping)', whose envelope carries only code and message. Scope that precisely: among the refusals the BATCH MACHINERY itself generates — the top-level $N 400, the base-address refusal, missing method or url, an unusable method, a nested $batch, the 100-operation cap — only the 424 is not the full code/message/target/details/innererror envelope — every refusal in that list carries it. It says nothing about what an inner request produces: an inner response carries whatever that resource would have answered directly, so a bare-404 family url still gives an EMPTY body and a rejected write still gives the InterfaceErrors XML-as-JSON. The missing-Content-Type refusal is plain text, and it is not an inner response at all. Only a LEADING $N path segment counts: a $1 inside a $filter value is ordinary text and the request runs.

```bash
# answers: 200
curl -u API_USER:API_PASSWORD -X POST -H 'Content-Type: application/json' -d '{"requests":[{"id":"1","method":"GET","url":"CUSTOMERS?$top=1&$select=CUSTNAME"}]}' 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/$batch'
```

Response:

```json
{"responses":[{"id":"1","status":200,"headers":{"content-type":"application/json; odata.metadata=minimal; odata.streaming=true","odata-version":"4.0"},"body":{"@odata.context":"...","value":[{"CUSTNAME":"100001"}]}}]}
```

- GET /$batch answers 400 '$batch requires POST method'; POST without a Content-Type answers a PLAIN-TEXT 400 body 'The batch request must have a "Content-Type" header.' (no envelope — measured); a MULTIPART body answers 400 'Error reading batch part: multipart: NextPart: EOF' (all measured verbatim).

## Conventions

| Topic | Detail |
| --- | --- |
| Property order | Responses emit properties in METADATA order regardless of $select order (measured). |
| Addressing a child row for a write | A SINGLE-KEY child is addressable by its bare key value — AINVOICEITEMS_SUBFORM(1) is KLINE 1. ADDRESSABLE is not WRITABLE: PATCH/DELETE work there only on a form that accepts writes at all, so invoice lines answer 200/204 (the one deleting write) while the children of TINVOICES and PAY answer the API-permission refusal to both verbs, exactly as their parents do. That refusal PRECEDES key resolution, so it arrives whatever key form you send. Their key shapes differ regardless: TPAYMENT2_SUBFORM and PAYITEMS_SUBFORM are single-key (KLINE), while TFNCITEMS_SUBFORM is COMPOSITE (FNCTRANS+KLINE), as its own attribute table shows. A COMPOSITE-KEY child (CUSTPERSONNEL_SUBFORM keyed NAME+FIRM, TFNCITEMS_SUBFORM keyed FNCTRANS+KLINE) is NOT addressable by a bare value in either key position: both answer 404 on the real wire, measured. Contacts are therefore addressed for a PATCH only by the COMPLETE named-pair key (order-insensitive): a PARTIAL key — one naming only NAME or only FIRM — is unaddressable and answers the bare 404 rather than picking a row, because FIRM is shared by every contact of a customer. A COMPLETE key that matches no row answers 400 'A record with the specified key was not found' instead — the two 404/400 answers separate 'that is not an address' from 'no such row'. Key values are matched as TEXT, so a single-key child accepts the bare, quoted or named form alike (KLINE 1, '1' and KLINE=1). And because FIRM carries a customer DESCRIPTION, it usually contains a SPACE: percent-encode it (%20) or curl rejects the URL before sending. DELETE of a contact answers the bare 404 in every key form: contacts are created, read and updated, never deleted. Two traps: a new line takes KLINE = max(existing)+1, so deleting a MIDDLE line leaves a permanent gap while deleting the HIGHEST line frees its number for the next insert (and emptying the invoice restarts at 1) — a stale KLINE can therefore address a different row; and an explicit KLINE in a POST body is IGNORED (the server assigns). FIRM carries the parent's CUSTDES, so RENAMING a customer silently rekeys its contacts — a key captured before the rename no longer resolves. |
| Write request and response details | Content-Type: a MISSING one is tolerated on entity writes (the body is still parsed — measured), a non-JSON one is refused with the verbatim MIME message, and $batch alone REQUIRES one. A JSON ARRAY body is refused verbatim on an ENTITY write: 'An unexpected 'StartArray' node was found when reading from the JSON reader. A 'StartObject' node was expected.' Every OTHER body that is not a JSON object — malformed JSON, a bare string, a literal null, trailing junk, or a zero-byte body — answers 'request body is empty' on an entity write and on $batch alike. The message names the SHAPE the parser could not use, not the byte count: read it as 'no usable object here'. Query options are ignored on WRITES generally — a POST carrying $select or duplicated $top values still creates, and returns the full entity — while the same duplicates answer a bare 404 on READS: the query-option rules are read rules. The Location header of a SUBFORM create is informational only: keyed subform items are not readable, so a GET of that exact URL answers the bare 404 (customer and invoice Locations do resolve). A create inside $batch answers its 201 in the batch body WITHOUT a Location header — recover a server-assigned key from the payload. |
| Write details an integrator hits | Line defaults, measured: an omitted TQUANT is 1 and an omitted PRICE is 0, and a NEGATIVE quantity is accepted (a negative draft is a legal shape here). A draft with NO lines — created empty or emptied by deleting them — reads totals of 0 with TOTQUANT null, and a create response OMITS the subform key entirely (index it defensively); an $expand of the same row answers an empty array. A duplicate property in a write body takes the LAST occurrence (standard JSON parsing) with no warning. A PATCH body of {} answers 200 and changes nothing, an explicit null CLEARS a column, and a ZERO-BYTE body answers 400 'request body is empty'. An empty string is stored and is DISTINCT from null ($filter=FAX eq '' matches it) on ordinary columns — with two carve-outs: an empty KEY is treated as absent (see Writing data), and a FORM-VALIDATED column stores null rather than '' (REFERENCE '' reads back null and is matched by REFERENCE eq null, not by REFERENCE eq ''), because the empty value short-circuits the lookup instead of passing through it. Writing PAYCODE does not derive PAYDES — set both if you need both. Subform reads come back ordered by key, not by insertion. A nested create is ATOMIC: if a child is rejected, no parent row is left behind. Only the PARENT's STATDES is validated against the instance's status list; a contact's STATDES is stored as given. An explicit IVNUM in an invoice POST is ignored (the server always assigns a draft number) — unlike CUSTNAME, which is honoured and answers 409 when taken. |
| Batch response and message details | An inner response's body carries whatever the inner request produced: a JSON object for an entity, a bare NUMBER for /$count, a STRING of XML for $metadata, and the empty STRING where the inner response had no body — type by inner content-type, not a fixed shape. The base-address refusal is 'A batch request url must address a resource under this environment's OData base.' — one message for every way of missing the base. It means the url does not address this environment's OData base at all: a foreign host or environment key, a different scheme, or a path whose leading .. segments climb above the base. The base is matched BYTE-exactly, so even a differently-cased host is foreign. The service ROOT itself IS addressable (the base with or without its trailing slash, or a bare slash), and a dot segment that stays inside the base resolves normally. Percent-encoded dot segments are not decoded into path segments INSIDE a batch, so they address nothing and answer a bare 404 — while on the OUTER url the hosting layer decodes and normalizes them before the API sees the path, so the same sequence resolves. Do not use dot segments to address anything. An inner request missing its url answers the missing-method-or-url message rather than the base refusal, and a body that is not an object answers whatever the inner resource would say about it — an ARRAY draws the entity-write StartArray envelope, a string 'request body is empty'. Duplicate inner ids are echoed as sent (they are not deduplicated, so correlate carefully). The message 'request body is empty' covers more than a zero-byte body: a batch body that parses but carries no requests array, and an inner request whose body is not a JSON object, answer it too. An InterfaceErrors row counter identifies the FORM row, not which child of your payload failed — it reads 'שורה 2-' for any child-level refusal. A percent-encoded OPTION NAME (%24top) is honoured, while a percent-encoded PATH segment (/%24count) is a bare 404 — the encoding rule differs by position. In a key predicate an apostrophe is escaped by DOUBLING it ('O''BRIEN'); a single one answers the bare 404. |
| What this surface does NOT offer | There is no optimistic concurrency: entities carry no ETag, If-Match and If-None-Match are ignored, and a PATCH is unconditional last-write-wins — build your own guard if concurrent editors matter. X-HTTP-Method-Override is ignored (a GET stays a GET). $top has no upper bound, so a huge value simply returns everything the result cap allows; only negative and non-integer values are refused. The @odata.context on a write is a DESCRIPTIVE fragment, not a URL: a decoded composite child key can contain spaces, so do not dereference it — use the Location header (for parents) or rebuild the address yourself. |
| The environment is not a fresh book | An environment starts from the seeded book described here, but everything anyone writes to it STAYS: the forms refuse API deletion for customers and invoices exactly as the real product does, so a shared or long-lived environment accumulates rows from every integrator who has used it. Do not assume a row count, and do not assume a name is free — create with an explicit key and treat 409 as 'someone got there first'. A write's OWNERLOGIN records who created THAT row, so rows you did not write carry someone else's identity. |
| Error precedence: authentication wins | The credential is checked BEFORE routing, before the $batch method check, and before any write-permission or body validation. An unknown path, a GET /$batch, or a POST to a permission-refused form all answer the empty 401 when the credential is missing or wrong — UNDER THE ODATA BASE you will not see a 404, a 400 or a write refusal until you are authenticated. The gate covers the whole /odata prefix, not merely the exact base: a wrong config-file or company segment (…/other.ini/demo, …/demo-typo) answers the empty 401 too, so a 401 there does NOT tell you your credential is good — fix the credential first, then the path, because until you authenticate both mistakes look identical. Only paths outside /odata — the tenant root, unknown non-OData paths — answer their bare 404 unauthenticated, carrying nothing to protect. (The real instance gates its own wrong-company paths the same way.) Fix auth first; every other diagnosis downstream of it is unreliable. One more ordering worth knowing: on a keyed write the KEY is resolved before the body is parsed, so a malformed body against a missing key answers 'A record with the specified key was not found' rather than a body complaint. |
| Published-document versioning | This document is generated from the deployed build, so during a deployment the docs URL can briefly serve the previous build's contract. If a documented behaviour and the wire disagree, re-fetch the document before treating the difference as a defect — and note the x-deployment-id response header, which changes when the build does — it is emitted on 2xx responses only, so capture it from a successful call. |
| Content negotiation is not honoured | The response media type is fixed by the ENDPOINT, never by your Accept header: Accept, OData-Version and Prefer are silently ignored (measured — Accept: application/xml on an entity set still answered JSON). Entity and collection reads are application/json (odata.metadata=minimal — the parameter phrasing varies by backend, a ledgered variance). Three endpoints are not JSON, and asking for JSON will not make them so: /$metadata and GetMetadataFor(entity='X') answer application/xml (EDMX), and /$count answers text/plain. One refusal is plain text too — a POST /$batch with no Content-Type header. |
| Sparse rows | Every declared property is emitted on every row, null where the record carries no value — exactly how real rows read. |
| Document lifecycle | Draft (T-number, FINAL null) → Final (book number, FINAL 'Y'). Cancellation adds a reversing row with negative totals beside the surviving original — the reversing row carries its OWN document number (IN254000012 reverses IN254000011), so never join a reversal to its original by IVNUM; the original keeps STATDES 'Final' while the reversal reads 'Canceled'. |
| Case sensitivity | Per the developer portal, requests are case sensitive: forms and fields are UPPERCASE and must be matched exactly. This simulator enforces that — a lowercase entity set answers the bare 404, a lowercase field the unknown-property 400. (The shared sandbox was observed to TOLERATE lowercase on some backend versions; the portal's documented contract is what a portable client must assume, and what we serve.) Query OPTION NAMES are the measured exception: $TOP=5, $ToP=5 and $top=5 are all honoured (six repeats each on the real wire, also $SELECT/$FILTER/$EXPAND/$ORDERBY) — option names are case-INsensitive, and so is the GRAMMAR inside an option value — the $orderby direction word (desc/DESC/Desc), the $filter comparison operators (eq/EQ/Eq), the and/or connectives, the null literal, and the T and Z designators in a $since timestamp. What stays case-SENSITIVE is the DATA: property names ($select=custname answers 'Could not find a property named custname'), entity-set names (/customers is a bare 404), and string literals you compare against. Basic-auth USERNAMES are case-sensitive (an uppercased username answers the empty 401 — measured on both wires). |
| Result limits in the real product | Real Priority caps collection results by the MAXFORMLINES system constant (MAXAPILINES, default 2,000, from v25.1) — measured: an uncapped CUSTOMERS pull on the official sandbox returned exactly 2,000 rows. This simulator's seeded book is far below any cap, so no cap is simulated; page with $top/$skip regardless, as you would against the real product. |
| /$count | GET <SET>/$count answers the matching-entity count as a PLAIN-TEXT number, and HONOURS $filter and $since (measured on the real wire: 856 unfiltered vs 133 filtered); $top/$skip do not apply. $orderby is meaningless to a count but is still VALIDATED — a malformed one is refused 400 exactly as on a collection read. The path must use a literal $ — a percent-encoded /%24count answers a bare 404. On the shared sandbox this endpoint is one of the ledgered backend-version coins (number on one version, a 500 cast-error envelope on the other); this simulator serves the number. |
| HEAD and OPTIONS | On entity-set-BACKED paths (collection, item, subform, and /$count) both answer a bare 404 (measured on the newer sandbox backend; the other draw answers 501 — a ledgered coin). The service root and $metadata answer them like GET — 200, measured six times each on the real wire. Function imports flip 404/200 by backend draw there (ledgered); this simulator answers them like GET. Do not preflight with any of them; issue the GET. |
| Methods and the write verbs | POST/PATCH/DELETE are REAL on the writable forms (CUSTOMERS, AINVOICES — see the writing-data section); on TINVOICES, PAY and ACCOUNTS_RECEIVABLE every write verb answers the measured API-permission refusal verbatim, before any body parsing. PUT is a measured oddity reproduced as-is: PUT of an EXISTING record answers a bare 404, PUT of a missing one 400 'A record with the specified key was not found' — do not use PUT. The service root, $metadata and function imports answer every REGISTERED method like GET (POST /$metadata returned the EDMX six times out of six on the real wire; POST on a function import is a 404/200 backend coin there — this simulator answers like GET). On form paths, registered unusual methods like PROPFIND never reach the real product — its hosting edge refuses them with plain 403/405 HTML pages (measured six times) — and this simulator answers them with its bare 404 rather than impersonating an edge. TRACE specifically is refused by HOSTING infrastructure on BOTH deployments (405, empty or HTML body) before any API code runs, and unregistered method names may draw an empty 501 from the runtime — even on the root. |
| Path tolerances | A trailing slash on a collection is tolerated (measured). A DUPLICATED honoured query option — $top, $skip, $filter, $select, $orderby, $expand or $since, in any letter case — answers a bare 404 (measured for $top five times, and for $filter/$select/$orderby on the same backend draw; the OTHER sandbox backend takes the last value instead, a ledgered variance, so never send duplicates). A repeat with an EMPTY value ($top=1&$top) does not count as a duplicate — the valued option is honoured (measured). $top=0 and $skip=0 are no-ops; negative or non-integer values are refused with the Invalid-value 400 (see the $top parameter row). Assorted benign tolerances (measured): a trailing comma in $select — but NOT in $orderby, where it is refused as an unnamed property — an EMPTY-valued option ($filter=), trailing slashes on /$count and on ITEM reads, %20 inside a key predicate, and a duplicated child NAME inside one $expand (deduped — the duplicate-option 404 is about repeated options, not values) are all accepted. An UNQUOTED key (CUSTOMERS(100001)) is in the bare-404 family, and so is a predicate naming an extra or duplicated key part. The NAMED form works on a single-key set too (CUSTOMERS(CUSTNAME='100001')), and composite keys are order-insensitive everywhere, not only on children. Function imports accept the empty-parens call form (GetLoginName() = GetLoginName). |
| Function imports | Five utility functions sit beside the entity sets in the service document, callable as plain GET paths, and $metadata declares them (Function elements with Edm.String returns plus FunctionImports, GetMetadataFor included with its entity parameter — the real document's shape). GetPriorityVersion, GetODataVersion and GetBinVersion answer { "@odata.context": "...$metadata#Edm.String", "value": "<string>" } — the values identify the instance, not a contract. GetTenantDetails answers BARE JSON with no @odata.context: { "tenantID": "<hex>", "hosting": true }. GetLoginName answers the #Edm.String shape carrying the authenticated API username. All require Basic auth like everything else. |
| Per-entity metadata | GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/GetMetadataFor(entity='CUSTOMERS') (v25.0+) returns EDMX scoped to the entity, exactly like the real product; %27-encoded quotes around the parameter are accepted too (measured). An unknown entity answers the real product's own 404 envelope verbatim: netprest return no data for X (the majority sandbox draw — one backend version answers a 500 'XML decode: EOF' envelope instead, a ledgered variance). Malformed forms (missing quotes, bare GetMetadataFor) answer the bare 404. |
| Nested $expand options | The separator inside $expand=CHILD(...) is ';', never ','. A comma runs the rest of the clause into the current option's value and is refused 400 with that option's own error — ($top=1,$select=NAME) answers 'Top option must be a non-negative integer, it is set to '1,$select=NAME' instead.'; ($select=NAME,$top=1) answers 'Found system token '$top' in select or expand clause 'NAME,$top=1'.' (both measured verbatim, six repeats). Nested $top must be a non-negative INTEGER: 0 means no limit (the full child set — measured), a positive value truncates, anything else is refused with the Top-option envelope — note the DIFFERENT envelope from top-level $top's Invalid-value message; both refuse. Nested $skip is honoured; a non-integer OR NEGATIVE nested $skip is refused with the symmetric envelope 'Skip option must be a non-negative integer, it is set to 'abc' instead.' (the strict draws of ledgered coins — one backend version leaks 'Invalid query options: strconv.Atoi: ...' for non-integers and ignores negatives). Nested $orderby and $filter are honoured against the child type. DUPLICATED nested options take the LAST value (measured six times — ($top=1;$top=2) truncates to 2), unlike top-level duplicates, which answer the bare 404. A nested $expand is refused 400 — the could-not-find envelope against the CHILD type for an unknown name, the not-a-navigation envelope for a plain child property (subforms publish no further navigations). An unknown property in a nested $select is refused 400 with the instance's own XML-generation message IN THE INSTANCE LANGUAGE (the reference instance is Hebrew-localized; emitted verbatim) — NOT the could-not-find envelope. Unknown nested $-options ($count=true) are silently ignored. One sandbox backend family phrases these refusals as 'Invalid query options: ...' instead (a ledgered variance); the option-specific messages above are the majority family, and what this simulator serves. |
| Item reads ignore list options | On an ITEM read (a keyed path), $select and $expand are honoured; $filter, $top and $skip are NOT EVEN PARSED — measured: an item read still answers the entity with a $filter that excludes it, with an unknown-property or function $filter that would 400/501 on a collection read, and with $top=-1 (three repeats each). $orderby IS still validated (a garbage direction answers its 400). So is every option NESTED inside $expand: a nested $filter naming an unknown child property, a nested typed mismatch, a nested $top=-1 or $skip=abc all answer 400 against the CHILD type, and a nested $filter FUNCTION answers 501 — on an item read exactly as on a collection. The rule is not 'item reads validate less', it is 'the TOP-LEVEL $filter/$top/$skip are not parsed on a keyed path'. Duplicated options answer the bare 404 everywhere. Do not rely on a filter to guard an item read. |
| Subform addressing | A subform is addressable as a path segment — CUSTOMERS('X')/CUSTPERSONNEL_SUBFORM — and supports the query options against the CHILD type, including /$count (a plain-text number honouring $filter; on the shared sandbox this is the same ledgered /$count coin, answering a 500 cast-error envelope on the other draw). A KEYED subform item — CUSTPERSONNEL_SUBFORM(NAME='x',FIRM=1) — answers a bare 404: a ledgered coin (two of six sandbox draws served the entity; the committed draw here does not — filter the subform collection instead). A PROPERTY path segment (CUSTOMERS('X')/CUSTNAME) answers a bare 404 (six consistent draws; a rare backend answered a 400 'Invalid OData path' envelope once — ledgered); project with $select instead. |
| Nulls in filters and sorts | $orderby places NULLS FIRST ascending and LAST descending, and an empty string sorts above null descending — page a sparse column with a tie-breaker if the boundary matters. In $filter, a comparison against a VALUE excludes rows where the property is null — eq/gt/ge/lt/le all skip them (comparing against the null LITERAL is different, and covered below). ne is the exception: a row whose property is NULL matches 'X ne value' (measured on the real wire — a filter on an all-null column returned every row for ne and none for eq). With the sparse-row rule (every property emitted, null where unpopulated), an ne filter can therefore return far more rows than its complement excludes. eq null and ne null work as expected. |
| $filter operand forms | The right operand may be ANOTHER PROPERTY — TOTPRICE eq DISPRICE compares the two row values (measured honoured; one sandbox backend draw matched nothing — ledgered). Both sides must be in the same type family, like literals. A NAVIGATION on either side is refused 400 'The operand for a binary operator 'Equal' is not a single value. Binary operators require both operands to be single values.' (measured; another backend draw silently ignores the filter — the refusal is committed). The 'not' operator is a TRAP: not (...) parses and silently matches NOTHING (measured three times — neither honoured nor refused); express negation with ne and De Morgan instead. The OData 'in' operator never reaches the real product — its hosting edge refuses the pattern with a 403 HTML page (measured); this simulator answers the grammar 400. A mismatched parenthesis answers 'Invalid query options: parse error. Mismatched parenthesis.' verbatim. |
| $batch executes (JSON format) | POST /$batch with the portal's JSON body (v19.1+) EXECUTES: inner requests run in order against this same surface with the caller's identity, and the response is {"responses":[{id,status,headers,body}]} — the measured shape. Inner urls may be absolute or service-root-relative; at most 100 operations (the portal's limit) — exceeding it refuses the WHOLE call with a top-level 400 'Batch commands are limited to 100 operations in one batch call.'; and the cap cannot be recursed around, because a NESTED $batch is refused per item. Refusals divide into two kinds, and the difference decides whether earlier writes survive. WHOLE-CALL (no responses array, nothing executes): anything wrong with the batch REQUEST ITSELF — a non-POST method, a missing or unusable Content-Type, a body that is not an object carrying requests, the 100-operation cap, and a $N back-reference not listed in its item's dependsOn. PER-ITEM (200 outer, siblings still answer): anything wrong with an individual inner request — an unusable method, a nested $batch, a foreign base, a missing method or url, and every refusal the addressed resource itself produces. An inner url must address THIS environment's OData base: a foreign host or environment key is refused per item rather than quietly answering with your data. There is NO rollback (portal): earlier operations persist when a later one fails, so a batch is not a transaction. The ONE case where earlier writes do not happen is a $N back-reference that is NOT listed in its item's dependsOn: that is detected before any item runs and refuses the whole call, so nothing executes. A $N that IS listed is refused per item (424) like any other failing item — the batch still runs, and earlier writes in it DO land. Failures are contained to their item — an unusable inner method fails only that request and its siblings still answer. Micro-contract: a request missing method or url answers 'Each batch request needs a method and a url.'; an inner method outside GET/POST/PATCH/PUT/DELETE/HEAD/OPTIONS answers a per-item 501 'Not implemented: METHOD PATH' — the method echoed as you sent it and the path WITHOUT its query string (the real instance coins between this and a bare 404; the informative draw is served here, and PROPFIND/TRACE/CONNECT are all in this family inside a batch, whatever they do on a direct request); a nested batch 'A batch request may not contain another $batch.'; a $N back-reference is refused as described under $batch above — whole-batch 400 when it is not in dependsOn, per-item 424 when it is; a missing id comes back as the KEY id with an empty-string value, not omitted; an empty requests array answers 200 with an empty responses array; an inner HEAD follows the same path split as a direct one — a bare 404 on entity-set-backed paths (collection, item, subform, /$count), and on the service root, $metadata and the function imports the FULL body its GET would produce, where a direct HEAD would have given you headers only. So a batched HEAD is never a header-only probe: it either fails or hands you the whole payload; a batch create's 201 carries NO Location header (read the server-assigned key from the payload); an inner response with no body carries body as the empty STRING; and an inner request's headers object is accepted but INERT — it cannot change the identity the batch already authenticated as, so do not try to switch credentials per item. A body on a GET or HEAD item is ignored rather than refused, so a client that serializes `body` unconditionally still reads normally. Assorted batch tolerances: a doubled slash, a trailing slash on /$batch, query options on the /$batch url itself, and a Content-Type carrying parameters (charset, odata.metadata) are all accepted; a duplicate requests key takes the last. A #fragment is NOT stripped — in path position it makes the url address nothing (bare 404), and it only survives inside a query value, where it lands in an ignored option. Whitespace in the PATH of an inner url is a bare 404 — leading whitespace, or trailing whitespace when the url has no query string. Trailing whitespace AFTER a query string is not: it lands inside the last option's VALUE, which the option parser tolerates, so the request runs normally (measured on the real instance too). The measured refusals stand verbatim: GET → '$batch requires POST method'; POST without a Content-Type → the PLAIN-TEXT body 'The batch request must have a "Content-Type" header.' (one backend draw serves the same text for GET — ledgered phrasing coin); a MULTIPART content type → 'Error reading batch part: multipart: NextPart: EOF' (this simulator never parses a multipart batch), and any OTHER non-JSON content type → the same MIME refusal an entity write answers. |
| Writing data — what a write may and may not do | POST creates DRAFTS with server-assigned temporary numbers (customers T-numbered when unnamed with STATDES 'Potential', 'Active' when named; invoices always T-numbered, STATDES 'Draft', FINAL null) — every write behaviour here was measured on the real wire, envelopes verbatim. Server fills OWNERLOGIN (the authenticated identity, PATs included), CREATEDDATE/STATUSDATE/IVDATE as date-only midnight Z, the CUST auto-unique, CDES from the customer, and the amount identity (plus TOTQUANT) from lines. PATCH applies WRITABLE columns only: server-owned columns (keys, computed amounts, INACTIVEFLAG, an invoice's FINAL/STATDES) are SILENTLY IGNORED while the response still answers 200 — read back to confirm, this is the real form engine's measured behaviour. Values are coerced to the COLUMN, not preserved as sent (measured): an Int column ROUNDS a fractional literal half toward +∞ (1.5 → 2, −1.5 → −1), while a Decimal column rounds to its declared SCALE half AWAY FROM ZERO (PRICE p13s2: 10.987654 → 10.99, 0.125 → 0.13, −0.125 → −0.13) — the two rules differ on negatives, so do not carry one across, and a string column TRUNCATES at MaxLength — counted in UTF-16 code units; when the cut would fall BETWEEN the halves of a surrogate pair the orphaned half is dropped too, so a truncated value is always well-formed text (and one unit shorter than the limit). KEY columns are the exception: a NON-EMPTY key is stored as given, so an over-long key is preserved and only the full value addresses the row. An EMPTY key is not stored at all — CUSTNAME '' is treated as ABSENT and takes the unnamed-create path, answering 201 with a server-assigned T-number and STATDES 'Potential' (measured on the real instance too). That is a trap worth guarding in your client: a serializer that emits '' for an unset field silently creates a temporary customer instead of drawing the missing-key refusal that an empty BODY draws. A quantity on the whole-unit 'ea' must be an integer (a fractional TQUANT answers the verbatim whole-value refusal). A Decimal's SCALE is enforced but its PRECISION is not, and an Int column is float-backed: values beyond 2^53 lose exactness and an extreme magnitude is stored as given and serializes in exponent form (1e+30) rather than being rounded — it is already past the column's precision. Keep amounts and identifiers inside their declared domains. Read back rather than assuming your value survived. A PATCH with an empty body answers 200 and changes nothing; an explicit null CLEARS a column. FINALIZED DOCUMENTS ARE NOT PROTECTED: an invoice with FINAL 'Y' accepts writable-column PATCHes and line writes exactly as the real form does (measured — the form validates fields, not lifecycle), and because the AR balance derives from finalized documents, such a write DOES move it. What is unsupported is the TRANSITION: no API call turns a draft into a finalized document (PATCH FINAL is ignored), so balances move only when you edit something already final. |
| Backend-version variance | Eighteen sandbox surfaces answer identical requests differently by backend version (filter functions, /$count incl. subform counts, GetLoginName shape and its non-GET methods, unknown-property filters, TYPED filter literals — the incompatible-types 400 vs silent coercion, a NAVIGATION in $filter — the not-single-value 400 vs silently ignored, property-vs-property comparisons — honoured vs matching nothing, partial-key reads, lowercase entity sets, HEAD/OPTIONS on entity sets, duplicated query options, keyed subform items, negative top-level $top/$skip and negative nested $skip, nested $top=-1, GetMetadataFor on an unknown entity, the non-integer nested-$skip message, property path segments, and refusal-message phrasing generally). This simulator commits to one coherent version; the conformance ledger records each choice and the evidence. |

## Limitations

- POST creates DRAFTS, and the draft->final TRANSITION is not supported (PATCH FINAL is silently ignored). An already-finalized document is still WRITABLE, though, and because the AR balance derives from finalized documents such a write moves the balance — do not treat the API as incapable of touching money. Deliberately unprobed — finalizing on the shared reference sandbox would create irreversible book entries.
- This book publishes no parts catalog: PARTNAME on invoice lines is accepted as given, where the real product validates it against its parts table (measured refusal ledgered).
- $batch back-references ($1, $2, ...) never resolve, and the refusal takes one of two shapes depending on the item's dependsOn — a whole-batch 400 that runs nothing, or a per-item 424. See the $batch section for the exact messages and which writes survive each.
- This simulator's hosting edge may refuse requests carrying certain default AUTOMATED User-Agent strings (for example Python-urllib) with a plain 403 before the API is reached. That is a hosting artifact, not Priority behaviour — the official sandbox serves such clients normally. Send an explicit User-Agent header from stdlib HTTP clients.
- A request whose environment key does not exist answers a vendor-neutral 404 problem document (application/problem+json, code SIM-1000) BEFORE any authentication — the key routes requests, it is not a credential. Everything under a VALID key behaves as this document describes, including the tenant root and unknown paths (bare 404).
- OAuth2 via the External ID module is not implemented (Basic and PAT are). The portal notes Basic is unavailable on real instances where External ID is enabled.
- Entity sets beyond the five above answer a bare 404 — the real instance publishes 1,739; this simulator publishes exactly what it serves.
- String functions in $filter answer 501 (see the variance note).
- The AR balance derivation is simulator-defined and documented; the real instance's could not be verified from the shared sandbox.

## Capability matrix

Every capability, with its support status. `not_supported` means exactly that — do not build against it.

| Capability | Protocol | Resource | Operations | Auth | Status | Notes |
| --- | --- | --- | --- | --- | --- | --- |
| Service document + $metadata (EDMX, real property names/types) | REST | `/, /$metadata` | GET | Basic | **supported** |  |
| Customers with contact subform | REST | `/CUSTOMERS (+CUSTPERSONNEL_SUBFORM)` | GET list, item, subform, $expand | Basic | **supported** |  |
| Sales invoices with lines | REST | `/AINVOICES (+AINVOICEITEMS_SUBFORM)` | GET list, item, subform, $expand | Basic | **supported** |  |
| Receipts with payment means and applications (partial/unapplied) | REST | `/TINVOICES (+TPAYMENT2_SUBFORM, TFNCITEMS_SUBFORM)` | GET list, item, subforms, $expand | Basic | **supported** |  |
| Payment terms | REST | `/PAY (+PAYITEMS_SUBFORM — empty in this single-payment book)` | GET list, item, subform, $expand | Basic | **supported** |  |
| AR balances (computed; derivation documented) | REST | `/ACCOUNTS_RECEIVABLE` | GET list, item | Basic | **supported** |  |
| Utility function imports | REST | `GetPriorityVersion, GetODataVersion, GetBinVersion, GetTenantDetails, GetLoginName` | GET | Basic | **supported** |  |
| Customer writes (drafts, contacts, nested create) | REST | `/CUSTOMERS (+CUSTPERSONNEL_SUBFORM)` | POST, PATCH; DELETE refused by the form (contacts: bare 404) | Basic / PAT | **supported** | Measured contract: a supplied CUSTNAME is honoured (Active) and an absent or empty one draws a T-number (Potential); server fills; InterfaceErrors refusals verbatim. |
| Invoice draft writes with lines | REST | `/AINVOICES (+AINVOICEITEMS_SUBFORM)` | POST (nested lines), PATCH, line POST/PATCH/DELETE(204); header/draft DELETE refused | Basic / PAT | **supported** | POST creates DRAFTS and no API call finalizes one (FINAL is silently ignored) — but an ALREADY-finalized invoice is writable, and such a write moves the AR balance. Totals recompute from lines. |
| Writes on receipts, terms, balances | REST | `/TINVOICES, /PAY, /ACCOUNTS_RECEIVABLE` | — | Basic / PAT | **not_supported** | The measured API-permission refusal, verbatim, on every write verb. |
| $batch (JSON format) | REST | `/$batch` | POST (≤100 inner requests, no rollback, no $N refs) | Basic / PAT | **supported** |  |
| Personal Access Tokens | REST | `every path (Basic: token as username, password 'PAT')` | — | PAT | **supported** |  |
| SOAP | SOAP | `—` | — | — | **not_supported** | Priority Cloud's integration surface is OData; there is no SOAP service to simulate. |

## REST resources

### `CUSTOMERS`

Customer master records (117 properties, the full real form). Payment terms appear as PAYCODE/PAYDES on the customer.

Base path: `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS` | supported | Collection read with the query options above. $count, $search, $format, unknown $-options and non-$ parameters are SILENTLY IGNORED (measured) — rows come back unaffected. This is Priority's behaviour, not an omission. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')` | supported | Item read: $entity context, properties at TOP LEVEL (no value wrapper). $select applies and so does $expand; LIST options on an item read ($filter, $top) are SILENTLY IGNORED — measured, an item read with a $filter that excludes the entity still returns it. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')/CUSTPERSONNEL_SUBFORM` | supported | The customer's contact persons. Key (NAME, FIRM) where FIRM carries the parent customer's DESCRIPTION (CUSTDES) — measured on the real wire, both on seeded rows and in a write's own Location header. Also reachable inline via $expand=CUSTPERSONNEL_SUBFORM. An inline child carries no envelope of its own and is the COMPLETE child set unless narrowed by nested options ($top/$skip/$orderby/$select/$filter). The path form supports the query options against the CHILD type, and ('<CUSTNAME>')/CUSTPERSONNEL_SUBFORM/$count answers the child count as a plain-text number honouring $filter. A KEYED subform item (CUSTPERSONNEL_SUBFORM(...)) is NOT addressable for READS — bare 404. WRITES do address child items here: POST ('<CUSTNAME>')/CUSTPERSONNEL_SUBFORM creates one, and PATCH ('<CUSTNAME>')/CUSTPERSONNEL_SUBFORM(<complete key>) updates it — DELETE answers the bare 404: this child is never deleted through the API. See the writing-data section for the payload contract. |
| POST | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS` | supported | Creates a record. A key you SUPPLY is honoured — the row lands under your CUSTNAME with STATDES 'Active', and a name already taken answers 409. Supply NO key (or an empty one, which counts as none) and the form assigns a temporary T-number with STATDES 'Potential'. The response is 201 with the FULL entity — server-filled values included — and a Location header with quotes percent-encoded. Children may ride in the same POST as subform arrays and are echoed back. See the writing-data section for the exact contract and refusals. |
| PATCH | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')` | supported | Applies WRITABLE columns and answers 200 with the full entity, while a FORM-VALIDATED column refuses the whole write with a 400 instead (which columns those are differs per form — see the writing-data section). Server-owned columns in the payload are SILENTLY IGNORED (measured — the response is still 200): read back to confirm. Unknown properties and wrong JSON types are refused. |
| DELETE | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')` | not_supported | The form refuses API deletion, with a DIFFERENT message per row state (named vs temporary customer; draft invoice vs finalized, where the message points at the CANCELLATION program because a final document cannot be deleted at all), and a well-formed key with no row answers the ordinary OData 400 'A record with the specified key was not found' instead of any InterfaceErrors document — the measured InterfaceErrors message, verbatim. Subform LINES are the exception where the writing-data section says so. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS

| Status | Meaning |
| --- | --- |
| 200 | OK — { "@odata.context": ..., "value": [...] } |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |

Request:

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS?$top=5'
```

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')

| Status | Meaning |
| --- | --- |
| 200 | OK — $entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | An unknown property in $select, a bad $orderby, or any invalid NESTED option inside $expand (validated against the CHILD type: unknown property, typed mismatch, bad $top/$skip). A TOP-LEVEL $filter/$top/$skip is not parsed here, so its invalid values answer 200 with the entity. |
| 404 | A DUPLICATED honoured query option, or a key form in the bare-404 family — EMPTY body, distinct from the envelope 404 below. |
| 501 | A $filter FUNCTION inside a NESTED $expand option — 'Function "X" is not supported'. A top-level $filter is not parsed on an item read, so a function THERE answers 200. |
| 404 | Well-formed key, no match: the ENVELOPE 404 'The specified entity was not found'. Missing key parts: bare 404, empty body. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')/CUSTPERSONNEL_SUBFORM

| Status | Meaning |
| --- | --- |
| 200 | OK — collection payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |
| 404 | The PARENT key does not resolve — envelope 404 |

##### POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS

| Status | Meaning |
| --- | --- |
| 201 | Created — full entity payload, Location header |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | Form validation refused: the InterfaceErrors document (instance language), or a property/type refusal in the OData envelope |
| 409 | A record with the specified key already exists |

##### PATCH https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')

| Status | Meaning |
| --- | --- |
| 200 | OK — full entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 404 | The address is in the bare-404 family (unquoted key, an extra key part, missing parts of a composite key) — bare 404, EMPTY body, before any body parsing. |
| 400 | Unknown property / type mismatch / form refusal, or 'A record with the specified key was not found' |

##### DELETE https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/CUSTOMERS('<CUSTNAME>')

| Status | Meaning |
| --- | --- |
| 400 | InterfaceErrors: use the form's deletion program |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 404 | The address is in the bare-404 family (unquoted key, an extra key part, missing parts of a composite key) — bare 404, EMPTY body, before any body parsing. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `$select` | Comma-separated property projection. Response properties keep METADATA order, not $select order, while the CONTEXT fragment echoes the order you sent (with duplicates deduped), and $select=* is honoured — the full property set with a (*) context (all measured). PLAIN properties only: naming a subform navigation in $select is refused 400 with the instance-language XML-generation message (measured) — embed subforms with $expand instead. | `$select=CUSTNAME` |
| `$filter` | eq, ne, gt, ge, lt, le with and/or and parentheses; string literals in single quotes, dates bare ISO-8601, null bare. LITERALS ARE TYPED: a numeric property takes a bare numeric literal, a string property a quoted one, a date property a bare ISO date — a family mismatch (COMMISSION gt '500', CUSTNAME eq 5) is refused 400 'A binary operator with incompatible types was detected. Found operand types ... for operator kind ...' (the strict draw of a measured backend variance; the other backend silently coerces or matches nothing — never rely on that). FUNCTIONS (contains, startswith, ...) answer 501 here — the shared sandbox answers them non-deterministically by backend version, so this simulator serves the one refusal an integrator can code against anywhere. An unknown PROPERTY is refused 400 naming it. | `$filter=CUSTNAME eq '100001'` |
| `$orderby` | Field asc\|desc, comma-separated for multi-key. The direction word must be asc or desc: anything else ($orderby=CUSTNAME sideways) is refused 400 on every measured draw — 'Syntax error at position N in '<option>'.' (the message phrasing varies by backend; the refusal does not). | `$orderby=CUSTNAME asc` |
| `$top` | Page size. The value must be a plain non-negative integer ('+' and surrounding spaces are tolerated — measured). 0 is a no-op (all rows). A NEGATIVE or NON-INTEGER value ($top=-1, $top=3.0, $top=abc) is refused 400 'Invalid value 'X' for $top query option found. The $top query option requires a non-negative integer value.' — the strict draw of a measured variance: one backend ignores negative integers, and non-integers are refused on every draw. Nested $top inside $expand has its own envelope — see the nested-options convention. | `$top=25` |
| `$skip` | Rows to skip; page with $top + $skip. The same value rules as $top: 0 is a no-op, negative or non-integer values are refused with the Invalid-value envelope. | `$skip=25` |
| `$since` | Priority-specific (v20.0+, developer portal): only records CHANGED at or after the given UTC instant — the portal recommends the Z suffix. Composes with $filter and the rest, including /$count. An UNPARSEABLE value is silently ignored (measured on the official sandbox). A WRITE is a change instant: on the WRITABLE forms a created row and an updated row both surface for a $since after the write, and a LINE write bumps its parent invoice — so $since polls for updates, not only for inserts. On the read-only forms (TINVOICES, PAY, ACCOUNTS_RECEIVABLE) nothing you send can create an instant; their rows carry the seed instant and ACCOUNTS_RECEIVABLE additionally surfaces when the customer behind it is created. Seeded rows carry the environment's seed instant, which is not exposed as a row property and is unrelated to document dates like IVDATE — use $since for change polling, not for date-range queries. | `$since=2026-01-01T00:00:00Z` |
| `$expand` | Embeds a subform inline, with nested options: $expand=CHILD($top=5;$select=A,B) — the nested separator is ';', NOT ',' (a comma is refused 400; see the nested-options convention). Works on COLLECTION and ITEM reads alike. The inline child is the COMPLETE child set UNLESS you narrow it with nested options — $top truncates, $skip skips, $orderby reorders, $select projects, and $filter excludes (all measured honoured on the real wire). An unknown child name is refused 400 naming it; expanding a PLAIN (non-navigation) property is refused 400 'is not a navigation property or complex property'. | `$expand=CUSTPERSONNEL_SUBFORM($top=5)` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CUSTNAME` | String(16) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTDESLONG` | String(80) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח מורחב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ECUSTDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לועזי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATDES` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OWNERLOGIN` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לטיפול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INACTIVEFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא פעיל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CREATEDDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך פתיחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATUSDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך עדכון סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PHONE` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר טלפון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FAX` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פקס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EMAIL` | String(68) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "דואר אלקטרוני". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BUSINESSTYPE` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תחום עיסוק". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MCUSTNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' לקוח מרכז". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MCUSTDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח מרכז". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPECODE` | String(2) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סוג לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPENAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סוג לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PCUSTNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חברת אם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPE2CODE` | String(2) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סווג נוסף ללקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PCUSTDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם חברת אם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPE2NAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סווג נוסף ללקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTPART` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מוצרים ללקוח בלבד?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NSFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שינוי שם?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד משלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור משלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ZONECODE` | String(2) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד איזור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ZONEDES` | String(10) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור איזור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TRACK` | String(2) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מסלול שרות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTNAMEPATNAME` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תבנית למס' לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ADDRESS` | String(80) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כתובת". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ADDRESS2` | String(80) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כתובת - שורה 2". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ADDRESS3` | String(80) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כתובת - שורה 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATE` | String(40) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עיר ומדינה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATEA` | String(40) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עיר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATECODE` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מדינה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATENAME` | String(40) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מדינה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ZIP` | String(10) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מיקוד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COUNTRYNAME` | String(18) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ארץ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAXNUM` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' חברה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAXNUMEXPL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הסבר על מספר התיק". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VATNUM` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר תיק במע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE2` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME2` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TERRITORYCODE` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד טריטוריה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TERRITORYDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם טריטוריה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMMISSION` | Decimal p6s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עמלת הסוכן(%)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ESTABLISHED` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שנת הקמה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EMPNUM` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר עובדים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור הסניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYCODE` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDES` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MAX_CREDIT` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תיקרת אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MAX_OBLIGO` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תיקרת אובליגו". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OBCODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRLINECODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד קו חלוקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRLINEDES` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור קו חלוקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `UNLOADTIME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "זמן פריקה בהפצה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRORDER` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סדר הפצה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NOTALLOWFORECAST` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קזז תחזית לק' בלבד?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RECYCLINGFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חייב במס מחזור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BONUSFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מקבל בונוס כללי ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMPETITORFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מתחרה ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FORECAST` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יעד מכירות/עסקאות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CHANEL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ערוץ מכירה ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRTYPECODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג חלוקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRTYPEDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סוג חלוקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SECONDLANGTEXT` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הדפסות באנגלית?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CONFIDENTIAL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לקוח חסוי?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `HOSTNAME` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "Web Site". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC1` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC1.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC2` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC2.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC3` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC3.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC4` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC4.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC5` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC5.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC6` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC6.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC7` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC7.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC8` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC8.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC9` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC9.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC10` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC10.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC11` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC11.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC12` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC12.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC13` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC13.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC14` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC14.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC15` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC15.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC16` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC16.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC17` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC17.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC18` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC18.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC19` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC19.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SPEC20` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "{CUSTSPEC_SPEC20.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXTFILEFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נספחים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WAVESTRATEGYCODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אופן פיצול משימות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WAVESTRATEGYDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור פיצול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PICKSTGCODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד אסטרטגיית ליקוט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PICKSTGDES` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור אסטרטגיה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AUTOSHPFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משלוח אריזות אוטו. ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EDOCUMENTS` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מקבל מסמך ממוחשב?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `GPSX` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קו רוחב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `GPSY` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קו אורך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QRANKCODE` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד דרגת איכות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QRANKDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור דרגת איכות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DCMONTHS` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חודשי DC מותרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע הלקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXDES` | String(56) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור מס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VATCOUNTRYNAME` | String(18) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ארץ רישום למע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTREMARK` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הערות לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PIKORDER` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סדר ליקוט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MINEXPDAYS` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מינימום ימי תוקף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RESERVFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לקוח לשריון מלאי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LANG` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד שפה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LANGNAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שפה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EORINUM` | String(17) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר EORI". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RETURNLABELS` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חיוב מדבקת החזרה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUST` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' לקוח (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
#### `CUSTPERSONNEL_SUBFORM` attributes

The customer's contact persons. Key (NAME, FIRM) where FIRM carries the parent customer's DESCRIPTION (CUSTDES) — measured on the real wire, both on seeded rows and in a write's own Location header.

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `NAME` | String(37) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ENAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לועזי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FIRSTNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם פרטי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LASTNAME` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם משפחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATDES` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INACTIVE` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא פעיל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OWNERLOGIN` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לטיפול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `GENDER` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מין". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PHONENUM` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "טלפון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CELLPHONE` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "טלפון נייד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `POSITIONDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הגדרת תפקיד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TITLEDES` | String(5) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תואר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OFFICEPHONE` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "טלפון במשרד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `HOMEPHONE` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "טלפון בבית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FAX` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פקס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EMAIL` | String(68) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "דואר אלקטרוני". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MAILAPP` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מאשר קבלת דיוור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `POSITIONCODE` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תפקיד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `POSITIONDES2` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור תפקיד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MAINPHONE` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר ראשי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DEALFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר לשווק". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CPROFFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר להצעה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ORDFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר להזמנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DOCFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר למשלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CIVFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר לחשבונית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TIVFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר לגיול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר להנח"ש". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SERVCALLFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר לשרות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CONSINGEEFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר לתיק יצוא". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NOTIFYFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר נוסף ליצוא". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `GWREGISTERED` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "רשום ב Pri Connect". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DEPARTMENT` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחלקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROFESSION` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מקצוע". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MANAGERNAME` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם מנהל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ASSISTANTNAME` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם עוזר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ASSISTANTPHONE` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "טלפון עוזר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BIRTHDATE10` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך לידה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אתר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODEDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור האתר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXTFILENAME` | String(66) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תמונה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LANG` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד שפה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LANGNAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שפה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PRIVSBYCONTACTONLY` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הרשאות לאיש קשר בלבד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PHONE` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FIRM` | String(48) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חברה". Emitted as declared in the instance $metadata; null when the row carries no value. |

### `AINVOICES`

Sales invoices (IVTYPE 'A'). LINE arithmetic (measured): QPRICE is the line total AFTER discount (TQUANT × PRICE × (1 − PERCENT/100)), DISPRICE is the PER-UNIT price after discount — a rate, not a total — and TOTPRICE equals QPRICE. A line DOES publish tax columns (IVTAX, VATFLAG, VPRICE) and they are writable and echoed back, but none of them enters any total in this book — the +VAT form of the identity is the HEADER's, where VAT is the column that participates. HEADER arithmetic: QPRICE = Σ line QPRICE, DISPRICE = QPRICE − DISCOUNT (the header-level discount, absent in this book), TOTPRICE = DISPRICE + VAT, TOTQUANT = Σ TQUANT. Do not sum the lines' DISPRICE — it is a unit rate. Header-level rate columns (PERCENT, TAXSUM) and the line's TOTPERCENT are RECORDED and echoed but never enter any total: this book applies no header-level discount (DISCOUNT is 0), and a write behaves identically on POST and PATCH about that.

Base path: `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES` | supported | Collection read with the query options above. $count, $search, $format, unknown $-options and non-$ parameters are SILENTLY IGNORED (measured) — rows come back unaffected. This is Priority's behaviour, not an omission. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')` | supported | Item read: $entity context, properties at TOP LEVEL (no value wrapper). $select applies and so does $expand; LIST options on an item read ($filter, $top) are SILENTLY IGNORED — measured, an item read with a $filter that excludes the entity still returns it. Composite keys are order-insensitive; a read missing key parts answers a bare 404 (this simulator serves the strict draw of a measured backend-version variance — see limitations). |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/AINVOICEITEMS_SUBFORM` | supported | Invoice lines: part, quantities, prices; line TOTPRICE sums to the header. Also reachable inline via $expand=AINVOICEITEMS_SUBFORM. An inline child carries no envelope of its own and is the COMPLETE child set unless narrowed by nested options ($top/$skip/$orderby/$select/$filter). The path form supports the query options against the CHILD type, and (IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/AINVOICEITEMS_SUBFORM/$count answers the child count as a plain-text number honouring $filter. A KEYED subform item (AINVOICEITEMS_SUBFORM(...)) is NOT addressable for READS — bare 404. WRITES do address child items here: POST (IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/AINVOICEITEMS_SUBFORM creates one, and PATCH (IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/AINVOICEITEMS_SUBFORM(<complete key>) updates it, and DELETE removes it (204). See the writing-data section for the payload contract. |
| POST | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES` | supported | Creates a DRAFT. Any key you supply is IGNORED — the server always assigns a temporary number (T-...). The response is 201 with the FULL entity — server-filled values included — and a Location header with quotes percent-encoded. Children may ride in the same POST as subform arrays and are echoed back. See the writing-data section for the exact contract and refusals. |
| PATCH | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')` | supported | Applies WRITABLE columns and answers 200 with the full entity, while a FORM-VALIDATED column refuses the whole write with a 400 instead (which columns those are differs per form — see the writing-data section). Server-owned columns in the payload are SILENTLY IGNORED (measured — the response is still 200): read back to confirm. Unknown properties and wrong JSON types are refused. |
| DELETE | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')` | not_supported | The form refuses API deletion, with a DIFFERENT message per row state (named vs temporary customer; draft invoice vs finalized, where the message points at the CANCELLATION program because a final document cannot be deleted at all), and a well-formed key with no row answers the ordinary OData 400 'A record with the specified key was not found' instead of any InterfaceErrors document — the measured InterfaceErrors message, verbatim. Subform LINES are the exception where the writing-data section says so. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES

| Status | Meaning |
| --- | --- |
| 200 | OK — { "@odata.context": ..., "value": [...] } |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |

Request:

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES?$top=5'
```

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')

| Status | Meaning |
| --- | --- |
| 200 | OK — $entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | An unknown property in $select, a bad $orderby, or any invalid NESTED option inside $expand (validated against the CHILD type: unknown property, typed mismatch, bad $top/$skip). A TOP-LEVEL $filter/$top/$skip is not parsed here, so its invalid values answer 200 with the entity. |
| 404 | A DUPLICATED honoured query option, or a key form in the bare-404 family — EMPTY body, distinct from the envelope 404 below. |
| 501 | A $filter FUNCTION inside a NESTED $expand option — 'Function "X" is not supported'. A top-level $filter is not parsed on an item read, so a function THERE answers 200. |
| 404 | Well-formed key, no match: the ENVELOPE 404 'The specified entity was not found'. Missing key parts: bare 404, empty body. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/AINVOICEITEMS_SUBFORM

| Status | Meaning |
| --- | --- |
| 200 | OK — collection payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |
| 404 | The PARENT key does not resolve — envelope 404 |

##### POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES

| Status | Meaning |
| --- | --- |
| 201 | Created — full entity payload, Location header |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | Form validation refused: the InterfaceErrors document (instance language), or a property/type refusal in the OData envelope |

##### PATCH https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')

| Status | Meaning |
| --- | --- |
| 200 | OK — full entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 404 | The address is in the bare-404 family (unquoted key, an extra key part, missing parts of a composite key) — bare 404, EMPTY body, before any body parsing. |
| 400 | Unknown property / type mismatch / form refusal, or 'A record with the specified key was not found' |

##### DELETE https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/AINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')

| Status | Meaning |
| --- | --- |
| 400 | InterfaceErrors: use the form's deletion program |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 404 | The address is in the bare-404 family (unquoted key, an extra key part, missing parts of a composite key) — bare 404, EMPTY body, before any body parsing. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `$select` | Comma-separated property projection. Response properties keep METADATA order, not $select order, while the CONTEXT fragment echoes the order you sent (with duplicates deduped), and $select=* is honoured — the full property set with a (*) context (all measured). PLAIN properties only: naming a subform navigation in $select is refused 400 with the instance-language XML-generation message (measured) — embed subforms with $expand instead. | `$select=IVNUM` |
| `$filter` | eq, ne, gt, ge, lt, le with and/or and parentheses; string literals in single quotes, dates bare ISO-8601, null bare. LITERALS ARE TYPED: a numeric property takes a bare numeric literal, a string property a quoted one, a date property a bare ISO date — a family mismatch (PERCENT gt '500', CUSTNAME eq 5) is refused 400 'A binary operator with incompatible types was detected. Found operand types ... for operator kind ...' (the strict draw of a measured backend variance; the other backend silently coerces or matches nothing — never rely on that). FUNCTIONS (contains, startswith, ...) answer 501 here — the shared sandbox answers them non-deterministically by backend version, so this simulator serves the one refusal an integrator can code against anywhere. An unknown PROPERTY is refused 400 naming it. | `$filter=FINAL eq 'Y' and TOTPRICE gt 500` |
| `$orderby` | Field asc\|desc, comma-separated for multi-key. The direction word must be asc or desc: anything else ($orderby=CUSTNAME sideways) is refused 400 on every measured draw — 'Syntax error at position N in '<option>'.' (the message phrasing varies by backend; the refusal does not). | `$orderby=IVDATE desc` |
| `$top` | Page size. The value must be a plain non-negative integer ('+' and surrounding spaces are tolerated — measured). 0 is a no-op (all rows). A NEGATIVE or NON-INTEGER value ($top=-1, $top=3.0, $top=abc) is refused 400 'Invalid value 'X' for $top query option found. The $top query option requires a non-negative integer value.' — the strict draw of a measured variance: one backend ignores negative integers, and non-integers are refused on every draw. Nested $top inside $expand has its own envelope — see the nested-options convention. | `$top=25` |
| `$skip` | Rows to skip; page with $top + $skip. The same value rules as $top: 0 is a no-op, negative or non-integer values are refused with the Invalid-value envelope. | `$skip=25` |
| `$since` | Priority-specific (v20.0+, developer portal): only records CHANGED at or after the given UTC instant — the portal recommends the Z suffix. Composes with $filter and the rest, including /$count. An UNPARSEABLE value is silently ignored (measured on the official sandbox). A WRITE is a change instant: on the WRITABLE forms a created row and an updated row both surface for a $since after the write, and a LINE write bumps its parent invoice — so $since polls for updates, not only for inserts. On the read-only forms (TINVOICES, PAY, ACCOUNTS_RECEIVABLE) nothing you send can create an instant; their rows carry the seed instant and ACCOUNTS_RECEIVABLE additionally surfaces when the customer behind it is created. Seeded rows carry the environment's seed instant, which is not exposed as a row property and is unrelated to document dates like IVDATE — use $since for change polling, not for date-range queries. | `$since=2026-01-01T00:00:00Z` |
| `$expand` | Embeds a subform inline, with nested options: $expand=CHILD($top=5;$select=A,B) — the nested separator is ';', NOT ',' (a comma is refused 400; see the nested-options convention). Works on COLLECTION and ITEM reads alike. The inline child is the COMPLETE child set UNLESS you narrow it with nested options — $top truncates, $skip skips, $orderby reorders, $select projects, and $filter excludes (all measured honoured on the real wire). An unknown child name is refused 400 naming it; expanding a PLAIN (non-navigation) property is refused 400 'is not a navigation property or complex property'. | `$expand=AINVOICEITEMS_SUBFORM` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CUSTNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NAME` | String(37) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVDATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVNUM` | String(16) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FINAL` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סופית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATDES` | String(12) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OWNERLOGIN` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לטיפול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ORDNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הזמנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `REFERENCE` | String(25) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הז. רכש (לקוח)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ADJPRICEFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לשערך מחירים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BOOKNUM` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית פנקס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROJDOCNO` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרויקט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROJDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור פרויקט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PRINTEDBOOL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הודפסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PLNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מחירון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PERCENT` | Decimal p8s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קביעת הנחה כללית %". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום לפני הנחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISCOUNT` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הנחה כללית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחיר אחרי הנחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VAT` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXSUM` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סה"כ לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAX` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ניכוי מס במקור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AFTERWTAX` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום אחרי ניכוי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVREFA` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר תיק במע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETAILS` | String(24) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE2` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME2` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אתר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODEDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור האתר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WARHSNAME` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחסן שולח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LOCNAME` | String(14) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איתור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WARHSDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור מחסן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOWARHSNAME` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחסן שריון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOLOCNAME` | String(14) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איתור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOWARHSDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור מחסן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TERRITORYCODE` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד טריטוריה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TERRITORYDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם טריטוריה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד משלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור משלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SHIPPERNAME` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חברת הובלה/תע/ספ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SHIPPERDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם ח. הובלה/תע/ספ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LORRYNUM` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' משאית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISTRDATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך הפצה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BOXNUM` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משטח שילוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BILLINGUSERLOGIN` | String(20) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אחראי גביה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCNUM` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. תנועת היומן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PACKCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סוג אריזה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PACKNAME` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סוג אריזה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MWEIGHT` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משקל ברוטו ידני". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WEIGHT` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משקל ברוטו מחושב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WEIGHTDIFF` | Decimal p10s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הפרש". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NWEIGHT` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משקל נטו מחושב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VOLUME` | Decimal p16s4 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נפח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VUNITNAME` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יח'". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AIRWAYBILL` | String(40) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר חבילה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BLACKLISTFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "Black List ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVRECONDATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך התאמת החשבונית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STORNOFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מבוטל ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXTFILEFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נספחים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INTERNAL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית פנימית ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTQUANT` | Decimal p16s3 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כמות פריטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PL` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית PL". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PACKNUM` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר חבילות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVCODENAME` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סווג נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVCODEDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סווג נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CPROFNUM` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הצעת מחיר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INCPARTEXT` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "להדפיס נספחי מוצרים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BONUSFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא לחשב בונוסים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CALCVATFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חושב מס AVALARA". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SDINUMIT` | String(36) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מזהה רשויות המס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MODELNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סל מוצרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QUANT` | Decimal p17s3 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כמות של סל המוצרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NOTINCLUDEREVREC` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא כלול בהכרה בהכנסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SCHEMEID` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מזהה ב- Peppol". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IDKEY` | String(40) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר מזהה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IV` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DEBIT` | String(1) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חיוב/זכוי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVTYPE` | String(1) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג". Emitted as declared in the instance $metadata; null when the row carries no value. |
#### `AINVOICEITEMS_SUBFORM` attributes

Invoice lines: part, quantities, prices; line TOTPRICE sums to the header.

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `PARTNAME` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מק"ט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PDES` | String(59) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור מוצר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CQUANT` | Decimal p17s3 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה למשלוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PQUANT` | Decimal p17s3 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה במחסן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SETFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אישור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TQUANT` | Decimal p17s3 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כמות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TUNITNAME` | String(3) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יח'". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QUANT` | Decimal p17s3 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כמות מפעל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `UNITNAME` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יח' מפעל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PRICE` | Decimal p13s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחיר ליחידה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VPRICE` | Decimal p13s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחיר ליח' כולל מע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ICODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע שורה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PRSOURCENAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מקור מחיר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PERCENT` | Decimal p6s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הנחה לשורה(%)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחיר ליח' אחרי הנחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סה"כ מחיר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סה"כ כולל מע"מ". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע חשבונית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ORDNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הזמנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OLINE` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PALLETNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "משטח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DATECODE` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תאריך (DC)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTPERCENT` | Decimal p8s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הנחה כללית (%)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VATFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מע"מ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTPARTNAME` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מק"ט לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTPARTBARCODE` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ברקוד לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `REVNAME` | String(10) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מהדורת מוצר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WARHSNAME` | String(4) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מחסן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LOCNAME` | String(14) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איתור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SERIALNAME` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פק"ע/מנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXPIRYDATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת.תפוגה של המנה/פק"ע". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOPALLETNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "למשטח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BARCODE` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ברקוד". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NUMPACK` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. אריזות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PACKCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סוג אריזה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PNUMPACK` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה - אריזות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CARTONNUM` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' קרטון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BUDCODE` | String(30) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סעיף תקציבי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME2` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 2". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME3` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME4` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 4". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME5` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 5". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון הכנסות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCDES` | String(48) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMMISSION` | Decimal p6s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עמלת סוכן (%)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE2` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMMISSION2` | Decimal p6s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עמלת סוכן נוסף (%)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXCH` | Decimal p13s6 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שער חליפין". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PURTAXPERCENT` | Decimal p7s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס קניה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PDACCNAME` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון יעד להכנסות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCICODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מיון שורת פ"י". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCIDES` | String(12) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור מיון שורת פ"י". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TRANSREFERENCE` | String(16) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אסמכתת שורה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXCODE` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד ניכוי מס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXCODE3` | String(8) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד ניכוי מס 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MPARTNAME` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פריט מרכז". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MPARTDES` | String(59) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור פריט מרכז". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MMPARTNAME` | String(22) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מק"ט לפי פריט מרכז". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BONUSFLAG` | String(1) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורת בונוס ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BONUSLINE` | Int64 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "בונוס קשור לשורה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVTAX` | Decimal p16s2 |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סך מע"מ ממקור חיצוני". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RRMETHODNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עקרון הכרה בהכנסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RRMETHODDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עקרון ההכרה - תיאור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RRTIMINGNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תזמון הכרה בהכנסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RRTIMINGDES` | String(32) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תזמון ההכרה - תיאור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FROMDATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מתאריך הכנסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TODATE` | DateTimeOffset |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עד תאריך הכנסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MODELNAME` | String(6) |  |  | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סל מוצרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `KLINE` | Int64 |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורה (מפתח)". Emitted as declared in the instance $metadata; null when the row carries no value. |

#### Limitations

- The seeded book uses VAT 0 throughout, matching the observed US-localized instance.

### `TINVOICES`

Receipts (IVTYPE 'T', RC-prefixed book numbers). TPAYMENT2_SUBFORM carries the payment means; TFNCITEMS_SUBFORM the applications — CREDIT per invoice (FNCIREF1). A finalized receipt with no applications is UNAPPLIED cash; Σ CREDIT never exceeds TOTPRICE.

Base path: `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES` | supported | Collection read with the query options above. $count, $search, $format, unknown $-options and non-$ parameters are SILENTLY IGNORED (measured) — rows come back unaffected. This is Priority's behaviour, not an omission. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')` | supported | Item read: $entity context, properties at TOP LEVEL (no value wrapper). $select applies and so does $expand; LIST options on an item read ($filter, $top) are SILENTLY IGNORED — measured, an item read with a $filter that excludes the entity still returns it. Composite keys are order-insensitive; a read missing key parts answers a bare 404 (this simulator serves the strict draw of a measured backend-version variance — see limitations). |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TPAYMENT2_SUBFORM` | supported | Payment means lines (check, transfer, card): PAYMENTCODE/PAYMENTNAME/QPRICE. Also reachable inline via $expand=TPAYMENT2_SUBFORM. An inline child carries no envelope of its own and is the COMPLETE child set unless narrowed by nested options ($top/$skip/$orderby/$select/$filter). The path form supports the query options against the CHILD type, and (IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TPAYMENT2_SUBFORM/$count answers the child count as a plain-text number honouring $filter. A KEYED subform item (TPAYMENT2_SUBFORM(...)) is NOT addressable for READS — bare 404. This form accepts NO writes at all — every write verb on the parent or this child answers the API-permission refusal. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TFNCITEMS_SUBFORM` | supported | Applications: CREDIT applied to the invoice named by FNCIREF1. A cancellation reverses with negative CREDIT. Also reachable inline via $expand=TFNCITEMS_SUBFORM. An inline child carries no envelope of its own and is the COMPLETE child set unless narrowed by nested options ($top/$skip/$orderby/$select/$filter). The path form supports the query options against the CHILD type, and (IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TFNCITEMS_SUBFORM/$count answers the child count as a plain-text number honouring $filter. A KEYED subform item (TFNCITEMS_SUBFORM(...)) is NOT addressable for READS — bare 404. This form accepts NO writes at all — every write verb on the parent or this child answers the API-permission refusal. |
| POST | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES` | not_supported | Every write verb on this form answers the measured API-permission refusal, verbatim (the reference instance refuses API operation of this form): POST, PATCH, PUT and DELETE alike, before any body parsing. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES

| Status | Meaning |
| --- | --- |
| 200 | OK — { "@odata.context": ..., "value": [...] } |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |

Request:

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES?$top=5'
```

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')

| Status | Meaning |
| --- | --- |
| 200 | OK — $entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | An unknown property in $select, a bad $orderby, or any invalid NESTED option inside $expand (validated against the CHILD type: unknown property, typed mismatch, bad $top/$skip). A TOP-LEVEL $filter/$top/$skip is not parsed here, so its invalid values answer 200 with the entity. |
| 404 | A DUPLICATED honoured query option, or a key form in the bare-404 family — EMPTY body, distinct from the envelope 404 below. |
| 501 | A $filter FUNCTION inside a NESTED $expand option — 'Function "X" is not supported'. A top-level $filter is not parsed on an item read, so a function THERE answers 200. |
| 404 | Well-formed key, no match: the ENVELOPE 404 'The specified entity was not found'. Missing key parts: bare 404, empty body. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TPAYMENT2_SUBFORM

| Status | Meaning |
| --- | --- |
| 200 | OK — collection payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |
| 404 | The PARENT key does not resolve — envelope 404 |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES(IVNUM='<IVNUM>',DEBIT='<DEBIT>',IVTYPE='<IVTYPE>')/TFNCITEMS_SUBFORM

| Status | Meaning |
| --- | --- |
| 200 | OK — collection payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |
| 404 | The PARENT key does not resolve — envelope 404 |

##### POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/TINVOICES

| Status | Meaning |
| --- | --- |
| 400 | לא ניתן להפעיל API למסך זה כיוון שהרשאותיך למסך זה אינן מספיקות. |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `$select` | Comma-separated property projection. Response properties keep METADATA order, not $select order, while the CONTEXT fragment echoes the order you sent (with duplicates deduped), and $select=* is honoured — the full property set with a (*) context (all measured). PLAIN properties only: naming a subform navigation in $select is refused 400 with the instance-language XML-generation message (measured) — embed subforms with $expand instead. | `$select=IVNUM` |
| `$filter` | eq, ne, gt, ge, lt, le with and/or and parentheses; string literals in single quotes, dates bare ISO-8601, null bare. LITERALS ARE TYPED: a numeric property takes a bare numeric literal, a string property a quoted one, a date property a bare ISO date — a family mismatch (QPRICE gt '500', ACCNAME eq 5) is refused 400 'A binary operator with incompatible types was detected. Found operand types ... for operator kind ...' (the strict draw of a measured backend variance; the other backend silently coerces or matches nothing — never rely on that). FUNCTIONS (contains, startswith, ...) answer 501 here — the shared sandbox answers them non-deterministically by backend version, so this simulator serves the one refusal an integrator can code against anywhere. An unknown PROPERTY is refused 400 naming it. | `$filter=FINAL eq 'Y'` |
| `$orderby` | Field asc\|desc, comma-separated for multi-key. The direction word must be asc or desc: anything else ($orderby=ACCNAME sideways) is refused 400 on every measured draw — 'Syntax error at position N in '<option>'.' (the message phrasing varies by backend; the refusal does not). | `$orderby=IVDATE desc` |
| `$top` | Page size. The value must be a plain non-negative integer ('+' and surrounding spaces are tolerated — measured). 0 is a no-op (all rows). A NEGATIVE or NON-INTEGER value ($top=-1, $top=3.0, $top=abc) is refused 400 'Invalid value 'X' for $top query option found. The $top query option requires a non-negative integer value.' — the strict draw of a measured variance: one backend ignores negative integers, and non-integers are refused on every draw. Nested $top inside $expand has its own envelope — see the nested-options convention. | `$top=25` |
| `$skip` | Rows to skip; page with $top + $skip. The same value rules as $top: 0 is a no-op, negative or non-integer values are refused with the Invalid-value envelope. | `$skip=25` |
| `$since` | Priority-specific (v20.0+, developer portal): only records CHANGED at or after the given UTC instant — the portal recommends the Z suffix. Composes with $filter and the rest, including /$count. An UNPARSEABLE value is silently ignored (measured on the official sandbox). A WRITE is a change instant: on the WRITABLE forms a created row and an updated row both surface for a $since after the write, and a LINE write bumps its parent invoice — so $since polls for updates, not only for inserts. On the read-only forms (TINVOICES, PAY, ACCOUNTS_RECEIVABLE) nothing you send can create an instant; their rows carry the seed instant and ACCOUNTS_RECEIVABLE additionally surfaces when the customer behind it is created. Seeded rows carry the environment's seed instant, which is not exposed as a row property and is unrelated to document dates like IVDATE — use $since for change polling, not for date-range queries. | `$since=2026-01-01T00:00:00Z` |
| `$expand` | Embeds a subform inline, with nested options: $expand=CHILD($top=5;$select=A,B) — the nested separator is ';', NOT ',' (a comma is refused 400; see the nested-options convention). Works on COLLECTION and ITEM reads alike. The inline child is the COMPLETE child set UNLESS you narrow it with nested options — $top truncates, $skip skips, $orderby reorders, $select projects, and $filter excludes (all measured honoured on the real wire). An unknown child name is refused 400 naming it; expanding a PLAIN (non-navigation) property is refused 400 'is not a navigation property or complex property'. | `$expand=TFNCITEMS_SUBFORM,TPAYMENT2_SUBFORM` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ACCNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון הלקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח/חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NAME` | String(37) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "איש קשר". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHNAME` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קופה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVNUM` | String(16) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר קבלה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FINAL` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סופית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STATDES` | String(12) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סטטוס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OWNERLOGIN` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לטיפול". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום חשבוניות לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISCOUNT` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הנחה על תשלום מוקדם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום הקבלה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DIFF` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הפרש". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BOOKNUM` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר פנקס". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ORDNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "עבור הזמנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `REFERENCE` | String(25) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הז. רכש (לקוח)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TYPECODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג מכירה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TYPEDES` | String(12) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סוג מכירה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROJDOCNO` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרויקט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROJDES` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור פרויקט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHPAYMENT` | Decimal p13s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תקבולים במזומן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCITEMSFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פירוט לפקודת יומן?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PROFORMAFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פירוט של חש. עסקה?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AFTERWTAX` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סה"כ תקבולים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAX` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ניכוי מס במקור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAXPERCENT` | Decimal p5s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "% ניכוי מס במקור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETAILS` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PRINTEDBOOL` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הודפסה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת. תשלום משוקלל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AVRGDATE` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת. חשבוניות משוקלל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ADJPRICEFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שערוך ליום החשבונית?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTCODE2` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס' סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGENTNAME2` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם סוכן נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCPATNAME` | String(5) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג תנועה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCNUM` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. תנועת היומן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STORNOFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מבוטל ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EMAIL` | String(68) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "דואר קבלה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHNAME` | String(6) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPECODE` | String(2) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סוג לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CTYPENAME` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סוג לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EXTFILEFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נספחים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BILLINGUSERLOGIN` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אחראי גביה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EDIFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שולמה עם Click2Pay". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVCODENAME` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד סווג נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVCODEDES` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור סווג נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHEXCEPTFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אישור חריגת מזומן?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TYPEDBYLOGIN` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מאשר מזומן חריג". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TYPEDDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאריך אישור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DEBIT` | String(1) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חיוב/זכוי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IV` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבונית (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVTYPE` | String(1) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג". Emitted as declared in the instance $metadata; null when the row carries no value. |
#### `TPAYMENT2_SUBFORM` attributes

Payment means lines (check, transfer, card): PAYMENTCODE/PAYMENTNAME/QPRICE.

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `PAYMENTCODE` | String(4) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYMENTNAME` | String(40) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אמצעי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHNAME` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד קופה/בנק/אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYACCOUNT` | String(34) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס חשבון/כרטיס אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `VALIDMONTH` | String(5) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תוקף כרטיס (MM/YY)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `QPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYCODE` | String(4) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDES` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FIRSTPAY` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תשלום ראשון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OTHERPAYMENTS` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום כל תשלום נוסף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STARDISCOUNT` | Decimal p13s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הנחת כוכבים/נקודות". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DEALCODE` | String(2) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד עסקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CLUBCODE` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מועדון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `LINKCODE` | String(2) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הצמדת תשלומים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CARDNUM` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. שובר אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CCUID` | String(40) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מזהה כרטיס יחודי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETAILS` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAX` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ניכוי במקור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAX2` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ניכוי במקור 2". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `WTAX3` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ניכוי במקור 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TOTPRICE` | Decimal p16s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום כולל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SHVA_TERMINALNAME` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מסוף שידור אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CONFNUM` | String(9) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר אישור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SHVAFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אישור אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `STORNOFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מבוטל ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHFLOWCODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תזרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת. פרעון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MSVDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת. פריקה למס"ב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MSVFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "בבדיקה למס"ב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BANKCODE` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד בנק - לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BANKNAME` | String(56) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם הבנק". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCH` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף - לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BIC` | String(12) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "BIC - Bank ID Code". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EEAFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "EEA". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SEPADIRDEBNUM` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מזהה הו"ק לSEPA". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IDNUM` | String(12) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר זהות/זהוי למס"ב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MSVNAMEFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח בשדה פרטים?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCTYPETOCHARGE` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג חשבון לחיוב". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACHFAILED` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "דחיית עסקת ACH". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `KLINE` | Int64 |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורה (מפתח)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYMENT` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תשלום (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
#### `TFNCITEMS_SUBFORM` attributes

Applications: CREDIT applied to the invoice named by FNCIREF1. A cancellation reverses with negative CREDIT.

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `CREDIT` | Decimal p18s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סכום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `IVCODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תעודה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCIREF1` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אסמכתא 1". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCIREF2` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אסמכתא 2". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCIREF3` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אסמכתא 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ORDNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "הזמנה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETAILS` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISCOUNT` | Decimal p5s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "% הנחה לתשלום מוקדם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME2` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 2". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME3` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 3". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME4` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 4". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COSTCNAME5` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מרכז רווח 5". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BUDCODE` | String(30) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סעיף תקציבי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FRECONNUM` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. התאמה פנימית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ת. ערך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PDACCNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון להעברת הפרשים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PDACCDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון הפרשים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DOCNO` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרויקט". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCICODE` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מיון שורת פ"י". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מס. לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CUSTDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם לקוח". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FNCTRANS` | Int64 |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תנועת יומן (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `KLINE` | Int64 |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורה (מפתח)". Emitted as declared in the instance $metadata; null when the row carries no value. |

### `PAY`

Payment terms: the seven standard terms of the US-localized instance, verbatim (Net Month End ... +120 Days — the names live in PAYDES; EPAYDES is null on every row, exactly as on the reference instance). NUMPAY > 1 would carry installment splits in PAYITEMS_SUBFORM.

Base path: `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY` | supported | Collection read with the query options above. $count, $search, $format, unknown $-options and non-$ parameters are SILENTLY IGNORED (measured) — rows come back unaffected. This is Priority's behaviour, not an omission. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY('<PAYCODE>')` | supported | Item read: $entity context, properties at TOP LEVEL (no value wrapper). $select applies and so does $expand; LIST options on an item read ($filter, $top) are SILENTLY IGNORED — measured, an item read with a $filter that excludes the entity still returns it. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY('<PAYCODE>')/PAYITEMS_SUBFORM` | supported | Installment splits per term. Every seeded term is single-payment (NUMPAY 1, matching the reference instance's seven standard terms), so the collection answers EMPTY — the navigation is published and addressable, the data says one payment. Also reachable inline via $expand=PAYITEMS_SUBFORM. An inline child carries no envelope of its own and is the COMPLETE child set unless narrowed by nested options ($top/$skip/$orderby/$select/$filter). The path form supports the query options against the CHILD type, and ('<PAYCODE>')/PAYITEMS_SUBFORM/$count answers the child count as a plain-text number honouring $filter. A KEYED subform item (PAYITEMS_SUBFORM(...)) is NOT addressable for READS — bare 404. This form accepts NO writes at all — every write verb on the parent or this child answers the API-permission refusal. |
| POST | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY` | not_supported | Every write verb on this form answers the measured API-permission refusal, verbatim (the reference instance refuses API operation of this form): POST, PATCH, PUT and DELETE alike, before any body parsing. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY

| Status | Meaning |
| --- | --- |
| 200 | OK — { "@odata.context": ..., "value": [...] } |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |

Request:

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY?$top=5'
```

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY('<PAYCODE>')

| Status | Meaning |
| --- | --- |
| 200 | OK — $entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | An unknown property in $select, a bad $orderby, or any invalid NESTED option inside $expand (validated against the CHILD type: unknown property, typed mismatch, bad $top/$skip). A TOP-LEVEL $filter/$top/$skip is not parsed here, so its invalid values answer 200 with the entity. |
| 404 | A DUPLICATED honoured query option, or a key form in the bare-404 family — EMPTY body, distinct from the envelope 404 below. |
| 501 | A $filter FUNCTION inside a NESTED $expand option — 'Function "X" is not supported'. A top-level $filter is not parsed on an item read, so a function THERE answers 200. |
| 404 | Well-formed key, no match: the ENVELOPE 404 'The specified entity was not found'. Missing key parts: bare 404, empty body. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY('<PAYCODE>')/PAYITEMS_SUBFORM

| Status | Meaning |
| --- | --- |
| 200 | OK — collection payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |
| 404 | The PARENT key does not resolve — envelope 404 |

##### POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/PAY

| Status | Meaning |
| --- | --- |
| 400 | לא ניתן להפעיל API למסך זה כיוון שהרשאותיך למסך זה אינן מספיקות. |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `$select` | Comma-separated property projection. Response properties keep METADATA order, not $select order, while the CONTEXT fragment echoes the order you sent (with duplicates deduped), and $select=* is honoured — the full property set with a (*) context (all measured). PLAIN properties only: naming a subform navigation in $select is refused 400 with the instance-language XML-generation message (measured) — embed subforms with $expand instead. | `$select=PAYCODE` |
| `$filter` | eq, ne, gt, ge, lt, le with and/or and parentheses; string literals in single quotes, dates bare ISO-8601, null bare. LITERALS ARE TYPED: a numeric property takes a bare numeric literal, a string property a quoted one, a date property a bare ISO date — a family mismatch (MONTHS gt '500', PAYCODE eq 5) is refused 400 'A binary operator with incompatible types was detected. Found operand types ... for operator kind ...' (the strict draw of a measured backend variance; the other backend silently coerces or matches nothing — never rely on that). FUNCTIONS (contains, startswith, ...) answer 501 here — the shared sandbox answers them non-deterministically by backend version, so this simulator serves the one refusal an integrator can code against anywhere. An unknown PROPERTY is refused 400 naming it. | `$filter=NUMPAY eq 1` |
| `$orderby` | Field asc\|desc, comma-separated for multi-key. The direction word must be asc or desc: anything else ($orderby=PAYCODE sideways) is refused 400 on every measured draw — 'Syntax error at position N in '<option>'.' (the message phrasing varies by backend; the refusal does not). | `$orderby=PAYCODE asc` |
| `$top` | Page size. The value must be a plain non-negative integer ('+' and surrounding spaces are tolerated — measured). 0 is a no-op (all rows). A NEGATIVE or NON-INTEGER value ($top=-1, $top=3.0, $top=abc) is refused 400 'Invalid value 'X' for $top query option found. The $top query option requires a non-negative integer value.' — the strict draw of a measured variance: one backend ignores negative integers, and non-integers are refused on every draw. Nested $top inside $expand has its own envelope — see the nested-options convention. | `$top=25` |
| `$skip` | Rows to skip; page with $top + $skip. The same value rules as $top: 0 is a no-op, negative or non-integer values are refused with the Invalid-value envelope. | `$skip=25` |
| `$since` | Priority-specific (v20.0+, developer portal): only records CHANGED at or after the given UTC instant — the portal recommends the Z suffix. Composes with $filter and the rest, including /$count. An UNPARSEABLE value is silently ignored (measured on the official sandbox). A WRITE is a change instant: on the WRITABLE forms a created row and an updated row both surface for a $since after the write, and a LINE write bumps its parent invoice — so $since polls for updates, not only for inserts. On the read-only forms (TINVOICES, PAY, ACCOUNTS_RECEIVABLE) nothing you send can create an instant; their rows carry the seed instant and ACCOUNTS_RECEIVABLE additionally surfaces when the customer behind it is created. Seeded rows carry the environment's seed instant, which is not exposed as a row property and is unrelated to document dates like IVDATE — use $since for change polling, not for date-range queries. | `$since=2026-01-01T00:00:00Z` |
| `$expand` | Embeds a subform inline, with nested options: $expand=CHILD($top=5;$select=A,B) — the nested separator is ';', NOT ',' (a comma is refused 400; see the nested-options convention). Works on COLLECTION and ITEM reads alike. The inline child is the COMPLETE child set UNLESS you narrow it with nested options — $top truncates, $skip skips, $orderby reorders, $select projects, and $filter excludes (all measured honoured on the real wire). An unknown child name is refused 400 naming it; expanding a PLAIN (non-navigation) property is refused 400 'is not a navigation property or complex property'. | `$expand=PAYITEMS_SUBFORM` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `PAYCODE` | String(4) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDES` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תנאי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EPAYDES` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תנאי תשלום (אנגלית)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NEXTMONTH` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שוטף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MONTHS` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חודשים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DAYS` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ימים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NUMPAY` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר תשלומים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CREDITCODE` | String(2) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סוג אשראי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CLUBCODE` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד מועדון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISCOUNT` | Decimal p5s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "% הנחה לתשלום מוקדם". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DISCDAYS` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ימים להנחה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYMENTCODE` | String(4) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYMENTNAME` | String(40) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "אמצעי תשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פירוט שורות?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAYDESCONT` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור תנאי תשלום המשך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FROMSYNC` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נתון תשתית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INACTIVE` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא פעיל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PAY` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תשלום (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |
#### `PAYITEMS_SUBFORM` attributes

Installment splits per term. Every seeded term is single-payment (NUMPAY 1, matching the reference instance's seven standard terms), so the collection answers EMPTY — the navigation is published and addressable, the data says one payment.

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `MONTHS` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חודשים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DAYS` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "ימים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `PERCENT` | Decimal p7s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "% לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `RPERCENT` | Decimal p16s7 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "% מנורמל לתשלום". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DETAILS` | String(24) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "פרטים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NEXTMONTH` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שוטף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `KLINE` | Int64 |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שורה (מפתח)". Emitted as declared in the instance $metadata; null when the row carries no value. |

### `ACCOUNTS_RECEIVABLE`

Per-customer AR balances, keyed by ACCNAME (= CUSTNAME). BALANCE1/2/3 agree in this single-currency book. Every customer has a row — creating a customer through the API gives it one immediately, at balance 0.

Base path: `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE`

#### Operations

| Method | Path | Status | Description |
| --- | --- | --- | --- |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE` | supported | Collection read with the query options above. $count, $search, $format, unknown $-options and non-$ parameters are SILENTLY IGNORED (measured) — rows come back unaffected. This is Priority's behaviour, not an omission. |
| GET | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE('<ACCNAME>')` | supported | Item read: $entity context, properties at TOP LEVEL (no value wrapper). $select applies ($expand has nothing to embed here — this resource publishes no subforms); LIST options on an item read ($filter, $top) are SILENTLY IGNORED — measured, an item read with a $filter that excludes the entity still returns it. |
| POST | `https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE` | not_supported | Every write verb on this form answers the measured API-permission refusal, verbatim (the reference instance refuses API operation of this form): POST, PATCH, PUT and DELETE alike, before any body parsing. |

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE

| Status | Meaning |
| --- | --- |
| 200 | OK — { "@odata.context": ..., "value": [...] } |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 501 | A $filter FUNCTION (contains, startswith, tolower, ...) — 'Function "X" is not supported'. Reachable wherever a $filter is PARSED: collections, subforms, /$count, and inside a NESTED $expand option on any read, item reads included. |
| 400 | An unknown property in $select/$filter/$orderby, a typed-literal mismatch, or an invalid $top/$skip value — $orderby is validated even where the option is otherwise ignored |
| 404 | A DUPLICATED honoured query option — bare 404, EMPTY body (distinct from the envelope 404 of a key that does not resolve) |

Request:

```bash
curl -u API_USER:API_PASSWORD 'https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE?$top=5'
```

##### GET https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE('<ACCNAME>')

| Status | Meaning |
| --- | --- |
| 200 | OK — $entity payload |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |
| 400 | An unknown property in $select, a bad $orderby, or any invalid NESTED option inside $expand (validated against the CHILD type: unknown property, typed mismatch, bad $top/$skip). A TOP-LEVEL $filter/$top/$skip is not parsed here, so its invalid values answer 200 with the entity. |
| 404 | A DUPLICATED honoured query option, or a key form in the bare-404 family — EMPTY body, distinct from the envelope 404 below. |
| 501 | A $filter FUNCTION inside a NESTED $expand option — 'Function "X" is not supported'. A top-level $filter is not parsed on an item read, so a function THERE answers 200. |
| 404 | Well-formed key, no match: the ENVELOPE 404 'The specified entity was not found'. Missing key parts: bare 404, empty body. |

##### POST https://erplab.cloud/sim/{environmentKey}/odata/Priority/tabula.ini/demo/ACCOUNTS_RECEIVABLE

| Status | Meaning |
| --- | --- |
| 400 | לא ניתן להפעיל API למסך זה כיוון שהרשאותיך למסך זה אינן מספיקות. |
| 401 | Missing or wrong credential — EMPTY body, WWW-Authenticate: Basic. Checked BEFORE routing, so it precedes every other code here. |

#### Query parameters

| Parameter | Description | Example |
| --- | --- | --- |
| `$select` | Comma-separated property projection. Response properties keep METADATA order, not $select order, while the CONTEXT fragment echoes the order you sent (with duplicates deduped), and $select=* is honoured — the full property set with a (*) context (all measured). PLAIN properties only: naming a subform navigation in $select is refused 400 with the instance-language XML-generation message (measured) — embed subforms with $expand instead. | `$select=ACCNAME` |
| `$filter` | eq, ne, gt, ge, lt, le with and/or and parentheses; string literals in single quotes, dates bare ISO-8601, null bare. LITERALS ARE TYPED: a numeric property takes a bare numeric literal, a string property a quoted one, a date property a bare ISO date — a family mismatch (BALANCE3 gt '500', ACCNAME eq 5) is refused 400 'A binary operator with incompatible types was detected. Found operand types ... for operator kind ...' (the strict draw of a measured backend variance; the other backend silently coerces or matches nothing — never rely on that). FUNCTIONS (contains, startswith, ...) answer 501 here — the shared sandbox answers them non-deterministically by backend version, so this simulator serves the one refusal an integrator can code against anywhere. An unknown PROPERTY is refused 400 naming it. | `$filter=BALANCE1 gt 0` |
| `$orderby` | Field asc\|desc, comma-separated for multi-key. The direction word must be asc or desc: anything else ($orderby=ACCNAME sideways) is refused 400 on every measured draw — 'Syntax error at position N in '<option>'.' (the message phrasing varies by backend; the refusal does not). | `$orderby=ACCNAME asc` |
| `$top` | Page size. The value must be a plain non-negative integer ('+' and surrounding spaces are tolerated — measured). 0 is a no-op (all rows). A NEGATIVE or NON-INTEGER value ($top=-1, $top=3.0, $top=abc) is refused 400 'Invalid value 'X' for $top query option found. The $top query option requires a non-negative integer value.' — the strict draw of a measured variance: one backend ignores negative integers, and non-integers are refused on every draw. Nested $top inside $expand has its own envelope — see the nested-options convention. | `$top=25` |
| `$skip` | Rows to skip; page with $top + $skip. The same value rules as $top: 0 is a no-op, negative or non-integer values are refused with the Invalid-value envelope. | `$skip=25` |
| `$since` | Priority-specific (v20.0+, developer portal): only records CHANGED at or after the given UTC instant — the portal recommends the Z suffix. Composes with $filter and the rest, including /$count. An UNPARSEABLE value is silently ignored (measured on the official sandbox). A WRITE is a change instant: on the WRITABLE forms a created row and an updated row both surface for a $since after the write, and a LINE write bumps its parent invoice — so $since polls for updates, not only for inserts. On the read-only forms (TINVOICES, PAY, ACCOUNTS_RECEIVABLE) nothing you send can create an instant; their rows carry the seed instant and ACCOUNTS_RECEIVABLE additionally surfaces when the customer behind it is created. Seeded rows carry the environment's seed instant, which is not exposed as a row property and is unrelated to document dates like IVDATE — use $since for change polling, not for date-range queries. | `$since=2026-01-01T00:00:00Z` |

#### Attributes

| Attribute | Type | Required | Read-only | Description |
| --- | --- | --- | --- | --- |
| `ACCNAME` | String(16) |  | yes | KEY. Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `EACCDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון (אנגלית)". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BALANCE3` | Decimal p18s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה במטבע חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מטבע החשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BALANCE1` | Decimal p18s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה ב{LC.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BALANCE2` | Decimal p18s2 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "יתרה ב{FC.F}". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACNGCODE` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חתך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACNGDES` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חתך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHNAME` | String(6) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `BRANCHDES` | String(32) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור הסניף". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TRIALBALCODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סעיף למאזן בוחן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TRIALBALDES` | String(56) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "כותרת למאזן בוחן". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `AGINGMETHOD` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "התאמה אוט. בקבלה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CLOSED` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מבוטל ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CLOSEDATE` | DateTimeOffset |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סגירה עד תאריך". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `MULTICURFLAG` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "רב מטבעי". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHFLOWCODE` | String(3) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד תזרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CASHNAME` | String(20) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד חש' בנק לתזרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SECNAME` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סעיף מאזני". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `DNAME` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תוכנת מקור". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `OLDNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספרו במערכת קודמת". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMPANYNAME` | String(8) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תת חברה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `COMPANYDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "שם תת חברה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FATACCNAME` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון בחברה ראשית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FATACCDES` | String(48) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור חשבון". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `CONFIDENTIAL` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון חסוי?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FORM6111` | String(4) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "סעיף בטופס 6111". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NOCASHFLOW` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא משתתף בתזרים". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `NOAGEDEBTS` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא לגיול ?". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SATCODE` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד קיבוץ SAT". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `SATDES` | String(80) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור קיבוץ SAT". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXONOMYCODE` | String(6) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "קוד טקסונומיה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `TAXONOMYDES` | String(120) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "תאור טקסונומיה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCFOREXPORT` | String(16) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "מספר חשבון לפריקה". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `INACTIVE` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "לא פעיל". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `FROMSYNC` | String(1) |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "נתון תשתית". Emitted as declared in the instance $metadata; null when the row carries no value. |
| `ACCOUNT` | Int64 |  | yes | Form-column title (the $metadata Priority.OData.Description annotation, in the instance language): "חשבון (ID)". Emitted as declared in the instance $metadata; null when the row carries no value. |

#### Limitations

- BALANCE is COMPUTED: Σ TOTPRICE of FINALIZED invoices − Σ applied receipt credits, per customer. FINALIZED means FINAL eq 'Y' on BOTH sides, and that includes a cancellation's reversing rows — their negative amounts are how a canceled document or application nets out of the balance. The credit side sums TFNCITEMS rows of finalized receipts only; each row's FNCIREF1 carries the applied invoice's IVNUM and its ACCNAME the customer. Unapplied cash does not reduce the balance until applied. A customer who owes shows a positive balance. The real instance's balance derivation could not be verified (its ledger subforms are not readable on the sandbox), so this derivation is the simulator's own, stated here precisely so it can be relied on — or ignored — knowingly.
- The ledger-entry subforms (ACCFNCITEMS_*) are not implemented; reading them answers a bare 404.

## Errors

Branch on the stable error CODE field shown in the example bodies below; message text is prose and may be reworded.

### Missing or wrong Basic credential (401)

**Means:** Every path under the /odata PREFIX is gated — the service root, $metadata, and also the paths that merely LOOK like the base (a wrong config-file or company segment): the credential is checked before any routing, so a 401 there does not mean your path is right. (The tenant root and other non-/odata paths answer their bare 404 without an auth gate; they carry nothing.) The 401 body is EMPTY with WWW-Authenticate: Basic — measured; there is no JSON envelope on auth failures.

**Do:** Send -u username:password. Mint credentials in Settings → ERP.

```json
(empty body)
```

### Unknown property in a query option (400)

**Means:** The envelope's code is the HTTP status AS A STRING and details is an OBJECT — Priority's measured shape, which differs from the OData spec's examples.

**Do:** Use property names exactly as $metadata declares them (they are UPPERCASE).

```json
{"error":{"code":"400","message":"Could not find a property named 'X' on type 'Priority.OData.CUSTOMERS'.","target":"","details":{},"innererror":{}}}
```

### Filter function not supported (501)

**Means:** String functions answer 501 here. The shared sandbox answers them 200 or 501 NON-DETERMINISTICALLY by backend version; a specific real instance behaves one way consistently. This simulator serves the refusal — the one contract portable to any instance.

**Do:** Filter with comparison operators; select client-side for substring needs.

```json
{"error":{"code":"501","message":"Function \"contains\" is not supported","target":"","details":{},"innererror":{}}}
```

### Malformed $filter expression (400)

**Means:** A missing operand answers 'Expression expected at position N in '<filter>'.'; an invalid character (a double quote, for instance) answers 'Syntax error: character '\"' is not valid at position N in '<filter>'.' — positions are 0-based indexes into the filter text. Both measured verbatim. This catalog is REPRESENTATIVE, not exhaustive: other malformed inputs answer the same envelope shape with their own messages, and one sandbox backend phrases some of them differently ('Invalid query options: Token ...' — a ledgered variance).

**Do:** String literals use SINGLE quotes ('X', doubled '' to escape); every comparison needs both operands.

```json
{"error":{"code":"400","message":"Expression expected at position 11 in 'CUSTNAME eq'.","target":"","details":{},"innererror":{}}}
```

### Bad nested $expand option (400)

**Means:** The nested-option separator is ';' — a comma runs the clause into the current option's value and is refused with that option's own error (this example is the measured comma-after-$top envelope; comma-after-$select answers 'Found system token ...'). A non-integer nested $skip answers the symmetric 'Skip option must be a non-negative integer ...' (one sandbox backend leaks a strconv error instead — ledgered); expanding a non-navigation answers 'is not a navigation property or complex property'; an unknown property in a nested $select answers the instance's XML-generation message in the instance language.

**Do:** Separate nested options with ';' inside the parentheses: $expand=CHILD($top=5;$select=A,B).

```json
{"error":{"code":"400","message":"Top option must be a non-negative integer, it is set to '1,$select=NAME' instead.","target":"","details":{},"innererror":{}}}
```

### Form validation refused a write (InterfaceErrors) (400)

**Means:** The form engine's refusal: HTTP 400 whose body is the interface XML rendered as JSON — NOT the OData envelope. @TYPE names the PARENT form even for child rows; the message counter is the interface row (שורה 1- for the parent, שורה 2- for the first child), and the text is in the INSTANCE language (Hebrew here), verbatim. Missing required columns, values not in a referenced table (unknown customer, bad status, any REFERENCE), and refused deletions all use this shape.

**Do:** Fix the named column; do not parse the message — its language is instance data.

```json
{"?xml":{"@version":"1.0","@encoding":"utf-8","@standalone":"yes"},"FORM":{"@TYPE":"CUSTOMERS","InterfaceErrors":{"@XmlFormat":"0","text":"שורה 1- - חסר מס. לקוח"}}}
```

### Wrong JSON type in a write payload (400)

**Means:** The one envelope with a POPULATED innererror (measured): the outer message names the literal and the target EDM type, the inner one both types.

**Do:** Send strings for string columns, bare numbers for numeric ones.

```json
{"error":{"code":"400","message":"Cannot convert the literal '5' to the expected type 'Edm.String'.","target":"","details":{},"innererror":{"message":"Cannot convert a value of type 'Edm.Int32' to the expected target type 'Edm.String'.","type":"","stacktrace":"","innererror":{}}}}
```

### Create key already exists (409)

**Means:** POST with an explicit key that is already taken. PATCH/PUT of a MISSING key answers 400 'A record with the specified key was not found' (a 400, not a 404 — measured).

**Do:** GET first, or treat 409 as 'exists'.

```json
{"error":{"code":"409","message":"A record with the specified key already exists","target":"","details":{},"innererror":{}}}
```

### API permission refused for this form (400)

**Means:** Writes to TINVOICES, PAY and ACCOUNTS_RECEIVABLE answer this measured refusal verbatim (the reference instance's API permissions), before any body parsing. Reads are unaffected.

**Do:** Treat these forms as read-only.

```json
{"error":{"code":"400","message":"לא ניתן להפעיל API למסך זה כיוון שהרשאותיך למסך זה אינן מספיקות.","target":"","details":{},"innererror":{}}}
```

### No such entity (404)

**Means:** A WELL-FORMED key that matches nothing gets the envelope. An unknown entity set, an unknown segment, a property path segment, a keyed subform item, or a composite read missing key parts gets a BARE 404 with an empty body.

**Do:** Distinguish the two 404s by the body: envelope = the set exists, the row does not.

```json
{"error":{"code":"404","message":"The specified entity was not found","target":"","details":{},"innererror":{}}}
```

