Breadcrumbs

Wisefish APIs - Usage

Summary:

  • To read all entries use GET

  • To read one specific entry use GET(id)

  • To create a new entry use POST + body with (all) properties

  • To update an existing entry use PATCH(id) + eTag + body with properties to update

  • To delete an existing entry use DELETE(id)


Overview

Contents

The contents of the APIs are selected as the most important fields in Wisefish. They should fulfill the needs for most users, but anyway in most tables there are more fields that do not have a property in the API.

Record ID

When interacting with specific records (e.g., a particular customer, item, or sales order), the record's unique ID is included in the URL to identify it.
For example, to retrieve a specific purchase agreement, the URL would include the agreement's ID:

<https://{businesscentralPrefix}/api/wisefish/base/v1.0/companies({companyId})/purchaseAgreements({agreementId})>

Where {agreementId} is the GUID of the agreement entry.
Similarly, for operations like deleting or updating a record, the record's ID is essential in the URL to target the correct entry.

In some cases, for better usability, the primary key of the entry could be used as a record ID, but not the GUID. The documentation mentions which field is used as a record ID.

Validating Data

When updating data, the API properties act in a very similar way as the fields on the pages within BC/Wisefish. The error handling that takes place when a user validates a field in Wisefish, is exactly the same as when the same field is populated with the API. The field order of the API will control the order of which fields are validated into the table. Changing the order of the payload (body object) will not have affect on how the fields are validated into the record.

Procedure Endpoints

There are also some specific procedure endpoints that modify data. They can have additional error handling and therefore return a runtime error (400) so that no entry is created in the database. Therefore these methods can safely be used when there is a human being watching the response.

Using these API procedures is not recommended for integration with production systems. In that case, it is usually better to use the inbound integration queue.
See: External Production API - User Documentation

Reading data (GET)

Request all entries

Data is retrieved with a GET request where the URL is is combined as follows:

JSON
GET
[server]/api/wisefish/base/v1.0/companies([CompanyGUID])/[endpoint]

Response

The data should be read from the value property of the returned object. It will be an array of JSON objects, where each object has all the properties in this particular API page.

JSON
{
    "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items",
    "value": [the array of objects]
}


Example:
To get all the items exposed by the API from the environment BC24BjarteyW1CU1rest on the containers.wisefish.com:

https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items

The data is returned as JSON.

{
    "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items",
    "value": [
        {
            "@odata.etag": "W/\"JzIwOzEwNTMxOTAxNzk1NTEwMjk4MDc4MTswMDsn\"",
            "id": "00684ed0-9ea1-ef11-b017-aa2d6f3d6955",
            "no": "0900",
            "description": "Þorskflök",
            "packageDescriptionType": "Trade Item",
            "packageDescription": "1 x 10",
            "tradeItemType": "Product",
            "itemCategoryCode": "FISH-PROD",
            "rawMaterialReportingCode": "001",
            "inventoryPostingGroup": "FINISHED",
            "blocked": false,
            "status": " ",
            "baseUnitOfMeasure": "KG",
            "tradeItemUnitOfMeasure": "BOX",
            "palletUnitOfMeasure": "PALLET",
            "weightUnitOfMeasure": "KG",
            "unitPrice": 7.5,
            "priceIncludesTax": false,
            "unitCost": 5,
            "lastModifiedDateTime": "2025-11-12T17:32:20.743Z"
        },
        {
            "@odata.etag": "W/\"JzIwOzE0MTEzNjQxMTU1MTg5MDQ5MTAzMTswMDsn\"",
            "id": "234fffc2-dd11-ef11-9f8b-6045bde9cc61",
            "no": "1000",
            "description": "Bicycle",
            "packageDescriptionType": " ",
            "packageDescription": "",
            "tradeItemType": " ",
            "itemCategoryCode": "",
            "rawMaterialReportingCode": "",
            "inventoryPostingGroup": "FINISHED",
            "blocked": false,
            "status": " ",
            "baseUnitOfMeasure": "PCS",
            "tradeItemUnitOfMeasure": "",
            "palletUnitOfMeasure": "",
            "weightUnitOfMeasure": "",
            "unitPrice": 4000,
            "priceIncludesTax": false,
            "unitCost": 350.594,
            "lastModifiedDateTime": "2025-07-21T11:19:01.34Z"
        }
  ]
}


