Skip to main content

Metadata discovery

The information on the BI Endpoints page in Business Central is also available as API endpoints. Use them to build documentation, generate pipelines, or create relationships in a BI model without hard-coding endpoint and field names.

EndpointReturns
biEndpointsEvery endpoint, standard and custom, with category, type, business key, URLs, tier and source table
propertiesThe fields of each endpoint
relationshipsForeign keys from an endpoint to others
referencedByForeign keys in other endpoints pointing at an endpoint
applicationInfoThe installed app version and the subscription

They are read like any other endpoint, under .../api/datawareness/endpoints/v1.0/companies({companyId})/, and take $filter and $select. In the Postman collection they are in the System folder.

biEndpoints​

GET .../biEndpoints?$filter=category eq 'Sales'
FieldMeaning
entitySetNameThe endpoint name used in the URL, for example customers
categoryFinance, Sales, Purchasing, Inventory, Jobs, Resources, Manufacturing, Assembly, Approvals, System or Custom
typeMaster Data or Transactional Data
businessKeyFieldsThe field or fields that identify a record, joined with &&, for example documentNo&&lineNo
urlThe full URL of the endpoint in this environment and company
genericUrlThe same URL with {{tenantId}}, {{environment}} and {{companyId}} placeholders
deletedRecordsUrl, genericDeletedRecordsUrlThe URL of the endpoint's deleted entries. See Deleted entries.
tierFree or Premium
descriptionWhat the endpoint provides
sourceTableThe Business Central source table

Category and type are rendered in the API output language.

properties​

The fields of one endpoint:

GET .../properties?$filter=entitySetName eq 'purchaseInvoiceHeaders'
FieldMeaning
entitySetNameThe endpoint
propertyNameThe field name in the response, for example buyFromVendorNo
propertyCaptionThe field's caption, for example Buy-from Vendor No.
dataTypeThe type, for example Code, Text, Decimal, Date
maxLengthThe maximum length of text and code fields
isPrimaryKeyWhether the field is part of the business key

For a custom endpoint, propertyName is the column slot (col1, col2, …) and propertyCaption is the business field it holds.

relationships​

How an endpoint's foreign keys join to other endpoints:

GET .../relationships?$filter=fromEndpoint eq 'purchaseInvoiceHeaders'
{
"value": [
{ "fromEndpoint": "purchaseInvoiceHeaders", "foreignKey": "buyFromVendorNo", "toEndpoint": "vendors", "primaryKeyField": "no", "condition": "" },
{ "fromEndpoint": "purchaseInvoiceHeaders", "foreignKey": "buyFromContactNo", "toEndpoint": "contacts", "primaryKeyField": "no", "condition": "" }
]
}

condition qualifies a relationship that only holds under a condition. For example, a global dimension column joins to dimensionValues only for the dimension code set up in General Ledger Setup: dimensionCode=glSetup.globalDimension1Code.

referencedBy​

The inverse: which endpoints point at this one.

GET .../referencedBy?$filter=toEndpoint eq 'purchaseInvoiceHeaders'
{
"value": [
{ "fromEndpoint": "purchaseInvoiceLines", "foreignKey": "documentNo", "toEndpoint": "purchaseInvoiceHeaders", "primaryKeyField": "no" }
]
}

applicationInfo​

GET .../applicationInfo
FieldMeaning
appId, name, publisher, versionThe installed BI Endpoints app
subscriptionId, tier, subscriptionStatus, expirationDateThe subscription
adminName, adminEmailThe subscription admin from BI Endpoints Setup

Use it to check which version a pipeline is talking to, and whether the subscription is active.

Example: build a model from metadata​

# Every transactional endpoint, its fields, and its joins
endpoints = get_all(f"{base}/biEndpoints?$filter=type eq 'Transactional Data'")
for ep in endpoints:
name = ep["entitySetName"]
fields = get_all(f"{base}/properties?$filter=entitySetName eq '{name}'")
joins = get_all(f"{base}/relationships?$filter=fromEndpoint eq '{name}'")
...

Add a custom endpoint and the same code picks it up on its next run.