Add-on Partner Technical Best Practices
Last updated February 06, 2024
Table of Contents
- Handling plan changes should be idempotent
- Don’t perform expensive provisions or plan changes in real time
- Use the add-on resource UUID instead of older identifiers
- Add-on config vars should be relevant to the application
- Use the correct email address for customers
- Identifying users sent through SSO
- App names are mutable
- Attachable add-ons can be attached to multiple apps
- Add-on slugs and plan slugs cannot change
- Questions and suggestions
This list of technical best practices provides guidance on how to handle common scenarios that you might encounter when building an add-on integration. More documentation about building add-ons is available in the Building Add-ons section of Dev Center.
Handling plan changes should be idempotent
When a request is made to upgrade or downgrade to the same plan that the add-on is already using, it should be treated as a no-op. Return a 200 OK
response status code and log it on your side. If this happens often, it might represent a problem with the initial plan change that causes Heroku to believe the action was unsuccessful and so the user is retrying the action. Monitoring for this situation and treating a request to change to the same plan as idempotent is the best approach.
Don’t perform expensive provisions or plan changes in real time
If your provision will take more than a few seconds, use the Async Partner API.
If your plan change will take more than a few seconds your service should respond with a 202 Accepted
status code. Use the callback APIs to make any necessary changes to the ENV vars when your service has finished. See the Add-on Partner API overview for more information.
Use the add-on resource UUID instead of older identifiers
Use the resource UUID as the primary key in your apps. Older identifiers such as the Heroku ID (or HID) should not be used.
The legacy identifiers in the provision request and Get App Info API exist for backwards compatibility. The only immutable, or unchanging, identifier that we support is the resource UUID, which is the uuid
field on the provision request and the resource.uuid
field on the Get App Info API response.
Add-on config vars should be relevant to the application
Only set config vars that will be useful to an application at runtime and for appropriate client libraries or tools. For example, it might be appropriate to set the username/password for a service such as SMTP. However, you shouldn’t set the username/password for a dashboard (this should be handled by SSO).
Use as few config vars as possible. If all metadata is naturally expressed as a URI, use that URI. For example, DATABASE_URL
instead of DATABASE_USER
, DATABASE_HOST
, and DATABASE_PASS
.
Use the correct email address for customers
Please fetch an app owner or collaborator’s email address every time you want to send the customer an email. Customers are allowed to change this email address and the owner of an app can change, so we recommend you do not persist it in your system.
If you are on the legacy (V1) add-ons integration, you should use the Get App Info API. If you are on the current (V3) integration, you can follow the Syncing user access as an ecosystem partner guide.
Do not use the id
key of the provision request as an email address. It will look like app123@heroku.com
. This is a legacy identifier called a Heroku ID (or HID) that we maintain for backwards compatibility. It does not function as an email address.
Identifying users sent through SSO
Follow the documentation for SSO to determine the user accessing your dashboard via SSO.
Note that the user email address provided in the SSO request may not be the app owner’s email address. We support multiple collaborators on apps, and Heroku Enterprise has several roles in an organization which may have access to an app’s add-ons.
Some users will have multiple apps, each with your add-on. Some partners attempt to merge multiple installations because they share an email address. However, apps can be transferred to other accounts, and so we recommend against doing that.
App names are mutable
App names change. Users can rename apps. Whenever you need the billing app name for an add-on, we recommend you use the Get App Info API to fetch it. Note that in the future we may allow add-ons to be moved between apps at a user’s request. It is best not to tie an add-on record to the Heroku app or its name on your side.
Attachable add-ons can be attached to multiple apps
Be careful not to assume in your code that an add-on only has one Heroku app attached to it. In particular, do not use the app name from the Get App Info API as an identifier for the add-on. This results in a brittle design and will prevent you from implementing attachable add-ons or many-per-app add-ons. Instead, you should always refer to the add-on resource UUID returned by the provision request and the Get App Info API rather than the app in your code.
Add-on slugs and plan slugs cannot change
For data consistency, especially across billing, we do not allow changes to the add-on slug or plan slugs. Instead, the recommended process is to archive the existing plan by hiding it or disabling it and creating a new plan with the preferred name.
Questions and suggestions
If you have any questions or suggestions for best practices that should be included in this article, please contact us by opening a support ticket.