Request a single entry

To request a specific entry, the user must know the record ID of that particular entry. The documentation for each endpoint should say which field is used as a record id.
In this case, it can be read from the property id when entries are retrieved with GET.

JSON
GET
[server]/api/wisefish/wiFiEP/v1.0/companies([CompanyGUID])/[endpoint]([recordID])


Response

The response will be a JSON object, with all the properties of this particular API object, looking like this

JSON
{
  "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies([companyId])/[endpoint]/$entity",
  "@odata.etag": [etag],
  "id" : the requested id,
  property 1,
  property 2,
  etc....
}


Example:
To get the item with system ID = 00684ed0-9ea1-ef11-b017-aa2d6f3d6955:

https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items(00684ed0-9ea1-ef11-b017-aa2d6f3d6955)

Response:

{
  "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items/$entity",
  "@odata.etag": "W/\"JzIwOzEwNTMxOTAxNzk1NTEwMjk4MDc4MTswMDsn\"",
  "id": "00684ed0-9ea1-ef11-b017-aa2d6f3d6955",
  "no": "0900",
  "description": "Þorskflök",
  "packageDescriptionType": "Trade Item",
  "packageDescription": "1 x 10",
  "tradeItemType": "Product",
  "itemCategoryCode": "FISH-PROD",
  "rawMaterialReportingCode": "001",
  "inventoryPostingGroup": "FINISHED",
  "blocked": false,
  "status": " ",
  "baseUnitOfMeasure": "KG",
  "tradeItemUnitOfMeasure": "BOX",
  "palletUnitOfMeasure": "PALLET",
  "weightUnitOfMeasure": "KG",
  "unitPrice": 7.5,
  "priceIncludesTax": false,
  "unitCost": 5,
  "lastModifiedDateTime": "2025-11-12T17:32:20.743Z"
}

Show child entries

For some APIs there are child entries. To make them visible in the response, the expand URL parameter must be used:

JSON
GET
[server]/api/wisefish/wiFiEP/v1.0/companies([CompanyGUID])/[endpoint]([recordID])?$expand=[detailsAPI]

See example:

CLICK HERE to view the example

Example:
To get the item and - all the units - with record ID = 00684ed0-9ea1-ef11-b017-aa2d6f3d6955

https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/
                    itemDetails(00684ed0-9ea1-ef11-b017-aa2d6f3d6955)?$expand=unitsOfMeasure

Response:

