Developer
News and Updates
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Runtimes
Web triggers
Async events
Dynamic Modules (EAP)
Customer-managed egress and remotes (EAP)
License API
Atlassian app REST APIs
Fetch APIs
Last updated Mar 23, 2026

Customer-managed egress and remotes API (EAP)

Customer-managed egress and remotes are currently available through Forge's Early Access Program (EAP). EAP capabilities are experimental, unsupported, and subject to change without notice, and are not recommended for production use.

For more details, see Forge EAP, Preview, and GA.

Once the manifest of an app has been configured, the app can interact with customer‑managed egress and remotes using the async Forge functions in the permissions module in @forge/bridge.

Egress-related calls will fail if permissions.external.configurable.enabled is not set to true, and setting a remote will not work unless the remote has the configured property defined in the manifest.

Set egress

When permissions.egress.set is called, an admin will see a confirmation modal describing the egress that will be added. If they approve, the group is saved and the Promise resolves. If they reject, the Promise rejects. This requires the user to be an administrator. This promise can be caught in the Forge app code and relevant errors can be shown to the user and handled as appropriate.

When this is called an admin will see a confirmation modal describing the egress that will be added. If they approve, the group is saved and the Promise resolves. If they reject, the Promise rejects. This requires the user to be an administrator otherwise the Promise will reject. This Promise can be caught in the Forge app code and relevant errors can be shown to the user and handled as appropriate.

Request

PropertyTypeRequired?Description
keystringYesThe unique key of the egress group
descriptionstringYesThe description of the egress group being created. This appears in the admin modal to provide context to the reviewing admin
configuredarrayYesAn array of objects containing information about the egress being configured. The object consists of two fields:

Responses

CodeDescription
201Success
400Malformed request, validation failures, or max egress limit exceeded
403Authorization/permission issues, feature not enabled for app, or rate limit exceeded
422Business logic violations (duplicate keys/domains, invalid URLs)
5XXUnexpected server errors

Example

1
2
import { permissions } from "@forge/bridge";
import { EgressType } from "@forge/egress";

async function configureEgress() {
  await permissions.egress.set({
    egresses: [
      {
        key: "example-egress",
        description: "Access to example.com",
        configured: [
          {
            domain: "https://api.example.com",
            type: [EgressType.Image],
          },
        ],
      },
    ],
  });
}

Get egress

When permissions.egress.get is called, any previously configured egress groups will be returned. This call does not require a user to be an administrator.

Request

PropertyTypeRequired?Description
keysstring[]NoIf provided, will return any egress groups that match the keys. If undefined, all egress groups will be returned.
pageSizenumberNoNumber of egress groups to return in a single page. If undefined, will default to returning all available egress groups.
nextPageTokenstringNoToken to fetch the next page of values when paginating with pageSize.

Responses

CodeDescription
200Success. Returns any configured egress groups.
400Invalid query parameters (pageSize out of range, invalid types)
401Authentication failures (missing/invalid OAuth claims, system account issues)
403Authorization failures (insufficient permissions, feature not enabled, rate limit)
429Rate limit exceeded
5XXServer/dependency errors

Example

1
2
import { permissions } from "@forge/bridge";

async function getEgress() {
  const getAllEgressGroups = await permissions.egress.get({});
  const getSomeEgressGroups = await permissions.egress.get({
    keys: ["my-egress-group-1", "my-egress-group-2"],
  });
}

Delete domain from egress group

Use permissions.egress.deleteDomain to delete a single domain from a previously defined egress group. This is useful when you want to keep the group but remove one domain/type entry. This requires the user to be an administrator.

Request

PropertyTypeRequired?Description
keystringYesThe unique key of the egress group
domainstringYesThe domain to delete from the group
typestringYesThe egress type to delete from the group. This is required because a group may have multiple egress types set for the same domain.

Response

CodeDescription
204Success (No Content). The domain/type combination was deleted, or didn't exist.
400Invalid request body (missing fields, wrong types, invalid enum value)
403Authorization failures (insufficient permissions, feature not enabled, rate limit)
429Rate limit exceeded
5XXServer/dependency errors

Example

1
2
import { permissions } from "@forge/bridge";

async function deleteEgress() {
  await permissions.egress.deleteDomain({
    key: "my-egress-group",
    domain: "http://www.example.com",
    type: "FRAMES",
  });
}

Delete group

Use permissions.egress.deleteGroup to delete an entire egress group and all of its defined domains. This requires the user to be an administrator.

Request

PropertyTypeRequired?Description
keystringYesThe unique key of the egress group

Response

CodeDescription
204Success (No Content). The egress group was deleted, or didn't exist.
400Invalid or missing key query parameter
403Authorization failures (insufficient permissions, feature not enabled, rate limit)
429Rate limit exceeded
5XXServer/dependency errors

Example

1
2
import { permissions } from "@forge/bridge";

async function deleteEgress() {
  await permissions.egress.deleteGroup({
    key: "my-egress-group",
  });
}

Set remote endpoint

Use permissions.remote.set to set or update the endpoint of a customer-managed remote. This requires the user to be an administrator.

Request

PropertyTypeRequired?Description
remotesarrayYesAn array of objects representing remotes, it must contain:
  • key: The key of the remote to be updated. The remote must exist in the manifest and be configurable.
  • endpoint: Absolute URL for the remote, or null to reset it. If a baseUrl is defined in the manifest, resetting to null will restore the manifest value. If no baseUrl is defined, resetting to null will unset the endpoint.

Response

CodeDescription
201Success
400Invalid request body, max remotes exceeded
403Authorization failures, rate limit
422Duplicate keys, invalid endpoints, pattern mismatch
429Rate limit exceeded
5XXServer/dependency errors

Example

1
2
import { permissions } from "@forge/bridge";

async function setRemote() {
  await permissions.remote.set({
    remotes: [
      {
        key: "my-remote",
        configured: {
          endpoint: "https://example.com",
        },
      },
    ],
  });
}

Get remote endpoint

Use permissions.remote.get to get previously configured remotes for an installation. You can fetch specific remotes or all remotes. This does not require the user to be an administrator.

Request

PropertyTypeRequired?Description
keysstring[]NoIf provided, will return any remotes that match the keys. If undefined, all remotes will be returned.
pageSizenumberNoNumber of remotes to return in a single page. If undefined, will default to returning all available remotes.
nextPageTokenstringNoToken to fetch the next page of values when paginating with pageSize.

Response

CodeDescription
200Success
400Invalid query parameters (pageSize out of range, keys exceeds pageSize, invalid types)
401OAuth authentication failures
403Authorization failures, rate limit
429Rate limit exceeded
5XXServer/dependency errors

Example

1
2
import { permissions } from "@forge/bridge";

async function getRemotes() {
  const getAllRemotes = await permissions.remote.get({});
  const getSomeRemotes = await permissions.remote.get({
    keys: ["my-remote", "my-remote-2"],
  });
}

Rate this page: