RFCs are a way for Atlassian to share what we’re working on with our valued developer community.
It’s a document for building shared understanding of a topic. It expresses a technical solution, but can also communicate how it should be built or even document standards. The most important aspect of an RFC is that a written specification facilitates feedback and drives consensus. It is not a tool for approving or committing to ideas, but more so a collaborative practice to shape an idea and to find serious flaws early.
Please respect our community guidelines: keep it welcoming and safe by commenting on the idea not the people (especially the author); keep it tidy by keeping on topic; empower the community by keeping comments constructive. Thanks!
Project Summary
This RFC defines how Forge app installations behave when they enter a suspended state. We want to give you - as a Forge developer - a clear, predictable contract: what happens to your app’s functions, UI extensions, product events, and storage access during suspension, and what you should do to handle the transition cleanly when your app comes back online.
Publish: 05 June 2026
Discuss: 19 June 2026
Resolve: 03 July 2026
Problem
Your Forge app can enter a suspended state for a number of reasons - for example, when a customer’s Marketplace subscription lapses, when data is being migrated to a new region, or when Atlassian needs to take an app offline for operational reasons.
Today, what actually happens to your app during suspension is not consistent:
- Your app may continue to appear available in some places while silently failing in others (e.g. invocations blocked). This creates a confusing experience for both, you and your customers.
- There is no documented, reliable contract for what you can expect during suspension - whether your functions will be called, whether your UI extensions will render, whether product events will be delivered, or whether your storage will be accessible. This also means that when a customer stopped paying for an app, vendors would continue to pay for Forge storage, compute and logs for the time of suspension (60 days).
- Future app types may not be tied to a single host app (like Jira or Confluence) anymore. This means suspension behaviour that was previously inherited from the host app no longer applies, and these app shapes need their own clearly defined suspension semantics.
The result is that it’s hard to build apps that handle suspension gracefully, recover cleanly, or communicate the right experience to your customers when an app goes offline.
It is also worth noting that when an Atlassian app subscription expires, the apps go offline for 60 days and then are soft-deleted. Forge apps stay online for 60 days and then are soft-deleted. This inconsistent behaviour is confusing for customers.
We want to fix this by introducing a simple, consistent suspension contract across all Forge app types.
Proposed Solution
When a Forge app installation enters a suspended state, it will be fully offline. Your app will not run, render, or receive events during suspension. Here’s exactly what that means:
- Functions and triggers will not be invoked. This includes scheduled triggers, web triggers, and event-triggered functions. No invocations will occur while the installation is suspended.
- UI extensions will be hidden. Any modules your app renders in the Atlassian product UI - panels, dialogs, issue glances, macros, etc. - will be hidden or shown as unavailable while the app is suspended.
- Product events will be dropped (with the exception of Data Residency (see below).
- Forge Storage will not be accessible, incl Forge remote (ie Forge Storage API calls). Your app will not be able to read from or write to Forge Storage while suspended.
- Your app remains visible to Admins. The app will still appear in the Connected Apps section of Atlassian Administration, marked as Suspended. Admins can either resubscribe or uninstall the app at any time during the suspension period.
Event Handling: Data Residency Migrations vs. Everything Else
The only case where suspension behaviour differs is for product event delivery during a data residency migration:
| Suspension reason | What happens to product events |
|---|---|
| Data residency migration | Events are queued while the app is offline and replayed once the migration is complete. Migrations are typically short-lived (up to ~24 hours), making buffering safe and practical. You don’t need to do anything - events will be delivered automatically on unsuspend. |
| All other suspension reasons (subscription lapse, key revocation, host product suspension, operational suspension, infrastructure maintenance) | Events are dropped. They are not buffered and will not be replayed when your app comes back online. You should implement a reconciliation pattern to re-sync your app’s state on unsuspend (see guidance below). |
We made this distinction because suspensions due to non-payment can last up to 60 days. Buffering all Atlassian app events for that duration at the volumes involved is not feasible and would potentially overwhelm your app with a large burst of buffered events if unsuspended. For short, bounded suspension windows like data residency migrations, buffering is safe and we will handle it automatically for you.
Suspension Scenarios and What to Expect
Here is a summary of how suspension works across the different scenarios you might encounter:
| Scenario | What triggers it | Functions & triggers | UI extensions | Product events | How it resolves |
|---|---|---|---|---|---|
| Data residency migration | An admin moves data to a new region | Not invoked | Hidden / Unavailable | Automatic - your app resumes once the migration completes | |
| Customer-managed key (CMK) revocation or re-encryption | A customer revokes or rotates their encryption keys | Not invoked | Hidden / Unavailable | Dropped | Automatic - your app resumes once the key operation is complete |
| Marketplace app subscription lapsed | A customer’s paid subscription for your app expires or is cancelled | Not invoked | Hidden / Unavailable | Dropped | The customer re-subscribes via their Billing Console. If not re-subscribed within the suspension window (up to 60 days), the installation moves to a deactivated state and is deleted after a further 30 days. |
| Host Atlassian app subscription lapsed | The Atlassian app your app is installed in (e.g. Jira, Confluence) is suspended due to non-payment | Not invoked | Hidden / Unavailable | Not applicable - the host app does not emit events when suspended | Automatic - your app resumes when the host product subscription is reinstated |
| Operational suspension by Atlassian | Atlassian suspends your app installation due to a policy violation, abuse, or an operational issue | Not invoked | Hidden / Unavailable | Dropped | You will be notified in advance and your app will be re-activated once the issue is resolved. |
| Atlassian infrastructure maintenance | Atlassian performs a planned infrastructure or storage migration | Not invoked | Hidden / Unavailable | Dropped | Automatic - your app resumes once maintenance is complete. Atlassian will provide advance notice where possible. |
What Is Changing: Removal of the “Unlicensed / Free” Mode
Some Forge apps have historically implemented a developer-defined “unlicensed” or degraded mode - keeping the app partially functional after a subscription lapsed, for example by showing a re-subscribe prompt while still serving basic functionality.
Under this new contract, this approach will no longer work. When an installation is suspended, it is fully offline - there is no platform support for a partially functional or degraded mode during the suspension window, regardless of what your app’s code does.
The right time to re-engage customers is before suspension occurs. We recommend using the licenseDetails object in the Forge license API - which exposes the trial end date and current subscription status - to surface warnings to Admins ahead of expiry. This is a better and more reliable re-engagement experience than a degraded post-expiry mode.
Guidance for Developers
Reconciling state after your app comes back online
Because Atlassian app events are dropped during suspension (for everything except data residency migrations), your app may have missed events that occurred while it was offline. We recommend building a reconciliation pattern that runs when your app transitions from suspended back to active:
- Provide a mechanism to gracefully resync your app’s state if needed. Use the Atlassian app REST APIs to fetch the current state of relevant data (e.g. Jira issues, Confluence pages, user data) rather than relying on any event replay.
- Make your synchronisation logic idempotent - running it multiple times should not produce duplicate side effects or data inconsistencies.
- Avoid assuming that no changes occurred while your app was offline. Treat your local state as stale on unsuspend and verify it against the Atlassian app.
We are also considering introducing suspended/ unsuspended lifecycle events that would notify your app explicitly when it gets suspended and transitions back to active, making it straightforward to trigger your reconciliation logic. We’d love to hear whether this would be useful to you.
Scheduled triggers
Scheduled triggers will not fire while your app is suspended. Missed scheduled executions are not queued - they will not run when your app comes back online. Design your scheduled trigger logic to be resilient to gaps: do not assume every scheduled execution has occurred when your app resumes.
Notifying your customers before suspension
For paid apps, the best way to prevent unexpected suspension for your customers is to surface clear warnings before their subscription expires. The licenseDetails object in the Forge license API gives you access to the trial end date and subscription state - use this to show timely, actionable prompts to Admins before the subscription lapses.
Multiple app compatible Forge apps
If you’re building a Forge app that is compatible with multiple Atlassian apps, your installation is not tied to a single host product like Jira or Confluence. This means your app’s suspension state is managed independently - for optional links, your app may remain online while the linked Atlassian app is offline and suspended .
Asks
We are keen to hear from you:
- Does this suspension contract work for your use cases? Are there scenarios where being fully offline during suspension would cause significant problems for your app or your customers?
- Would a suspended/ unsuspended lifecycle event - explicitly notifying your app when it comes back online - be useful for triggering reconciliation? How would you use it?
- Does removing the “unlicensed/free” degraded mode affect you? What patterns do you currently rely on that this change would break?
- If your design needs a reconciliation pattern, can this be achieved gradually within current API limits and costs?
