BI
The BI endpoints expose any Business Central table as JSON, so a reporting or analytics tool can read NP Retail data without a dedicated endpoint being built for each table first.
There are two endpoints. GET /bi/{tableNo} returns the records of a table. GET /tablemetadata and GET /tablemetadata/{tableNo} describe what can be read and what the records look like.
Enabling a table
The BI endpoint can reach every table in the database, so access is not granted by the permission set alone. Each table has to be enabled for the caller, one table at a time.
In Business Central, open NaviPartner API Keys, select the key your integration uses, and choose BI API Allowed Tables. Add a row per table you want the integration to read. If your integration authenticates with an Entra ID application that was not created from a NaviPartner API Key, use the BI API Allowed Tables action on the Entra Application card instead.
An application that belongs to a NaviPartner API Key always uses the list of that key. Rows added for such an application directly are ignored.
The list is held once per tenant rather than per company, so enabling a table enables it in every company the caller can already reach. Which companies those are is decided separately, by where the BI permission set is assigned: a caller that does not hold it in a given company cannot read anything there, whatever the list says.
Reading a table that has not been enabled returns 403 with the error code bi_table_not_allowed.
Discovering tables and fields
GET /tablemetadata lists every table that can be exposed, with its table number, its English and translated name, whether you are allowed to read it, and whether it supports replication.
GET /tablemetadata/{tableNo} describes one table field by field. For each field it gives the field number, the English and translated caption, the data type, the length for text fields, whether the field belongs to the primary key, and jsonName: the property name that field has in the records returned by /bi/{tableNo}.
Both metadata endpoints are open to every caller that holds the BI permission set. They return no business data, and they work whether or not the table has been enabled. Only the data endpoint is gated by the allowlist.
Which fields you get
The records contain every field that is stored in the database, including the system fields: id (the system id of the record), systemCreatedAt, systemCreatedBy, systemModifiedAt and systemModifiedBy.
Calculated fields are not returned, because they are not stored: FlowFields and FlowFilters are left out. Binary and filter fields are left out as well: Blob, Media, MediaSet and TableFilter.
Enum and option fields carry the value name rather than the translated caption, so NP API Key rather than NaviPartner API Key. That name is the same whatever language the caller asks for, which makes it safe to store and compare. Dates, times, durations and date formulas are written in the invariant format for the same reason.
Property names are the camelCase form of the English field name, so No. becomes no and VAT Bus. Posting Group becomes vatBusPostingGroup. The names id and rowVersion are reserved; a field whose name would collide with a reserved name, or with a field that comes earlier in the table, gets its field number appended, for example id_1. Always take the names from jsonName rather than deriving them yourself.
Paging and incremental loads
Paging and replication behave exactly as they do elsewhere in this API. See Pagination and Replication.
The default page size of the BI endpoint is 1000 records rather than the usual maximum, because a BI record carries every field of its table and some tables have several hundred. You can raise it up to 20000 with pageSize.
Every read is incremental. There is no separate mode to switch on: records always come back ordered by row version, and every record carries its rowVersion. To read a table for the first time, call it without lastRowVersion and follow nextPageKey to the end. To pick up changes later, pass the highest rowVersion you received as lastRowVersion. Sending sync=false is rejected, so you cannot end up with a read you are unable to resume.
A read stops just below the oldest write that is still in progress, so a record is never handed out before every record older than it is also available. That is what makes storing the highest rowVersion you received safe: a write that commits out of order cannot slip in behind your watermark. It also means a page can come back empty, or shorter than pageSize, while a write is in flight. Ask again in a moment rather than treating that as the end of the data.
Because reads are ordered by row version, the table needs a database index that starts with it. Most tables do not have one until it is added to NP Retail, so a table nobody has read this way before answers 400 with the error code bi_missing_rowversion_index. The message names the table; send it to NaviPartner and the index will be added.
GET /tablemetadata tells you in advance which tables are ready, through the syncSupported flag. A table with syncSupported: false cannot be read through /bi at all yet.
Language
The metadata endpoints return both an English and a translated caption for every table and field. The translated caption follows the Accept-Language header, then the language of the user behind the API key, and finally English. The language that was used is reported back in the language property of the response.
Field tooltips are not returned. Business Central does not make them available at runtime.