{
  "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/itemDetails/$entity",
  "@odata.etag": "W/\"JzIwOzE3MDk0OTg5Mjk1NjExMTAyMTY1MTswMDsn\"",
  "id": "00684ed0-9ea1-ef11-b017-aa2d6f3d6955",
  "no": "0900",
  "no2": "",
  "gtin": "00000000000666",
  "description": "Þorskflök",
  "description2": "",
  "fullDescription": "Þorskflök ",
  "latinDescription": "",
  "type": "Inventory",
  "tradeItemType": "Product",
  "itemCategoryId": "33434031-7a14-f011-b01f-bdbc04fc3978",
  "itemCategoryCode": "FISH-PROD",
  "inventoryPostingGroupId": "abea13b1-dd11-ef11-9f8b-6045bde9cc61",
  "inventoryPostingGroup": "FINISHED",
  "taxGroupCode": "",
  "defaultStockCenterId": "04daea07-a0a1-ef11-b017-aa2d6f3d6955",
  "defaultStockCenter": "OWN",
  "blocked": false,
  "status": " ",
  "irregularTradeItem": false,
  "baseUnitOfMeasure": "KG",
  "qtyInBaseUnit": 1,
  "weightInBaseUnit": 1,
  "tradeItemUnitOfMeasure": "BOX",
  "qtyInTradeItemUnit": 10,
  "weightInTradeItemUnit": 10,
  "palletUnitOfMeasure": "PALLET",
  "qtyInPalletUnit": 1000,
  "weightInPalletUnit": 1000,
  "weightUnitOfMeasure": "KG",
  "purchUnitOfMeasure": "KG",
  "salesUnitOfMeasure": "KG",
  "unitPrice": 7.5,
  "priceIncludesTax": false,
  "unitCost": 5,
  "countryOfOrigin": "",
  "rawMaterial": "70064",
  "rawMaterialDescription": "Cod - raw material",
  "rawMaterialReportingCode": "001",
  "defaultRawMaterialState": "HEADED",
  "processingMethod": "FILLETED",
  "processingMethodDescription": "Filleted",
  "cutCode": "",
  "sizeGrade": "",
  "sizeGradeDescription": "",
  "qualityGrade": "",
  "qualityGradeDescription": "",
  "grossWeight": 1,
  "netWeight": 1,
  "palletNetWeight": 0,
  "lastModifiedDateTime": "2025-11-12T17:32:20.743Z",
  "itemUnits": [
    {
      "@odata.etag": "W/\"JzIwOzEyODc0Mjk1MTcwNzIwNTY4MTgxMTswMDsn\"",
      "id": "cd7e1ad7-9ea1-ef11-b017-aa2d6f3d6955",
      "itemNo": "0900",
      "code": "BOX",
      "qtyPerUnit": 10,
      "qtyRoundingPrecision": 0,
      "height": 0,
      "width": 0,
      "length": 0,
      "lastModifiedDateTime": "2024-11-13T09:13:54.54Z"
    },
    {
      "@odata.etag": "W/\"JzIwOzExNjY4MjM3NTgzMzAyNjA4MzQ4MTswMDsn\"",
      "id": "8ad920e0-9ea1-ef11-b017-aa2d6f3d6955",
      "itemNo": "0900",
      "code": "KG",
      "qtyPerUnit": 1,
      "qtyRoundingPrecision": 0,
      "height": 0,
      "width": 0,
      "length": 0,
      "lastModifiedDateTime": "2024-11-13T09:13:54.007Z"
    },
    {
      "@odata.etag": "W/\"JzIwOzExNDYyMjY3MDQ5MTY3MTE5MzUxMTswMDsn\"",
      "id": "cd1e2b9a-9fa1-ef11-b017-aa2d6f3d6955",
      "itemNo": "0900",
      "code": "LB",
      "qtyPerUnit": 0.45359237,
      "qtyRoundingPrecision": 0,
      "height": 0,
      "width": 0,
      "length": 0,
      "lastModifiedDateTime": "2024-11-13T09:13:54.54Z"
    },
    {
      "@odata.etag": "W/\"JzE5OzkyMzkxMzgwNjA5MTE2NDc1MTUxOzAwOyc=\"",
      "id": "ce1e2b9a-9fa1-ef11-b017-aa2d6f3d6955",
      "itemNo": "0900",
      "code": "PALLET",
      "qtyPerUnit": 1000,
      "qtyRoundingPrecision": 0,
      "height": 0,
      "width": 0,
      "length": 0,
      "lastModifiedDateTime": "2024-11-13T09:13:54.54Z"
    }
  ]
}



Filtering

A filter is added with $filter. An example of how a filter is added:

https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/itemUnitOfMeasures?$filter=itemNo eq '70070'



Modifying data

Create an entry (POST)

Data is created with a POST request where the body contains the properties for all entry fields to be populated:

JSON
POST
[server]/api/wisefish/wiFiEP/v1.0/companies([CompanyGUID])/[endpoint]

Body:
{[The input is a JSON object of the format the API expects. The names of the properties must match exactly the API.]}

Response

The response of a create request is a JSON object will all the properties of the object that was created. Same as when getting one entry.

CLICK to see an example of creating an entry with API

Example:
To create a customer, send in all the necessary field values:

POST
https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/customers

