Skip to main content

Actions

The ballerinax/microsoft.dynamics365.finance.expense package exposes the following clients:

ClientPurpose
ClientProvides access to Microsoft Dynamics 365 Finance Expense entities (expense codes, expense parameters, expense rates, expenses, mileage rates, per diems, and travel receipts) via OData.

Client

Provides access to Microsoft Dynamics 365 Finance Expense entities (expense codes, expense parameters, expense rates, expenses, mileage rates, per diems, and travel receipts) via OData.

Configuration

FieldTypeDefaultDescription
authOAuth2ClientCredentialsGrantConfigRequiredOAuth2 client credentials configuration containing tokenUrl, clientId, clientSecret, and scopes for authenticating against Microsoft Entra ID.
httpVersionhttp:HttpVersionhttp:HTTP_2_0HTTP protocol version to use for outbound requests.
http1Settingshttp:ClientHttp1Settings{}Configurations related to the HTTP/1.x protocol.
secureSockethttp:ClientSecureSocket?()SSL/TLS configuration for secure connections.
proxyhttp:ProxyConfig?()HTTP proxy server configuration.

Initializing the client

import ballerinax/microsoft.dynamics365.finance.expense;

configurable string tokenUrl = ?;
configurable string clientId = ?;
configurable string clientSecret = ?;
configurable string serviceUrl = ?;

expense:Client fo = check new (
{
auth: {
tokenUrl,
clientId,
clientSecret
}
},
serviceUrl
);

Operations

Expense Codes

listExpenseCodes

Lists ExpenseCode records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListExpenseCodesQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: ExpenseCodesCollection|error

Sample code:

expense:ExpenseCodesCollection result = check fo->listExpenseCodes(
queries = {
filter: "codeType eq 'Receipt'",
top: 20,
'select: "expenseCode,name,shortDescription,salesTaxCode"
}
);
createExpenseCodes

Creates a new ExpenseCode.

Parameters:

NameTypeRequiredDescription
payloadExpenseCodeYesThe ExpenseCode record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: ExpenseCode|error

Sample code:

expense:ExpenseCode payload = {
dataAreaId: "USMF",
expenseCode: "MEALS",
name: "Meals",
shortDescription: "Meal expenses",
codeType: "Receipt",
salesTaxCode: "MEALTAX",
direct: "No"
};
expense:ExpenseCode result = check fo->createExpenseCodes(payload);
getExpenseCodes

Retrieves a single ExpenseCode by its key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier, e.g. "USMF".
expenseCodestringYesThe expense code key field, e.g. "MEALS".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetExpenseCodesQueriesNoOData query options: expand, 'select.

Returns: ExpenseCode|error

Sample code:

expense:ExpenseCode result = check fo->getExpenseCodes("USMF", "MEALS");
deleteExpenseCodes

Deletes a specific ExpenseCode.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseCodestringYesThe expense code key field to delete.
headersDeleteExpenseCodesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteExpenseCodes("USMF", "MEALS", {ifMatch: eTag});
updateExpenseCodes

Updates a specific ExpenseCode.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseCodestringYesThe expense code key field to update.
payloadExpenseCodeYesThe fields to update.
headersUpdateExpenseCodesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: ExpenseCode|error

Sample code:

expense:ExpenseCode result = check fo->updateExpenseCodes(
"USMF",
"MEALS",
{name: "Meals and entertainment"},
{ifMatch: eTag}
);

Expense Parameters

listExpenseParameters

Lists ExpenseParameters records, with optional OData query support. This entity is typically configured once per company (dataAreaId).

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListExpenseParametersQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: ExpenseParametersCollection|error

Sample code:

