> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.navipartner.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.navipartner.com/_mcp/server.

# Read Table

GET https://api.npretail.app/{tenant}/{environment}/{company}/bi/{tableNo}

Returns the records of any Business Central table, one JSON object per record, with every stored field of the table as a property.

The table has to be enabled for the calling API key, or for the calling Entra ID application, in the BI API Allowed Tables setup in Business Central. Reading a table that is not enabled fails with 403 and the error code `bi_table_not_allowed`.

Every read is incremental. Records always come back ordered by row version and always carry `rowVersion`, so the table needs an index that starts with the row version; without it the call fails with 400 and the error code `bi_missing_rowversion_index`. Read a table for the first time by omitting `lastRowVersion` and following `nextPageKey` to the end, then pass the highest `rowVersion` you received as `lastRowVersion` to pick up changes later.

The default page size is 1000 records, because a BI record carries every field of its table. The maximum is 20000.

Reference: https://docs.navipartner.com/apis/api-reference/bi/service-bi/get-table-records

## Authentication

- `x-np-api-key` header (required) — API Key authentication via header

## Request

### Path parameters

- `tenant` (string, required) — Your Entra Tenant ID. [More details.](/paths#1-tenant)
- `environment` (string, required) — Your Business Central Environment. [More details.](/paths#2-environment)
- `company` (string, required) — Your Business Central Company. [More details.](/paths#3-company)
- `tableNo` (integer, required) — The Business Central table number. `GET /tablemetadata` lists the available tables.

### Query parameters

- `pageSize` (integer, optional) — The maximum number of records to return per page. Defaults to 1000, maximum 20000.
- `pageKey` (string, optional) — The key for the next page of results, obtained from a previous response.
- `lastRowVersion` (string, optional) — The highest row version received previously. Only newer records are returned. Omit it to read the table from the beginning. A page stops below any write still in progress, so it can be shorter than pageSize or empty while one is in flight, which is what makes storing the highest rowVersion you received safe.
- `sync` (boolean, optional) — Deprecated and no longer needed. Every read is incremental, so sync=true is accepted and does nothing, and sync=false is rejected with invalid_input.

## Response

### 200

- `morePages` (boolean, required)
- `nextPageKey` (string, required)
- `nextPageURL` (string, required)
- `data` (list of map from string to any, required)

## Examples

**Response**

```json
{
  "morePages": true,
  "nextPageKey": "eyJ2aWV3IjoiU09SVElORyhOby4pIn0",
  "nextPageURL": "https://api.npretail.app/tenant/env/company/bi/27?pageKey=eyJ2aWV3IjoiU09SVElORyhOby4pIn0",
  "data": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "no": "A1000",
      "description": "Office Chair",
      "baseUnitOfMeasure": "PCS",
      "unitPrice": 4000,
      "systemModifiedAt": "2026-09-17T10:30:00Z",
      "rowVersion": "12345678901234567890"
    }
  ]
}
```

**SDK Code**

```python Read the Item table
import requests

url = "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27"

querystring = {"pageSize":"1000"}

headers = {"x-np-api-key": "<NaviPartner API Key>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript Read the Item table
const url = 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000';
const options = {method: 'GET', headers: {'x-np-api-key': '<NaviPartner API Key>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Read the Item table
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("x-np-api-key", "<NaviPartner API Key>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Read the Item table
require 'uri'
require 'net/http'

url = URI("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["x-np-api-key"] = '<NaviPartner API Key>'

response = http.request(request)
puts response.read_body
```

```java Read the Item table
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000")
  .header("x-np-api-key", "<NaviPartner API Key>")
  .asString();
```

```php Read the Item table
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000', [
  'headers' => [
    'x-np-api-key' => '<NaviPartner API Key>',
  ],
]);

echo $response->getBody();
```

```csharp Read the Item table
using RestSharp;

var client = new RestClient("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000");
var request = new RestRequest(Method.GET);
request.AddHeader("x-np-api-key", "<NaviPartner API Key>");
IRestResponse response = client.Execute(request);
```

```swift Read the Item table
import Foundation

let headers = ["x-np-api-key": "<NaviPartner API Key>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./bi/27?pageSize=1000")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```