This guide documents the API needed for Shiptheory to download shipments from Microsoft Dynamics 365 Business Central.


  1. OAuth Access Tokens
  2. Company Information via ODatav4
  3. Warehouse Location via ODatav4
  4. Warehouse Shipment via ODatav4
  5. Shipment Status Update via ODatav4
  6. User List for Channel User Printing (Optional)


Please implement them in Business Central, example AL codes are given here:


1 - OAuth Access Token

HTTP – POST

https://login.microsoftonline.com/TENANTID/oauth2/v2.0/token


This API is provided by Microsoft to authenticate all application access. All requests made by Shiptheory will have a Bearer Token obtained set in the header.


Body – Form Data


KeyValue
client_id

The one generated in the Azure Portal

client_secret

The one generated in the Azure Portal

scope

https://api.businesscentral.dynamics.com/.default

grant_typeclient_credentials


Response


{

    "token_type": "Bearer",

    "expires_in": 3599,

    "ext_expires_in": 3599,

    "access_token": "XXXX"

}


2- Company Information via ODatav4

HTTP – GET

https://api.businesscentral.dynamics.com/v2.0/TENANT_ID/Sandbox/ODataV4/Company('COMPANY_ID')/


Shiptheory uses this API as part of a connection test. Replace the Tenant ID, environment string (Sandbox or Production), and Company ID (e.g. Demo - ABC) with yours in the above. When a request is made, the company ID will be URL-encoded.


Parameters: Company ID


Body – Form Data


KeyValue
Authorization

Bear access_token from 1 - OAuth Access Token

Content-Type

application/json

Accept

application/json

If-Match*


Response


{

    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/TENANTID/ODataV4/$metadata#Company/$entity",

    "Name": "Demo Company",

    "timestamp": 1525918,

    "Evaluation_Company": true,

    "Display_Name": "Demo Co",

    "Id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",

    "Business_Profile_Id": "",

    "SystemCreatedAt": "0001-01-01T00:00:00Z",

    "SystemCreatedBy": "00000000-0000-0000-0000-000000000000",

    "SystemModifiedAt": "0001-01-01T00:00:00Z",

    "SystemModifiedBy": "00000000-0000-0000-0000-000000000000"

}


3- Warehouse Location via ODatav4

HTTP – GET

To return a warehouse location:

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryLocations(‘LOCATIONID’)


To return a list of warehouse locations:

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryLocations


Shiptheory uses this API to get the warehouse address for shipment rather than the default Shipment Location set in the Shiptheory website’s UI. This is enabled in the channel setting page.


Parameters

Location ID: Warehouse location code e.g. MAIN


Body – Form Data


KeyValue
Authorization

Bear access_token from 1 - OAuth Access Token

Content-Type

application/json

Accept

application/json

If-Match*


Response


{

    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/$metadata#Company('Demo%20ABC')/shiptheoryLocations/$entity",

    "@odata.etag": "xxx",

    "code": "MAIN",

    "name": "Main Warehouse",

    "address": "4.1 Paintworks",

    "address2": "Bath Road",

    "city": "Bristol",

    "county": "",

    "postCode": "BS4 3EH",

    "countryRegionCode": "GB",

    "phoneNo": "+44-(0)12 1234 1234",

    "email": ""

}


4- Warehouse Shipment via ODatav4

HTTP – GET

For Warehouse Shipment:

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryWhseShipments?$filter=QUERY_STRING


For Posted Warehouse Shipment:

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryPostedWhseShipmentsQuery?$filter=QUERY_STRING


Shiptheory uses this API to search for Warehouse Shipment.


Please return an empty array ([]) for value in your response if there is no matching shipment filtered by the QUERY_STRING. e.g.


{

    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/$metadata#Company('Demo%20ABC')/shiptheoryWhseShipments",

    "value": []

}


Parameters

Example 1 - To download a shipment

QUERY_STRING =whseShipmentNo eq 'WSHIP-000001'  and sourceNo eq 'SO-00001' and status eq 'Released'


Example 2 - During our shipments discovery we will use the following query string. Note that we both use 'status' and 'shiptheoryStatus' so that we do not download the same shipment over and over again:

QUERY_STRING=status eq 'Released' and shiptheoryStatus ne 'Booked' and shiptheoryStatus ne 'In Progress' and shiptheoryStatus ne 'Queued'


Body – Form Data


KeyValue
Authorization

Bear access_token from 1 - OAuth Access Token

Content-Type

application/json

Accept

application/json

If-Match*


Response


{

    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/$metadata#Company('Demo%20ABC')/shiptheoryWhseShipments",

    "value": [

        {

            "systemIdWhseShipmentHeader": "xxxxxxxx-8506-ed11-82f8-0022480097ae",

            "whseShipmentNo": "WSHIP-000001",

            "status": "Released",

            "shipmentDate": "2019-09-17",

            "shippingAgentCode": "FEDEX",

            "shippingAgentServiceCode": "NEXT DAY",

            "locationCode": "MAIN",

            "systemIdWhseShipmentLine": "xxxxxxxx-8506-ed11-82f8-0022480097ae",

            "sourceNo": "101002",

            "lineNo": 10000,

            "itemNo": "1968-S",

            "description": "MEXICO Swivel Chair, black",

            "quantity": 10,

            "qtyToShip": 10,

            "qtyShipped": 0,

            "unitOfMeasureCode": "PCS",

            "shiptheoryPTR": "",

            "shiptheoryStatus": "Queued",

            "systemIdSalesOrder": "xxxxxxxx-a0e2-4bf7-97b7-f057cc6bfbd2",

            "shipToName": "Centennial Hotel",

            "shipToAddress": "63-71 Hills Rd",

            "shipToAddress2": "",

            "shipToCity": "Cambridge",

            "shipToCounty": "",

            "shipToPostCode": "CB2 1PG",

            "shipToCountryCode": "GB",

            "sellToEmail": "reception@centennialhotel.co.uk",

            "sellToPhoneNo": "",

            "sellToVATRegistrationNo": "GB111111111",

            "countryOfOriginCode": "",

            "weightPerUOM": 7,

            "heightPerUOM": 150,

            "widthPerUOM": 100,

            "lengthPerUOM": 90,

            "cubagePerUOM": 1350000,

            "commodityCode": "",

            "commodityCodeDescription": "",

            "AuxiliaryIndex1": "WSHIP-000001",

            "AuxiliaryIndex2": "Order",

            "AuxiliaryIndex3": "101002",

            "AuxiliaryIndex4": "1968-S",

            "AuxiliaryIndex5": "1968-S",

            "AuxiliaryIndex6": "PCS"

        },

    ..

    ]

}


Payload field details


The following table summarizes the meaning of each field in the payload:


Field

Meaning

Sample values

systemIdWhseShipmentHeader

The internal primary key for Warehouse Shipment

xxxxxxxx-8506-ed11-82f8-0022480097ae

whseShipmentNo

Warehouse Shipment ID that you can find in Business Central

WSHIP-000001

status

Warehouse Shipment Status, valid values are Released, Open

Released

shipmentDate

Shipment Date

2019-09-17

shippingAgentCode

Carrier Name

FEDEX

shippingAgentServiceCode

Carrier Service

NEXT DAY

locationCode

Location Code. Shiptheory will take this to look up the warehouse address in a separate requested

MAIN

systemIdWhseShipmentLine

The internal primary key for Warehouse Shipment Line. It is also the line for a particular item being sold (per item). It has different values for different items in the same order.

xxxxxxxx-8506-ed11-82f8-0022480097ae

sourceNo

Sales Order ID

101002

lineNo

Line No in a Sale Order

10000

itemNo

Item No for the product being sold

1968-S

description

Item Description

MEXICO Swivel Chair, black

quantity

Quantity in the sale order

10

Shiptheory ignores this field and uses qtyToShip to determine the quantity

qtyToShip

Quantity being shipped in this shipment

10

qtyShipped


0

unitOfMeasureCode

Unit of Measure Code. e.g. PCS, BOX

PCS

shiptheoryPTR

Carrier Tracking Number, to be filled in by Shiptheory


shiptheoryStatus

Shipment Status is to be filled in by Shiptheory. Valid values are Queued, In Progress, Booked

Queued

systemIdSalesOrder

The internal primary key for Sales Order

xxxxxxxx-a0e2-4bf7-97b7-f057cc6bfbd2

shipToName

Name of receiver

Centennial Hotel

shipToAddress

Address 1 of the receiver

63-71 Hills Rd

shipToAddress2

Address 2 of the receiver


shipToCity

City of receiver

