Introducing a better way to register webhooks for App Migrations

Hello Everyone,

We’re happy to announce that we just released App Migration Webhook in Connect Descriptor (rfc, MIG ticket)

You can now register webhooks by adding this entry in your Connect Descriptor:

  "cloudAppMigration": {
    "migrationWebhookPath" : "/<relative-url-to-baseUrl>"

Please see this DAC page for more info:


Hi, I am adding registration of webhook url via Connect Descriptor to our app. I have problem with this approach as it looks that webhook url is not being registered at all. I am installing application on my test instance using cloud descriptor pointing to my dev environment. I have deployed there application with updated cloud descriptor. Here it is how it looks like

  "key": "com.spartez.jira.plugins.bork.tfs4jira",
  "baseUrl": "",
  "name": "TFS4JIRA Cloud",
  "description": "Integrate Jira and Azure DevOps. Increase collaboration and agility.",
  "authentication": {
    "type": "jwt"
  "lifecycle": {
    "installed": "/installed",
    "enabled": "/app-enabled",
    "uninstalled": "/uninstalled"
  "apiMigrations": {
    "context-qsh": true,
    "gdpr": true,
    "signed-install": true
  "apiVersion": 101,
  "vendor": {
    "name": "Appfire",
    "url": ""
  "enableLicensing": true,
  "scopes": [
  "cloudAppMigration": {
    "migrationWebhookPath": "/app-migration/event"

Is there something wrong that I am doing? Just in case it would be related, the same migration endpoint was previously registered using Webhook API.

Hey Sebastian,

Happy to see the solution being tried out :slight_smile:

With regards to your concern, I’ve managed to checkout the descriptor by hitting this url:

I can see that you do have the following entry in the descriptor:

  "cloudAppMigration": {
    "migrationWebhookPath": "/app-migration/eventTwo"

I’ve tried out myself and it looks like the endpoint is returning a 401, I can verify that the webhook being used is from the descriptor. I hope this helps you out

Hi Clive,
Sorry for providing wrong endpoint in example. I have changed it recently for testing. I can see your request under " /app-migration/event" url. The case it that when I run migration from Server to Cloud I don’t receive any requests from under configured url. When I use Webhook API to register it, everything works correctly.
Is it possible that webhook is regsitered on your side but not used for some reason?

Hey Sebastian,

I’m seeing the following with 2 most recent transfers

transferId: …d3ee24
uses the webhook api
Resulted in 200 so it was successful

transferId: …2f246a
Uses Webhook in Connect descriptor
Resulted in 401

It looks likes 2 different endpoints are being used here. The /eventTwo seems to be not working returning a 401 and I couldn’t find anymore usages of except for that 1 transferId listed above, I can verify that the system identified it as a Webhook in Connect descriptor.

Do you have a more recent transferId where in you’re just using the Webhook in Connect descriptor that I could look into?

If I could guess a possible scenario, it could be that the migrationWebhookPath entry was no longer present during migration? For example, you initially installed the app containing the entry but updated it later on and the entry was no longer present. The entry migrationWebhookPath in the descriptor must remain present and the descriptor is used as the source of truth, if it’s no longer present during the installation we don’t consider it’s past installation or past value of the migrationWebhookPath entry

I have run one more migration yesterday. Here are details:
transferId: …d835d119
uses Webhook in Connect Descriptor

On my side, I don’t see any request coming to endpoint configured via Connect Descriptor.

Hey Sebastian,

For the transferId provided I can see that the Webhook in descriptor is indeed being picked up.

addOnKey=com.spartez.jira.plugins.bork.tfs4jira, baseUrl=, migrationWebhookPath=/app-migration/event

We can indeed verify that the calls are being made to the correct endpoint and it is rejecting the request we’re sending. This is retried multiple times and the response looks to be the same.

The response body:

<?xml version='1.0' encoding='UTF-8'?><Error><Code>AuthenticationRequired</Code><Message>Authentication required.</Message></Error>

Response status: 401

Are you seeing the 401 on your side? Let me know if this helps.

Hmm, so I found some requests coming from Atlassian. User agent on those requests is set to “Atlassian HttpClient unknown / JIRA-1001.0.0-SNAPSHOT (100232) / Atlassian-Connect/1001.0.0-SNAPSHOT”.
Those are hitting incorrect endpoint, endpoint in those requests is "". “tfs4jiraod” is missing from path. Response for those is in fact 401.

Hi Sebastian,

I think I’ve figured out what has been happening, I didn’t notice it previously but It’s because of the baseUrl not being an actual base url in a strict sense.

The way it’s being processed right now is we’re parsing the webhook into 2 parts:

so when we concatenated the other prefix coming from migrationWebhookPath the old prefix got replace as we’re now computing for relative url

My suggestion would be to simply have the following configuration:

    "baseUrl": "",
    "cloudAppMigration": {
        "migrationWebhookPath": "/tfs4jiraod/app-migration/event"

Hi Clive,
Is current behaviour of creating webhook url expected one or is it a bug? It sounds like a bug in my opinion. Lifecycle urls are correctly build based on “baseUrl” and “lifecycle” entries in descriptor.
I would expect the same behaviour for “migrationWebhookPath” field.

I can change path as you proposed. I think proper way to fix this issue would be to change behaviour on your side, to be consistent with how other endpoints are built.

Hey Sebastian,

You’re right, it would make sense to have the behavior the same as it would with the lifecycle entry. As such we’ve now deployed a fix for this. Let me know how it works out on your end :slight_smile:

I have tested it and it work correctly. Thanks for such quick fix release.

1 Like

Hi @CliveKarstenLim,

Is it now safe to remove the explicit registration via API (old method) if we migrated to descriptor registration? If not, do you maybe have an ETA?

Hello @lexek-92

Yes it should be safe to do so, the webhook in connect descriptor should be more reliable and our now suggested way of registering webhooks. One caveat on this is customers that hasn’t updated their Connect app in the cloud site would be getting errors as they’re still on an old descriptor that doesn’t have the webhook entry.

There’s currently no ETA for this as this would highly depend on when this was introduced to the app as well as customer’s adoption rate (updating the app to the version that has the entry). If you have detected that the webhook used via API is no longer being used for quite sometime then it would be safe to deprecate it.

Hope this makes sense.

Understood. If we’re feeling confident that it’s safe to remove explicitly registered webhooks, should we also actively unregister the webhooks from existing installations, or it doesn’t matter?

I’d say there’s more advantage to leaving it in as unregistering them on old existing installations that doesn’t have the new descriptor entry, will cause app migration to get stuck since your cloud app would never receive webhooks when they start migrating