expense:ExpenseParametersCollection result = check fo->listExpenseParameters(
queries = {'select: "dataAreaId,personalPaidBy,taxIncluded,postImmediately"}
);
createExpenseParameters

Creates the ExpenseParameters record for a company.

Parameters:

NameTypeRequiredDescription
payloadExpenseParametersYesThe ExpenseParameters record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: ExpenseParameters|error

Sample code:

expense:ExpenseParameters payload = {
dataAreaId: "USMF",
personalPaidBy: "Employee",
taxIncluded: "Yes",
postImmediately: "No",
whenToEvaluatePolicy: "OnSubmit"
};
expense:ExpenseParameters result = check fo->createExpenseParameters(payload);
getExpenseParameters

Retrieves the ExpenseParameters record for a company.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier, e.g. "USMF".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetExpenseParametersQueriesNoOData query options: expand, 'select.

Returns: ExpenseParameters|error

Sample code:

expense:ExpenseParameters result = check fo->getExpenseParameters("USMF");
deleteExpenseParameters

Deletes the ExpenseParameters record for a company.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
headersDeleteExpenseParametersHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteExpenseParameters("USMF", {ifMatch: eTag});
updateExpenseParameters

Updates the ExpenseParameters record for a company.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
payloadExpenseParametersYesThe fields to update.
headersUpdateExpenseParametersHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: ExpenseParameters|error

Sample code:

expense:ExpenseParameters result = check fo->updateExpenseParameters(
"USMF",
{postImmediately: "Yes"},
{ifMatch: eTag}
);

Expense Rates

listExpenseRates

Lists ExpenseRate records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListExpenseRatesQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: ExpenseRatesCollection|error

Sample code:

expense:ExpenseRatesCollection result = check fo->listExpenseRates(
queries = {
filter: "currency eq 'USD'",
orderby: "expense asc"
}
);
createExpenseRates

Creates a new ExpenseRate.

Parameters:

NameTypeRequiredDescription
payloadExpenseRateYesThe ExpenseRate record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: ExpenseRate|error

Sample code:

expense:ExpenseRate payload = {
dataAreaId: "USMF",
expense: "MEALS",
description: "Standard meal rate",
rate: 45.00,
currency: "USD",
rateIAmountsIncludeSalesTax: "No"
};
expense:ExpenseRate result = check fo->createExpenseRates(payload);
getExpenseRates

Retrieves a single ExpenseRate by its key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expensestringYesThe expense key field, e.g. "MEALS".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetExpenseRatesQueriesNoOData query options: expand, 'select.

Returns: ExpenseRate|error

Sample code:

expense:ExpenseRate result = check fo->getExpenseRates("USMF", "MEALS");
deleteExpenseRates

Deletes a specific ExpenseRate.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expensestringYesThe expense key field to delete.
headersDeleteExpenseRatesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteExpenseRates("USMF", "MEALS", {ifMatch: eTag});
updateExpenseRates

Updates a specific ExpenseRate.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expensestringYesThe expense key field to update.
payloadExpenseRateYesThe fields to update.
headersUpdateExpenseRatesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: ExpenseRate|error

Sample code:

expense:ExpenseRate result = check fo->updateExpenseRates(
"USMF",
"MEALS",
{rate: 48.00},
{ifMatch: eTag}
);

Expenses

listExpenses

Lists Expenses (expense transaction) records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListExpensesQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: ExpensesCollection|error

Sample code:

expense:ExpensesCollection result = check fo->listExpenses(
queries = {
filter: "approvalStatus eq 'Submitted'",
top: 25,
'select: "expenseTransactionNumber,expenseCategory,amount,currency,merchant"
}
);
createExpenses

Creates a new Expenses (expense transaction) record.

Parameters:

NameTypeRequiredDescription
payloadExpensesYesThe Expenses record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: Expenses|error

Sample code:

expense:Expenses payload = {
dataAreaId: "USMF",
expenseTransactionNumber: "EXP-000456",
expenseCategory: "Meals",
expenseType: "Meals",
amount: 58.75,
currency: "USD",
transactionDate: "2026-08-01",
merchant: "Downtown Bistro",
employeePersonnelNumber: "000182",
purpose: "Client dinner"
};
expense:Expenses result = check fo->createExpenses(payload);
getExpenses

Retrieves a single Expenses record by its key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseTransactionNumberstringYesThe expense transaction number key field, e.g. "EXP-000456".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetExpensesQueriesNoOData query options: expand, 'select.

Returns: Expenses|error

Sample code:

expense:Expenses result = check fo->getExpenses("USMF", "EXP-000456");
deleteExpenses

Deletes a specific Expenses record.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseTransactionNumberstringYesThe expense transaction number key field to delete.
headersDeleteExpensesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteExpenses("USMF", "EXP-000456", {ifMatch: eTag});
updateExpenses

Updates a specific Expenses record.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseTransactionNumberstringYesThe expense transaction number key field to update.
payloadExpensesYesThe fields to update.
headersUpdateExpensesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: Expenses|error

Sample code:

expense:Expenses result = check fo->updateExpenses(
"USMF",
"EXP-000456",
{approvalStatus: "Approved"},
{ifMatch: eTag}
);

Mileage Rates

listMileageRates

Lists MileageRate records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListMileageRatesQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: MileageRatesCollection|error

Sample code:

expense:MileageRatesCollection result = check fo->listMileageRates(
queries = {
filter: "rateType eq 'Mileage' and vehicleType eq 'Car'",
orderby: "fromDate desc"
}
);
createMileageRates

Creates a new MileageRate.

Parameters:

NameTypeRequiredDescription
payloadMileageRateYesThe MileageRate record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: MileageRate|error

Sample code:

expense:MileageRate payload = {
dataAreaId: "USMF",
description: "Standard car mileage rate",
expenseCategory: "Mileage",
rate: 0.67,
vehicleType: "Car",
quantity: 0,
fromDate: "2026-01-01",
toDate: "2026-12-31",
rateType: "Mileage"
};
expense:MileageRate result = check fo->createMileageRates(payload);
getMileageRates

Retrieves a single MileageRate by its composite key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseCategorystringYesThe expense category key field, e.g. "Mileage".
fromDatestringYesThe rate's effective start date key field.
quantitydecimalYesThe quantity (distance tier) key field.
rateTypestringYesThe rate type key field, e.g. "Mileage" or "Passenger".
vehicleTypestringYesThe vehicle type key field, e.g. "Car".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetMileageRatesQueriesNoOData query options: expand, 'select.

Returns: MileageRate|error

Sample code:

expense:MileageRate result = check fo->getMileageRates(
"USMF",
"Mileage",
"2026-01-01",
0,
"Mileage",
"Car"
);
deleteMileageRates

Deletes a specific MileageRate.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseCategorystringYesThe expense category key field.
fromDatestringYesThe rate's effective start date key field.
quantitydecimalYesThe quantity (distance tier) key field.
rateTypestringYesThe rate type key field.
vehicleTypestringYesThe vehicle type key field.
headersDeleteMileageRatesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteMileageRates(
"USMF",
"Mileage",
"2026-01-01",
0,
"Mileage",
"Car",
{ifMatch: eTag}
);
updateMileageRates

Updates a specific MileageRate.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
expenseCategorystringYesThe expense category key field.
fromDatestringYesThe rate's effective start date key field.
quantitydecimalYesThe quantity (distance tier) key field.
rateTypestringYesThe rate type key field.
vehicleTypestringYesThe vehicle type key field.
payloadMileageRateYesThe fields to update.
headersUpdateMileageRatesHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: MileageRate|error

Sample code:

expense:MileageRate result = check fo->updateMileageRates(
"USMF",
"Mileage",
"2026-01-01",
0,
"Mileage",
"Car",
{rate: 0.70},
{ifMatch: eTag}
);

Per Diems

listPerDiems

Lists PerDiems records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListPerDiemsQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: PerDiemsCollection|error

Sample code:

expense:PerDiemsCollection result = check fo->listPerDiems(
queries = {
filter: "countryRegionId eq 'USA'",
'select: "location,stateId,mealAllowance,hotelAllowance,dateFrom,dateTo"
}
);
createPerDiems

Creates a new PerDiems record.

Parameters:

NameTypeRequiredDescription
payloadPerDiemsYesThe PerDiems record to create.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: PerDiems|error

Sample code:

expense:PerDiems payload = {
dataAreaId: "USMF",
location: "Seattle",
stateId: "WA",
countryRegionId: "USA",
dateFrom: "2026-01-01",
dateTo: "2026-12-31",
currency: "USD",
mealAllowance: 65.00,
hotelAllowance: 180.00,
otherAllowance: 10.00
};
expense:PerDiems result = check fo->createPerDiems(payload);
getPerDiems

Retrieves a single PerDiems record by its composite key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
locationstringYesThe location key field, e.g. "Seattle".
stateIdstringYesThe state key field, e.g. "WA".
countryRegionIdstringYesThe country/region key field, e.g. "USA".
dateFromstringYesThe validity start date key field.
dateTostringYesThe validity end date key field.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetPerDiemsQueriesNoOData query options: expand, 'select.

Returns: PerDiems|error

Sample code:

expense:PerDiems result = check fo->getPerDiems(
"USMF",
"Seattle",
"WA",
"USA",
"2026-01-01",
"2026-12-31"
);
deletePerDiems

Deletes a specific PerDiems record.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
locationstringYesThe location key field.
stateIdstringYesThe state key field.
countryRegionIdstringYesThe country/region key field.
dateFromstringYesThe validity start date key field.
dateTostringYesThe validity end date key field.
headersDeletePerDiemsHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deletePerDiems(
"USMF",
"Seattle",
"WA",
"USA",
"2026-01-01",
"2026-12-31",
{ifMatch: eTag}
);
updatePerDiems

Updates a specific PerDiems record.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
locationstringYesThe location key field.
stateIdstringYesThe state key field.
countryRegionIdstringYesThe country/region key field.
dateFromstringYesThe validity start date key field.
dateTostringYesThe validity end date key field.
payloadPerDiemsYesThe fields to update.
headersUpdatePerDiemsHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: PerDiems|error

Sample code:

expense:PerDiems result = check fo->updatePerDiems(
"USMF",
"Seattle",
"WA",
"USA",
"2026-01-01",
"2026-12-31",
{mealAllowance: 70.00},
{ifMatch: eTag}
);

Trv Receipts

listTrvReceipts

Lists TrvReceiptEntity (travel receipt) records, with optional OData query support.

Parameters:

NameTypeRequiredDescription
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesListTrvReceiptsQueriesNoOData query options: skip, top, filter, orderby, expand, crossCompany, count, 'select.

Returns: TrvReceiptsCollection|error

Sample code:

expense:TrvReceiptsCollection result = check fo->listTrvReceipts(
queries = {
filter: "isCreditCardExpense eq 'No'",
'select: "documentId,name,fileName,fileType"
}
);
createTrvReceipts

Creates a new TrvReceiptEntity (travel receipt), including the receipt's binary file content.

Parameters:

NameTypeRequiredDescription
payloadTrvReceiptEntityYesThe TrvReceiptEntity record to create, including the fileContents attachment.
headersmap<string|string[]>NoOptional HTTP headers to include in the request.

Returns: TrvReceiptEntity|error

Sample code:

byte[] receiptBytes = check io:fileReadBytes("./receipt.pdf");
expense:TrvReceiptEntity payload = {
dataAreaId: "USMF",
documentId: "RCPT-000789",
'resource: 1,
name: "Taxi receipt",
fileName: "receipt.pdf",
fileType: "pdf",
isCreditCardExpense: "No",
fileContents: {
fileContent: receiptBytes,
fileName: "receipt.pdf"
}
};
expense:TrvReceiptEntity result = check fo->createTrvReceipts(payload);
getTrvReceipts

Retrieves a single TrvReceiptEntity by its key.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
documentIdstringYesThe document ID key field, e.g. "RCPT-000789".
headersmap<string|string[]>NoOptional HTTP headers to include in the request.
queriesGetTrvReceiptsQueriesNoOData query options: expand, 'select.

Returns: TrvReceiptEntity|error

Sample code:

expense:TrvReceiptEntity result = check fo->getTrvReceipts("USMF", "RCPT-000789");
deleteTrvReceipts

Deletes a specific TrvReceiptEntity.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
documentIdstringYesThe document ID key field to delete.
headersDeleteTrvReceiptsHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: error?

Sample code:

check fo->deleteTrvReceipts("USMF", "RCPT-000789", {ifMatch: eTag});
updateTrvReceipts

Updates a specific TrvReceiptEntity.

Parameters:

NameTypeRequiredDescription
dataAreaIdstringYesThe company data area identifier.
documentIdstringYesThe document ID key field to update.
payloadTrvReceiptEntityYesThe fields to update.
headersUpdateTrvReceiptsHeadersNoOptional headers. Set ifMatch to the entity's current ETag for optimistic concurrency.

Returns: TrvReceiptEntity|error

Sample code:

expense:TrvReceiptEntity result = check fo->updateTrvReceipts(
"USMF",
"RCPT-000789",
{notes: "Re-submitted after manager rejection"},
{ifMatch: eTag}
);