Body:
{
    "customerNo" : "C00013",
    "name": "John Smith",
    "addressLine1" : "Strandgata",
    "postalCode": "220",
    "city": "Hafnarfjordur",
    "country": "IS",
    "salespersonCode": "BS"
}

Response:

JSON
{
    "@odata.context": "https://containers.wisefish.com/BC/api/wisefish/base/v1.0/$metadata#companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/customers/$entity",
    "@odata.etag": "W/\"JzIwOzEwNjExODYzNDkzMDExNDE1NjY0MTswMDsn\"",
    "id": "2917c9b3-c9c3-f011-b029-8a429957c0db",
    "customerNo": "C00013",
    "name": "John Smith",
    "name2": "",
    "addressLine1": "Strandgata",
    "addressLine2": "",
    "postalCode": "220",
    "city": "Hafnarfjordur",
    "state": "",
    "country": "IS",
    "contact": "",
    "email": "",
    "salespersonCode": "BS",
    "currencyCode": "",
    "billToCustomerNo": "",
    "blocked": "_x0020_",
    "paymentMethodCode": "",
    "paymentTermsCode": "",
    "customerPostingGroup": "",
    "customerPriceGroup": "",
    "salesType": " ",
    "placeOfDelivery": "",
    "eulerID": "",
    "addRef": "",
    "paymentBankAccount": "",
    "ediCustomerCode": "",
    "lastModifiedDateTime": "2025-11-17T15:25:53.07Z"
}



Update an entry (PATCH)

Modifying entries with API requires the use of eTags. This is done to make sure user has the latest update of the data.

The updating process must be like this:

  1. Use GET to find out the current etag for the entry to updated: This is kept in property @odata.etag which is the second one on the response object.

  2. Use a PATCH request and

    1. set the value of @odata.etag on the key If-Match on the header

    2. set the properties to be updated in the body

JSON
GET the id and etag
{
   "@odata.etag": "W/\"JzExOzE7MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=\"",    // Example of an etag
   "id": "0c9e...",  // Example of an id
   "property1": "",
   "property2": "",
   ...
}


PATCH
[server]/api/wisefish/wiFiEP/v1.0/companies([CompanyGUID])/[endpoint]([recordID])
If-Match: W/"JzExOzE7MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA="

Body:
{
    properties to update
}

Response

The response of a patch request is a JSON object will all the properties of the object, not only the updated ones.

If PATCH fails, it is because one of the below:

✔ missing ETag
✔ invalid ETag
✔ trying to update a non-editable field

Note: POST can sometimes be used to update an existing entry, if the primary key is given, but this is not correct usage and not recommended because empty properties in the body will erase the current values of the entry.


Delete an entry (DELETE)

To delete an entry, use the record ID of the and do a DELETE request:

JSON
DELETE
[server]/api/wisefish/wiFiEP/v1.0/companies([CompanyGUID])/[endpoint]([recordID])

Response

This request does not have a response object or text. If it runs without error, the delete was a success.


Example:
To delete the item with record ID = 00684ed0-9ea1-ef11-b017-aa2d6f3d6955:

DELETE
https://containers.wisefish.com/BC24BjarteyW1CU1rest/api/wisefish/base/v1.0/companies(cf9f7b85-dd11-ef11-9f8b-6045bde9cc61)/items(00684ed0-9ea1-ef11-b017-aa2d6f3d6955)

Using procedures

For some endpoints, procedures have been added that are “service enabled”. This means that an additional endpoint will exist on the following URL format:

JSON
[server]/api/wisefish/base/v1.0/companies([CompanyGUID])/[endpoint]([recordID])/Microsoft.NAV.[procedureName]
  • These endpoints are only used with POST requests.

  • If the procedure has defined parameters, all of them must exist in the body.

  • They can be blank, if the procedure allows blank values.

Request is like this:

JSON
POST
https:/[server]/api/wisefish/base/v1.0/companies([CompanyGUID])/[endpoint]([recordID])/Microsoft.NAV.[procedureName]

Body:
{
    ...the parameters in the body, if the procedure has parameters
}