Hello Team,

if you are developing one App for several cloud Business Central tenants and still publishing it with "Upload Extension" action - my post for you.

You know that Business Central (and NAV 2018) has standard APIs. But you could do more than only create-delete-modify records in tables.

Business central has special group of APIs named "automation".

Let's check them.

First of all - construct correct URL.

For SAAS Business Central it will be:

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/$metadata

Environment name is Sandbox name or "Production" for prod environment (default name, could be changed in some cases).

So my URL looks this way:

https://api.businesscentral.dynamics.com/v2.0/abaludin.onmicrosoft.com/springsandbox/api/microsoft/automation/v1.0/$metadata

Open Postman (or any other REST client) and execute GET request, using Basic Authentication with your User name as login and Web Access Key as a password:

You'll get full list of Business Central Complex types and automation entities. You can see that with them you're able to install/uninstall existing extensions, use configuration packages, upload and install new apps, get list of extensions and check their installation status.

Wonderful.

Now for example, let's get list of your extensions.

Get companies list with next URL:

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/companies

copy ID of needed company and get it:

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/companies(<<COMPANY ID>>)

and now get the extensions list

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/companies(<<COMPANY ID>>)/extensions

That's how it works.

Now I want to publish my existing *.app file to this sandbox.

URL will be:

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/companies(<<COMPANY ID>>)/extensionUpload(0)/content

and you need to change method to PATCH and add next headers:

Content-Type - application/octet-stream

If-Match - *

Now click on Body tab, select "Binary" type, click on select file button and choose your *.app file. Press "Send" - you should get status 204 "No Content"

Yeah, app has been published, but are you sure?

Let's check installation status.

use next URL:

https://api.businesscentral.dynamics.com/v2.0/<<DOMAIN OR TENANT ID>>/<<ENVIRONMENT NAME>>/api/microsoft/automation/v1.0/companies(<<COMPANY ID>>)/extensionDeploymentStatus

Don't forget to change method to GET and set Body to "none". Execute request:

My app's installation status is "InProgress". That's ok. When you execute it a bit later - you'll get "Completed" or "Failed" status.

Completed means that you could relax, Failed means that you need to open your environment and check what happened manually on extensions -> Installation status page.

Now you could ask me - Andrey, that's cool feature but it looks a bit useless. Am I need to open Postman each time I want to deploy my app without VS Code?

Of course not. I care about you and don't want to force you to make extra clicks. We will publish app to multiple environments directly from VS Code.

I have next frequent situation. I'm developer. Project has production tenant and 2 sandboxes. One for me - for active development. And one for my consultant who becomes very angry when gets "Administrator made changes" error each 5 minutes. After preparing new version of app, i need to publish it to other sandbox and production tenant. And I don't want to do extra clicks.

Install Rest Client extension to you VS Code:

and create AppManagement.rest file in your project.

Code of file:

@username = YOUR-USER-NAME
@password = YOUR-WEB-ACCESS-KEY
@tenantid = YOUR-DOMAIN-OR-TENANT-ID
@productionname = production
@sandboxname = YOUR-SANDBOX-NAME
@companyid = YOUR-COMPANY-ID
@appname = YOR-APP-FILE-NAME

### Prod Publish

PATCH https://api.businesscentral.dynamics.com/v2.0/{{tenantid}}/{{productionname}}/api/microsoft/automation/v1.0/companies({{companyid}})/extensionUpload(0)/content
Authorization: Basic {{username}} {{password}}
If-Match: *
Content-Type: application/octet-stream

< .\{{appname}}

### Prod Check Status

GET https://api.businesscentral.dynamics.com/v2.0/{{tenantid}}/{{productionname}}/api/microsoft/automation/v1.0/companies({{companyid}})/extensionDeploymentStatus
Authorization: Basic {{username}} {{password}}

### Sandbox Publish

PATCH https://api.businesscentral.dynamics.com/v2.0/{{tenantid}}/{{sandboxname}}/api/microsoft/automation/v1.0/companies({{companyid}})/extensionUpload(0)/content
Authorization: Basic {{username}} {{password}}
If-Match: *
Content-Type: application/octet-stream

< .\{{appname}}

### Sandbox Check Status

GET https://api.businesscentral.dynamics.com/v2.0/{{tenantid}}/{{sandboxname}}/api/microsoft/automation/v1.0/companies({{companyid}})/extensionDeploymentStatus
Authorization: Basic {{username}} {{password}}

My file looks this way you could find ti attached below:

Then you create it - you'll see that action "Send Request" appears near each request.

After creation of new app version - just change @appname parameter and click on send request of publishing and after that on Checking status.

You could add to this file unlimited quantity of environments and simply publish your new app version to numbers of them with 2 clicks.

Standard APIs are perfect tool.

Hope my experience was useful for you!