13 Metadata Discovery Reference
The main bcnav module provides functions for exploring Business Central’s API schema at runtime.
13.1 Entity Descriptors
struct
(struct bc-entity (name publisher group version) #:extra-constructor-name make-bc-entity) name : string? publisher : (or/c #f string?) group : (or/c #f string?) version : (or/c #f string?)
name —
The BC entity name (e.g., "customers", "salesOrders") publisher —
#f for standard API, or the publisher name for custom APIs group —
#f for standard API, or the API group for custom APIs version —
#f for standard API, or the version for custom APIs
Standard entity modules export bc-entity values for each entity (e.g., customers, vendors, items). Use these with inspect, peek, and sample for schema and data exploration.
procedure
(bc-entity-standard? entity) → boolean?
entity : bc-entity?
procedure
(bc-entity-url entity) → string?
entity : bc-entity?
procedure
(bc-entity-id-url entity id) → string?
entity : bc-entity? id : string?
13.2 Schema Inspection
procedure
entity : bc-entity?
Entity name and API type (standard or custom)
Key properties (usually 'id)
All properties with their OData types and nullability
Navigation properties (expandable relationships)
Uses the text-table library for formatted table output.
Requires authentication. Fetches metadata on first use (then cached).
(require bcnav bcnav/api/master-data) ;; ... authentication ... (inspect customers)
Produces something like:
╭────────────────────────────────────────────╮ |
│ customers (standard v2.0 API) │ |
╰────────────────────────────────────────────╯ |
Key: id |
|
╭──────────────────┬───────────────────┬────────────────┬──────────╮ |
│ Field │ OData Type │ Racket Type │ Nullable │ |
├──────────────────┼───────────────────┼────────────────┼──────────┤ |
│ id │ Edm.Guid │ string? │ no │ |
│ number │ Edm.String │ string? │ yes │ |
│ displayName │ Edm.String │ string? │ yes │ |
│ type │ Edm.String │ string? │ yes │ |
│ addressLine1 │ Edm.String │ string? │ yes │ |
│ ... │ │ │ │ |
╰──────────────────┴───────────────────┴────────────────┴──────────╯ |
|
Navigation Properties (use with $expand): |
╭──────────────────┬───────────────┬──────────────╮ |
│ Name │ Target │ Multiplicity │ |
├──────────────────┼───────────────┼──────────────┤ |
│ currency │ currency │ one │ |
│ paymentTerm │ paymentTerm │ one │ |
│ picture │ picture │ many │ |
│ ... │ │ │ |
╰──────────────────┴───────────────┴──────────────╯ |
procedure
(inspect->comment entity) → string?
entity : bc-entity?
Useful for copying into a module as inline documentation.
procedure
(inspect->scribble entity) → string?
entity : bc-entity?
Generates "@" subsection and "@" tabular forms that can be pasted into a ".scrbl" file.
procedure
target : (or/c bc-entity? bc-result?) n : exact-positive-integer? = 5
When target is a bc-entity, fetches from the API (equivalent to calling the entity’s list function with #:top n).
When target is a bc-result, extracts the first n records from the existing result without making an API call.
Requires authentication when fetching from an entity.
(sample customers) ;; fetch first 5 from API (sample customers 10) ;; fetch first 10 from API ;; Extract from an existing result (define all-customers (customers-list)) (sample all-customers 3) ;; first 3 records, no API call
procedure
target : (or/c bc-entity? bc-result?) n : exact-positive-integer? = 5
When target is a bc-entity, fetches from the API. When target is a bc-result, displays records from the existing result.
A header showing the entity name, API type, and record count
A table with columns for each field in the returned records
Automatic column alignment (right for numbers, left for text)
Ideal for interactive exploration in the REPL. Uses sample internally to get data, then formats it using the text-table library.
Requires authentication when fetching from an entity.
(peek customers) ;; fetch and display first 5 records (peek customers 10) ;; fetch and display first 10 records ;; Display from an existing result (define result (customers-list)) (peek result 3) ;; display first 3, no API call
This outputs a nicely formatted table:
╭────────────────────────────────────────────────────────────╮ |
│ customers (standard v2.0 API) - 5 records │ |
╰────────────────────────────────────────────────────────────╯ |
╭──────────────────┬──────────┬───────────────────┬──────────╮ |
│ id │ number │ displayName │ email │ |
├──────────────────┼──────────┼───────────────────┼──────────┤ |
│ a1b2c3d4-... │ C00010 │ Contoso Ltd │ info@... │ |
│ e5f6g7h8-... │ C00020 │ Fabrikam Inc │ sales@...│ |
│ ... │ │ │ │ |
╰──────────────────┴──────────┴───────────────────┴──────────╯ |
13.3 Standard API Metadata
procedure
Returns a hash table mapping entity names (as symbols) to entity-info structs.
The result is cached in current-bc-metadata-cache. Subsequent calls return the cached data without making an API request.
Requires authentication.
procedure
(entity-schema entity-name) → (or/c #f entity-info?)
entity-name : (or/c string? symbol?)
Calls fetch-metadata internally (using cached data if available).
(define info (entity-schema 'customer)) (entity-info-properties info)
13.4 Custom API Metadata
procedure
(fetch-custom-metadata publisher group version) → (hash/c symbol? entity-info?) publisher : string? group : string? version : string?
Returns a hash table mapping entity names to entity-info structs.
Custom API metadata is cached separately from standard API metadata, keyed by the combination of publisher, group, and version.
procedure
(custom-entity-schema publisher group version entity-name) → (or/c #f entity-info?) publisher : string? group : string? version : string? entity-name : (or/c string? symbol?)
13.5 Schema Data Structures
struct
(struct entity-info ( name key-properties properties navigation-properties) #:extra-constructor-name make-entity-info) name : symbol? key-properties : (listof symbol?) properties : (listof property-info?) navigation-properties : (listof nav-property-info?)
name —
The entity name as a symbol key-properties —
Property names that form the entity’s primary key (usually just '(id)) properties —
List of all properties (fields) navigation-properties —
List of expandable relationships
struct
(struct property-info (name type nullable?) #:extra-constructor-name make-property-info) name : symbol? type : string? nullable? : boolean?
name —
The property name as used in API requests/responses type —
The OData/EDM type (e.g., "Edm.String", "Edm.Guid") nullable? —
Whether the property can be null/empty
struct
(struct nav-property-info (name target-type multiplicity) #:extra-constructor-name make-nav-property-info) name : symbol? target-type : string? multiplicity : (or/c 'one 'many)
name —
The property name to use with #:expand target-type —
The type of the related entity multiplicity —
'one for single related record, 'many for a collection
13.6 Enum Support
Business Central uses enum types for fields with a fixed set of allowed values. These types have names like Microsoft.NAV.assemblyPolicy and are returned as encoded strings in API responses.
procedure
→ (or/c #f (listof (cons/c exact-integer? string?))) entity : bc-entity? field-name : symbol?
Each value is a pair of (numeric-value . decoded-name).
(enum-values items 'assemblyPolicy) ;; => ’((0 . "Assemble-to-Stock") (1 . "Assemble-to-Order"))
Use the numeric value in filters for cleaner queries:
(items-list #:query (make-query #:filter (eq 'assemblyPolicy 0)))
Special characters are converted to _xNNNN_ format where NNNN is the hex Unicode code point.
(bc-encode-enum "Assemble-to-Stock") ;; => "Assemble_x002D_to_x002D_Stock"
Converts _xNNNN_ patterns back to their original characters.
(bc-decode-enum "Assemble_x002D_to_x002D_Stock") ;; => "Assemble-to-Stock"
struct
(struct enum-info (name full-name members) #:extra-constructor-name make-enum-info) name : symbol? full-name : string? members : (listof enum-member-info?)
name —
Local name as a symbol (e.g., 'assemblyPolicy) full-name —
Fully qualified name (e.g., "Microsoft.NAV.assemblyPolicy") members —
List of allowed values, sorted by numeric value
struct
(struct enum-member-info (value name decoded-name) #:extra-constructor-name make-enum-member-info) value : exact-integer? name : string? decoded-name : string?
value —
The numeric value (use this in filters) name —
The API-encoded name (e.g., "Assemble_x002D_to_x002D_Stock") decoded-name —
Human-readable name (e.g., "Assemble-to-Stock")
13.7 Cache Management
parameter
→ (or/c #f (hash/c symbol? entity-info?)) (current-bc-metadata-cache cache) → void? cache : (or/c #f (hash/c symbol? entity-info?))
= #f
parameter
→ (hash/c string? (hash/c symbol? entity-info?)) (current-bc-custom-metadata-cache cache) → void? cache : (hash/c string? (hash/c symbol? entity-info?))
= (hash)
procedure
Call this if you need to refresh metadata after BC schema changes (e.g., after installing extensions or updating BC).