12 Entity API Reference
bcnav provides modules for accessing different categories of Business Central entities.
12.1 Master Data
| (require bcnav/api/master-data) | package: bcnav-lib |
Master data entities represent core business objects like customers, vendors, and items.
12.1.1 Customers
value
procedure
(customers-list [#:query q]) → bc-result?
q : odata-query/c = #f
Example: Customers modified since a specific datetime
The 'lastModifiedDateTime field is an Edm.DateTimeOffset. Use odata-datetime for filtering:
(customers-list #:query (make-query #:filter (ge 'lastModifiedDateTime (odata-datetime "2024-12-01T00:00:00Z")) #:orderby '(lastModifiedDateTime . desc)))
procedure
(customers-get id) → hash?
id : string?
procedure
(customers-create data) → hash?
data : hash?
Required fields typically include 'displayName.
procedure
(customers-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
If etag is provided, the update only succeeds if the record’s current ETag matches (optimistic concurrency). Otherwise, a wildcard ETag is used.
Returns the updated customer.
procedure
(customers-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.1.2 Vendors
value
procedure
(vendors-list [#:query q]) → bc-result?
q : odata-query/c = #f
procedure
(vendors-get id) → hash?
id : string?
procedure
(vendors-create data) → hash?
data : hash?
procedure
(vendors-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(vendors-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.1.3 Items
value
procedure
(items-list [#:query q]) → bc-result?
q : odata-query/c = #f
procedure
(items-create data) → hash?
data : hash?
procedure
(items-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(items-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.2 Sales
| (require bcnav/api/sales) | package: bcnav-lib |
Sales entities for orders and invoices.
12.2.1 Sales Orders
value
procedure
(sales-order-list [#:query q]) → bc-result?
q : odata-query/c = #f
Common expand: 'salesOrderLines to include line items.
(sales-order-list #:query (make-query #:filter (and: (eq 'status "Open") (date-between 'orderDate "2024-01-01" "2024-12-31")) #:expand '(salesOrderLines)))
procedure
(sales-order-get id) → hash?
id : string?
procedure
(sales-order-create data) → hash?
data : hash?
procedure
(sales-order-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(sales-order-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.2.2 Sales Invoices
value
procedure
(sales-invoice-list [#:query q]) → bc-result?
q : odata-query/c = #f
Common expand: 'salesInvoiceLines to include line items.
(sales-invoice-list #:query (make-query #:filter (date-between 'postingDate "2024-12-01" "2024-12-31") #:select '(id number customerName totalAmountIncludingTax)))
procedure
(sales-invoice-get id) → hash?
id : string?
procedure
(sales-invoice-create data) → hash?
data : hash?
procedure
(sales-invoice-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(sales-invoice-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.3 Purchasing
| (require bcnav/api/purchasing) | package: bcnav-lib |
Purchasing entities for orders and invoices from vendors.
12.3.1 Purchase Orders
value
procedure
(purchase-order-list [#:query q]) → bc-result?
q : odata-query/c = #f
Common expand: 'purchaseOrderLines to include line items.
(purchase-order-list #:query (make-query #:filter (and: (eq 'status "Open") (date-between 'expectedReceiptDate "2024-12-01" "2024-12-31")) #:expand '(purchaseOrderLines)))
procedure
(purchase-order-get id) → hash?
id : string?
procedure
(purchase-order-create data) → hash?
data : hash?
Required fields typically include 'vendorNumber or 'vendorId.
procedure
(purchase-order-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(purchase-order-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.3.2 Purchase Invoices
value
procedure
(purchase-invoice-list [#:query q]) → bc-result?
q : odata-query/c = #f
Common expand: 'purchaseInvoiceLines to include line items.
(purchase-invoice-list #:query (make-query #:filter (date-between 'postingDate "2024-10-01" "2024-12-31") #:orderby '(postingDate . desc)))
procedure
(purchase-invoice-get id) → hash?
id : string?
procedure
(purchase-invoice-create data) → hash?
data : hash?
procedure
(purchase-invoice-update id data [ #:etag etag]) → hash? id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(purchase-invoice-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.4 Finance
| (require bcnav/api/finance) | package: bcnav-lib |
Finance entities for the chart of accounts, trial balance, general ledger entries, and journals.
12.4.1 Accounts
value
procedure
(account-list [#:query q]) → bc-result?
q : odata-query/c = #f
Key fields: 'number, 'displayName, 'category, 'accountType, 'netChange, 'blocked.
Navigation property: 'trialBalance can be expanded to get trial balance data.
procedure
(account-get id) → hash?
id : string?
12.4.2 Trial Balance
value
The trial balance provides account balance information as of a specific date.
procedure
(trial-balance-list [#:query q]) → bc-result?
q : odata-query/c = #f
'accountId —
GUID of the related G/L account 'number —
Account number 'display —
Account display name 'totalDebit —
Total debit amount 'totalCredit —
Total credit amount 'balanceAtDateDebit —
Positive balance as of the filter date 'balanceAtDateCredit —
Negative balance as of the filter date 'dateFilter —
The date filter applied
Example: Get account balances as of a specific date
The 'dateFilter field accepts date strings. Use odata-date to ensure correct formatting:
(trial-balance-list #:query (make-query #:filter (eq 'dateFilter (odata-date "2024-12-31"))))
procedure
(trial-balance-get id) → hash?
id : string?
12.4.3 General Ledger Entries
value
G/L entries are read-only and represent posted transactions.
procedure
(general-ledger-entry-list [#:query q]) → bc-result?
q : odata-query/c = #f
'entryNumber —
Sequential entry number 'postingDate —
Date the entry was posted 'documentNumber —
Source document number 'documentType —
Type of source document (Invoice, Payment, etc.) 'accountId / 'accountNumber —
Related G/L account 'debitAmount / 'creditAmount —
Entry amounts 'description —
Entry description
Example: Get entries for a specific account up to a date
The 'postingDate field is an Edm.Date, so use odata-date:
(general-ledger-entry-list #:query (make-query #:filter (and: (eq 'accountNumber "1000") (le 'postingDate (odata-date "2024-12-31"))) #:select '(postingDate debitAmount creditAmount description)))
For a date range, use the date-between convenience function:
(general-ledger-entry-list #:query (make-query #:filter (and: (eq 'accountNumber "1000") (date-between 'postingDate "2024-01-01" "2024-12-31"))))
procedure
(general-ledger-entry-get id) → hash?
id : string?
12.4.4 Journals
value
Journals are containers for journal lines that can be posted to create G/L entries.
procedure
(journal-list [#:query q]) → bc-result?
q : odata-query/c = #f
Key fields: 'code, 'displayName, 'balancingAccountId, 'balancingAccountNumber.
Navigation property: 'journalLines can be expanded to include lines.
procedure
(journal-get id) → hash?
id : string?
procedure
(journal-create data) → hash?
data : hash?
Required fields: 'code, 'displayName.
procedure
(journal-update id data [#:etag etag]) → hash?
id : string? data : hash? etag : (or/c #f string?) = #f
procedure
(journal-delete id [#:etag etag]) → void?
id : string? etag : (or/c #f string?) = #f
12.5 Custom API Framework
| (require bcnav/api/custom) | package: bcnav-lib |
Macros for defining access to custom and publisher APIs.
struct
(struct custom-api-info (publisher group version) #:extra-constructor-name make-custom-api-info) publisher : string? group : string? version : string?
syntax
(define-custom-api name publisher group version)
publisher —
The API publisher (e.g., "microsoft", "contoso") group —
The API group name version —
The API version (e.g., "v1.0")
(define-custom-api contoso-api "contoso" "inventory" "v1.0")
syntax
(define-entity name entity-name)
(define-entity name api-info entity-name)
2-argument form: Uses the standard BC v2.0 API. The entity-name is a string literal naming the BC entity (e.g., "taxGroups").
3-argument form: Uses a custom/publisher API. The api-info is a custom-api-info created by define-custom-api.
Use entity-out to provide these bindings from your module.
Note: Entity names are not validated at definition time. If you use an entity name that doesn’t exist in BC, you’ll get an HTTP error when you make a request.
;; Standard API (2-arg form) (define-entity tax-group "taxGroups") (provide (entity-out tax-group)) ;; Provides: tax-group, tax-group-list, tax-group-get, tax-group-create, ... ;; Custom API (3-arg form) (define-custom-api contoso-api "contoso" "inventory" "v1.0") (define-entity widget contoso-api "widgets") (provide (entity-out widget))
syntax
(define-entity/read-only name entity-name)
(define-entity/read-only name api-info entity-name)
Use this for entities that don’t support create, update, or delete operations. When used with entity-out, only the read bindings are provided.
(define-entity/read-only account "accounts") (provide (entity-out account)) ;; Provides: account, account-list, account-get
syntax
(entity-out name)
For full CRUD entities, provides: name, name-list, name-get, name-create, name-update, name-delete.
For read-only entities, provides: name, name-list, name-get.
(define-entity customers "customers") (define-entity/read-only account "accounts") (provide (entity-out customers) ;; 6 bindings (entity-out account)) ;; 3 bindings
12.6 Entity Function Patterns
All entity functions follow consistent patterns:
12.6.1 List functions
(name-list #:query q) ;; -> bc-result?
Returns a bc-result containing all matching records. Use for to iterate directly, or bc-result->list to convert to a list. Each record is a hash table with symbol keys corresponding to entity fields. The special key 'odata.etag contains the record’s ETag.
See Result Wrapper for the full bc-result API.
12.6.2 Get functions
(name-get id) ;; -> hash?
Returns a single hash table. Raises exn:fail:bcnav:http with status 404 if not found.
12.6.3 Create functions
(name-create data) ;; -> hash?
Takes a hash table of field values. Returns the created record with server-generated fields.
12.6.4 Update functions
(name-update id data #:etag etag) ;; -> hash?
Takes an ID, a hash of fields to change, and an optional ETag. Returns the updated record.
12.6.5 Delete functions
(name-delete id #:etag etag) ;; -> void?
Takes an ID and an optional ETag. Returns (void) on success.