Cambridge

shipToCounty

County of receiver

Bristol

shipToPostCode

The Postal Code of the receiver

CB2 1PG

shipToCountryCode

Country Code of receiver

GB

sellToEmail

Email of receiver

reception@centennialhotel.co.uk

sellToPhoneNo

Phone number of receiver


sellToVATRegistrationNo

VAT number of receiver

GB111111111

countryOfOriginCode

Country Code of original for custom purpose


weightPerUOM

Weight per UOM

7,

heightPerUOM

height Per UOM

150,

widthPerUOM

width Per UOM

100,

lengthPerUOM

length Per UOM

90,

cubagePerUOM

cubage Per UOM

1350000,

commodityCode

Commodity Code


commodityCodeDescription

Commodity Code Description


AuxiliaryIndex1

Not used currently

WSHIP-000001

AuxiliaryIndex2

Not used currently

Order

AuxiliaryIndex3

Not used currently

101002

AuxiliaryIndex4

Not used currently

1968-S

AuxiliaryIndex5

Not used currently

1968-S

AuxiliaryIndex6

Not used currently

PCS


5 - Shipment Status Update via ODatav4

HTTP – PUT / PATCH


This is for updating the Shiptheory package tracking and shipment status. Please refer to the shipment status section for more information. Notice different VERB is used for different shipment types (PUT vs PATCH)


It is very important you implemented this properly as this prevents Shiptheory from downloading the same shipment over and over again. If there is an error in updaing the shpiment's 'shiptheoryStatus', you should be able to see the error messaage it in Shipment Message within Shiptheory.


For Warehouse Shipment - PUT

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryWarehouseShipmentLine(systemIdWhseShipmentLine)


e.g. …/shiptheoryWarehouseShipmentLine(ddb86f8b-c0ba-ee22-a56a-6045bdd0821d)


For Post Warehouse Shipment - PATCH

https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/Company('COMPANYID')/shiptheoryPostedWarehouseShipments(no=’whseShipmentNo’)


e.g. …/shiptheoryPostedWarehouseShipments(no='PWS34815')


Shiptheory uses this API to update to update the Shipment status, and tracking number returned by Carrier


Parameters

For Warehouse Shipment

systemIdWhseShipmentLine: The unique key for the warehouse shipment line


For Post Warehouse Shipment

whseShipmentNo: The posted warehouse shipment no


shiptheoryPTR: Tracking Number

shiptheoryStatus: Shipment Status


Request - JSON

Shiptheory will send a PUT request to update the status of the Post Warehouse Shipment, or sale line of Warehouse Shipment (an item in a Sale Order) with this format as an example:


{

    "shiptheoryStatus": "Booked",

    "shiptheoryPTR": "T123456789"

}


Response - JSON - Example of Warehouse Shipment


{

    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/TENANTID/Sandbox/ODataV4/$metadata#Company('Demo%20ABC)/shiptheoryWarehouseShipmentLine/$entity",

    "@odata.etag": "xxxx",

    "systemId": "c5fb6d6a-8506-ed11-82f8-0022480097ae",

    "no": "WSHIP-000001",

    "lineNo": 20000,

    "sourceNo": "101002",

    "sourceLineNo": 20000,

    "itemNo": "1928-S",

    "description": "AMSTERDAM Lamp",

    "shiptheoryPTR": "",

    "shiptheoryStatus": ""

}


6 - User List for Channel User Printing

HTTP – GET

https://api.businesscentral.dynamics.com/v2.0/Sandbox/api/microsoft/automation/v2.0/companies(COMPANY_ID)/users


Upon the saving of the setting page, Shiptheory will retrieve a list of user to enable the Channel User Printing feature. Your shipment will still be downloaded if this API is not available to Shiptheory.


To learn more about User-Specific Printing, please read it here: Sales Channel User-Specific Printing.


To learn more about the above user listing API, please read it here: Microsoft Business Central user resource type.


Parameters:

COMPANY_ID in the form of "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx". Shiptheory will retrieve the COMPANY_ID  from the "Company Information" endpoint above.


We will fetch the user with state = "Enabled", please also make sure userName, displyName and userSecurityId are non-empty.


Response - JSON

{

    "userSecurityId": "GUID",

    "userName": "katy",

    "displayName": "Katy Burgess",

    "state": "Enabled",

    "expiryDate": "datetime"

}