Forge Dynamic Modules is now available as part of Forge’s Early Access Program (EAP). To start testing this, sign up here.
EAP features and APIs are unsupported, and subject to change without notice. Apps that use dynamic modules should not be deployed to production environments.
All dynamic modules created during EAP will not be carried over to Preview. For more details, see Forge EAP, Preview, and GA.
You can manage Dynamic Modules through its REST API. This API checks every request for OAuth authorisation to determine if it has permissions to access the target installation.
No OAuth 2.0 scopes are required.
You can configure a remote backend to call the Dynamic Module REST API. See Calling Atlassian app APIs from a remote.
Remote backends can only use asApp calls for dynamic module operations; asUser calls are not allowed. This means your remote backend will only be able to call the Dynamic Modules API as a generic bot user.
The Forge SDK code examples on this page use the requestAtlassian module, which is available from the @forge/api package.
This package module uses the app's credentials, determined by the scopes defined in the app's manifest.
Send a POST request to /forge/installation/v1/dynamic/module to register a dynamic module for the current app installation.
| Property | Type | Required? | Description |
|---|---|---|---|
key | string | Yes | The unique key of the target dynamic module on the installation |
type | string | Yes | The dynamic module being created (for example, use trigger to specify the Trigger module) |
data | map | Yes | The dynamic module's structure, but in JSON format (the payloads in the
Code examples use the Trigger module)
|
1 2import { requestAtlassian } from "@forge/api"; const payload = { key: "unique-module-key", type: "trigger", data: { key: "trigger-key", events: [ "avi:jira:updated:issue" ], "endpoint": "some-endpoint" } } const response = await requestAtlassian(`/forge/installation/v1/dynamic/module/`, { headers: { 'Content-Type': 'application/json' }, method: 'POST', body: JSON.stringify(payload), }); const body = await response.text(); console.log(`Response: ${response.status} ${body}`);
The dynamic module was successfully registered on the installation.
The request does not have permissions to access the target installation.
1 2{ "message": "Authorization failed" }
The Dynamic Module service encountered an unexpected problem.
1 2{ "message": "An internal error occurred" }
Send a PUT request to /forge/installation/v1/dynamic/module/<key> to update a dynamic module registered on the installation
(identified by the module's key).
| Property | Type | Required? | Description |
|---|---|---|---|
key | string | Yes | The unique key of the target dynamic module on the installation |
dynamicModuleRequest | map | Yes | Payload that defines the updated dynamic module |
The dynamicModuleRequest property requires the same properties as the registration request, as in:
| Property | Type | Required? | Description |
|---|---|---|---|
key | string | Yes | The unique key of the target dynamic module on the installation |
type | string | Yes | The dynamic module being created (for example, use trigger to specify the Trigger module) |
data | map | Yes | The dynamic module's structure, but in JSON format (the payloads in the
Code examples use the Trigger module)
|
1 2import { requestAtlassian } from "@forge/api"; const key = "unique-module-key"; const payload = { key: "unique-module-key", type: "trigger", data: { key: "trigger-key", events: [ "avi:jira:updated:issue" ], "endpoint": "some-endpoint" } } const response = await requestAtlassian(`/forge/installation/v1/dynamic/module/${key}`, { headers: { 'Content-Type': 'application/json' }, method: 'PUT', body: JSON.stringify(payload) }); const body = await response.text(); console.log(`Response: ${response.status} ${body}`);
The taget dynamic module was successfully updated. The response will contain the payload of the updated dynamic module.
1 2{ "key": "unique-module-key", "type": "trigger", "data": { "key": "trigger-key", "events": [ "avi:jira:updated:issue" ], "endpoint": "some-endpoint" } }
The specified key does not match the key specified in the dynamicModuleRequest map.
1 2{ "message": "Key cannot be modified during update" }
The Dynamic Module service encountered an unexpected problem.
1 2{ "message": "An internal error occurred" }
Send a GET request to /forge/installation/v1/dynamic/module/ to retrieve a paginated list of dynamic modules currently registered on the app installation.
| Property | Type | Required? | Description |
|---|---|---|---|
nextPageToken | string | No | Pagination cursor for fetching subsequent dynamic modules. This field is only present in a response if a strict subset of dynamic modules was previously fetched from this installation. |
limit | integer | No | Maximum number of dynamic modules to return |
1 2import { requestAtlassian } from "@forge/api"; const params = new URLSearchParams({ limit: '10', nextPageToken: '<PAGINATION-TOKEN>' }).toString(); const response = await requestAtlassian(`/forge/installation/v1/dynamic/module/?${params}`, { headers: { 'Content-Type': 'application/json' }, method: 'GET' }); const body = await response.text(); console.log(`Response: ${response.status} ${body}`);
Dynamic modules were successfully fetched.
1 2{ "key": "a-dynamic-module", "type": "trigger", "data": { "key": "trigger-key", "function": "jira-updated-issue-handler", "events": [ "avi:jira:updated:issue" ] } }, { "key": "another-dynamic-module", "type": "trigger", "data": { "filter": { "expression": "event.issue.fields?.issueType.name == 'Bug'", "onError": "RECEIVE_AND_LOG" }, "key": "another-trigger-key", "endpoint": "some-endpoint", "events": [ "avi:jira:updated:issue" ] } }
The request does not have permissions to access the target installation.
1 2{ "message": "Authorization failed" }
The Dynamic Module service encountered an unexpected problem.
1 2{ "message": "An internal error occurred" }
Send a GET request to /forge/installation/v1/dynamic/module/<key> to retrieve a registered dynamic module on the installation
(identified by the module's key).
| Property | Type | Required? | Description |
|---|---|---|---|
key | string | Yes | The unique key of the target dynamic module on the installation |
1 2import { requestAtlassian } from "@forge/api"; const key = '<YOUR-MODULE-KEY>'; const response = await requestAtlassian(`/forge/installation/v1/dynamic/module/${key}`, { headers: { 'Content-Type': 'application/json' }, method: 'GET' }); const body = await response.text(); console.log(`Response: ${response.status} ${body}`);
The specified dynamic module was successfully fetched.
1 2{ "key": "a-dynamic-module", "type": "trigger", "data": { "key": "trigger-key", "events": [ "avi:confluence:viewed:page" ], "function": "confluence-viewed-handler" } }
The request does not have permissions to access the target installation.
1 2{ "message": "Authorization failed" }
The Dynamic Module service encountered an unexpected problem.
1 2{ "message": "An internal error occurred" }
Send a DELETE request to forge/installation/v1/dynamic/module/<key> to delete a registered dynamic module on the installation
(identified by the module's key).
| Property | Type | Required? | Description |
|---|---|---|---|
key | string | Yes | The unique key of the target dynamic module on the installation |
1 2import { requestAtlassian } from "@forge/api"; const moduleKey = '<YOUR-MODULE-KEY>'; const response = await requestAtlassian(`/forge/installation/v1/dynamic/module/${moduleKey}`, { headers: { 'Content-Type': 'application/json' }, method: 'DELETE' }); console.log(`Response: ${response.status}`);
No content will be returned if the target dynamic module was successfully deleted.
The request does not have permissions to access the target installation.
1 2{ "message": "Authorization failed" }
The Dynamic Module service encountered an unexpected problem.
1 2{ "message": "An internal error occurred" }
Rate this page: