Deep-dive on the Next Gen Platform. Join the Webinar!

Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Working with AI
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Extending Heroku
  • Building Add-ons
  • Add-on APIs
  • Add-on Partner API Reference

Add-on Partner API Reference

English — 日本語に切り替える

Last updated March 12, 2025

Table of Contents

  • Overview
  • Add-on Provision
  • Grant Code Exchange
  • Access Token Refresh
  • Add-on Config Update
  • Add-on Action Provision
  • Add-on Plan Change
  • Add-on Deprovision
  • Add-on Action Deprovision
  • Add-on Info
  • Add-on Single Sign-on

Overview

The Add-on Partner API facilitates the provisioning, configuration, updating, and deprovisioning of add-on resources between Heroku and an add-on partner. In some cases a request is sent from Heroku to the add-on partner, and in other cases the request originates from the add-on partner and is sent to Heroku. If you are new to Heroku or are interested in taking your integration further, please take a look at the Platform API for Partners, which provides a guided introduction and includes information on additional endpoints.

Authentication & SSL

Calls from Heroku to the base_url for your service will include an Authorization header and MUST be validated using the id and api:password from your add-on manifest. The base_url MUST be an https url with a valid SSL certificate. For example if your manifest has an id of addon-slug, and an api:password of super-secret then requests to your service will include this header Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=.

Calls from your service to the Heroku API MUST use an OAuth access_token. The access_token, and refresh_token are obtained by exchanging a oauth_grant:code included in the initial provision request.

Idempotency

Requests MAY be sent multiple times (Heroku follows the pattern of at least once delivery), and endpoints MUST respond idempotently. For example, in the case of creating a resource multiple POSTs with the same parameters should only provision a single resource. The uuid SHOULD be used as a way to disambiguate duplicate requests. We recommend that a unique constraint be enabled at the database level on the uuid sent by Heroku to guard against duplicating work when such duplication would affect the outcome. The discussions of each interaction below adds more specifics about handling repeated idempotent requests.

Validation

Request bodies MAY contain additional elements not currently documented here, and such requests should be treated as valid.

Timeouts

Your service SHOULD respond within 500 milliseconds. Currently, it MUST return within 20 seconds or the request will fail. This upper limit will be reduced over time at our discretion and based on our analysis.

Versioning

The current version of the Add-on Partner API is version 3. Requests from Heroku to your service are versioned using the Accept header. For v3 requests this is set to application/vnd.heroku-addons+json; version=3. When making requests to Heroku on the Platform API you should use the Accept header specified by the Platform API reference. Currently this is application/vnd.heroku+json; version=3.

Response Bodies

All response bodies MUST contain valid JSON.

Exceptions

If your API CAN NOT fulfill a request, you SHOULD respond with an appropriate HTTP status code in the 4xx range if it is due to an invalid request (e.g. non-existent plan) or 5xx range if your API is experiencing unexpected errors. The error response body MUST contain valid JSON.

For 4xx and 5xx responses on provision and plan change requests, the message property from your JSON response will be displayed to the user. For all other responses, and when no message property is available, a generic error message will be displayed.

For common types of errors, it is recommended that your API add an id property to error payloads that contains a short keyword identifying the type of error. For an example, see how Heroku does it in our Platform API Reference. In the future, such identifiers may be exposed to partners in metrics and tooling for analysis. Failed Attempts to provision, deprovision etc, are available in the Partner Portal. We encourage you to monitor this list as it gives visibility into problems that customers are having.

Platform API

After your add-on resource is provisioned, you can use the Platform API to query information about your add-on installations or to update the configuration vars for your add-on.

Add-on Provision

A provision request from Heroku to your add-on service.

We support both synchronous and asynchronous add-on provisioning. If your provisioning process requires more than a few seconds, you should use asynchronous provisioning. This allows you to complete add-on resource setup in the background and notify Heroku upon completion. Please see Getting Started with Asynchronous Provisioning for a detailed overview and explanation of related policies.

The provisioning process is very similar under synchronous or asynchronous scenarios - we send a POST to the endpoint you registered in your manifest with a set of parameters, documented below. Your service can decide on each provision request whether to respond for synchronous, asynchronous, or failed provisioning by returning the appropriate HTTP response code.

The add-on provision request POST /heroku/resources sent from Heroku to the partner is expected to be idempotent. In other words, the same request MAY be sent to the partner multiple times, but only a single resource SHOULD be created per uuid, and the same response SHOULD be returned each time. However, if the resource has been deprovisioned, it SHOULD NOT be created again and a 410 SHOULD be returned. In order to facilitate data expunging by the partner the time frame in which a provision request may be retried is limited to 24 hours.

If you cannot support a provisioning request due to the parameters of the requested plan being unsupported by your add-on service, return a 422 status code along with an explanatory JSON encoded message. This message will be displayed to the customer in whatever context they’ve requested your add-on.

Asynchronous Provisioning

Under asynchronous provisioning, when an add-on receives a provisioning request from Heroku, it must do the following:

  • Issue a response with a 202 Accepted status code and a relevant message to be displayed to customers. This lets Heroku know you’re in the process of provisioning the requisite resources,
  • Persist the metadata included in Heroku’s request so you can correctly fulfill future add-on requests (upgrades/downgrades, deprovisions, SSO dashboard sign-ins, etc.)
  • Provision the necessary resources in your infrastructure,
  • Exchange the OAuth grant token we sent in the provisioning request to allow for resource scoped OAuth Platform API for Partners access,
  • (Optional) Update Heroku with the correct add-on configuration value which will be included in the owning app’s ENV, and
  • Mark the add-on resource as provisioned. If you don’t mark a resource as provisioned, we’ll assume it’s stuck and deprovision it after around 12 hours.

Some add-ons (for instance, those that only add log drains) may not need to include configuration values in an app’s ENV, and can skip updating the add-on configuration step.

A release is cut for the app that owns the add-on resource when you mark the resource as provisioned. Please be sure your add-on resource is ready to use when you mark it as such.

See Asynchronous Provisioning of Add-ons for a higher-level overview and info on billing policies.

Parameters

Name Type Description Example
callback_url string The URL which should be used to retrieve updated information about the add-on and the app which owns it. https://api.heroku.com/addons/01234567-89ab-cdef-0123-456789abcdef
name string Logical name of the resource being provisioned. acme-inc-primary-database
oauth_grant nullable object OAuth object details null
oauth_grant:code uuid may be exchanged for an access_token that is scoped to the resource being provisioned for use in the Platform API 01234567-89ab-cdef-0123-456789abcdef
oauth_grant:expires_at date-time the time at which the grant expires (ensure you have exchanged the code before this time)
defaults to 5 minutes from now
2016-03-03T18:01:31-0800
oauth_grant:type string the oauth grant type authorization_code
options object extra command line options passed in to the heroku addons:create command { "foo" : "bar", "baz" : "true" }
plan string the name of the plan to provision basic
region string Specifies the geographical region of the app that the add-on is being provisioned to— for the common run time, either amazon-web-services::us-east-1 or amazon-web-services::eu-west-1 are possible. The region values for private spaces are:
  • amazon-web-services::eu-west-1 (dublin)
  • amazon-web-services::eu-central-1 (frankfurt)
  • amazon-web-services::eu-west-2 (london)
  • amazon-web-services::ca-central-1 (montreal)
  • amazon-web-services::ap-south-1 (mumbai)
  • amazon-web-services::us-west-2 (oregon)
  • amazon-web-services::ap-southeast-1 (singapore)
  • amazon-web-services::ap-southeast-2 (sydney)
  • amazon-web-services::ap-northeast-1 (tokyo)
  • amazon-web-services::us-east-1 (virginia)
Use this to provision the resource in geographical proximity to the app, ignore it (if your add-on is not latency sensitive) or respond with an error if your add-on does not support apps in the region specified
amazon-web-services::us-east-1
uuid string The unique identifier Heroku uses for the installed add-on. It corresponds with the id field in the Heroku Platform API. 01234567-89ab-cdef-0123-456789abcdef

Optional Parameters

Name Type Description Example
log_input_url nullable string Provided so that logs can be sent to the app’s log stream. This field is only present when configured in your manifest, by adding log_input to the requires field. For more information, see the article describing logplex input. https://token:t.01234567-89ab-cdef-0123-456789abcdef@1.us.logplex.io/logs
log_drain_token string Provided so that logs from the app can be sent to the log_drain_url specified by the partner. This field is only present when configured in your manifest, by adding syslog_drain to the requires field. For more information, see the article describing accessing application logs. d.01234567-89ab-cdef-0123-456789abcdef

Request Example

POST /heroku/resources HTTP/1.1
Host: addon-slug-1234567890ab.herokuapp.com:443
Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=
Content-Type: application/json
Accept: application/vnd.heroku-addons+json; version=3
{
  "callback_url": "https://api.heroku.com/addons/01234567-89ab-cdef-0123-456789abcdef",
  "name": "acme-inc-primary-database",
  "oauth_grant": {
    "code": "01234567-89ab-cdef-0123-456789abcdef",
    "expires_at": "2016-03-03T18:01:31-0800",
    "type": "authorization_code"
  },
  "options": { "foo" : "bar", "baz" : "true" },
  "plan": "basic",
  "region": "amazon-web-services::us-east-1",
  "uuid": "01234567-89ab-cdef-0123-456789abcdef",
  "log_input_url": "https://token:t.01234567-89ab-cdef-0123-456789abcdef@1.us.logplex.io/logs",
  "log_drain_token": "d.01234567-89ab-cdef-0123-456789abcdef"
}

Parameters

Name Type Description Example
id string MAY be a string (e.g. UUID) or integer value. It MUST be an immutable value that can be used to address your resource. You MAY choose to use the value of the uuid field in the request. 01234567-89ab-cdef-0123-456789abcdef

Optional Parameters

Name Type Description Example
message string Further instructions to the user after creating the add-on Your add-on is being provisioned. It will be available shortly.
log_drain_url string URL capable of receiving logplex drain formatted logs from attached application(s). https://1.1.1.1

Response Example

HTTP/1.1 202 Accepted
{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "message": "Your add-on is being provisioned. It will be available shortly.",
  "log_drain_url": "https://1.1.1.1"
}

Synchronous Provisioning

You can use synchronous provisioning when your provisioning process completes quickly, for instance under a second. Under synchronous provisioning, you’re not required to mark the add-on resources as provisioned, however you should still exchange the grant code so you can use the Platform API for Partners in the future.

Under synchronous provisioning, you should:

  • Respond with a 200 OK status code to let Heroku know the provisioning process is complete,
  • Include the correct config value directly in your initial JSON response,
  • Exchange OAuth tokens after you have responded above.

You don’t need to:

  • Update Heroku with add-on configuration vars, as you return those in the main response,
  • Mark the resource as provisioned, as that’s implied in your 200 OK response.

Request Parameters

The request will be the same as it is under asynchronous provisioning.

Response Parameters

In addition to the id parameter as documented under asynchronous provisioning, you should include a config parameter along with any other optional parameters of your choosing.

Name Type Description Example
config object Configuration variables to be set as environment variables on any applications that use this add-on resource. All environment variables that you send should have the same prefix: your add-on’s name, capitalized. However, within the context of a Heroku app, the prefix may be different for a variety of reasons. For example, if your add-on is named fast-db and you are setting FAST_DB_URL, the variable name on the application will default to FAST_DB_URL but would be PRIMARY_DB_URL if the user added the add-on with the prefix PRIMARY_DB. { "MYADDON_URL": "http://myaddon.com/52e82f5d73" }

Response Example

HTTP/1.1 200 OK
{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "message": "Resource has been created and is available!",
  "config": { "MYADDON_URL": "http://myaddon.com/52e82f5d73" }
}

Grant Code Exchange

In order to interact with the Platform API as an add-on partner, you will need to exchange the oauth_grant:code from the provision request for an access_token, and refresh_token, which are used for authenticating requests, and obtaining new access_tokens respectively. Note that the access_token can only be used to request data about the add-on resource it was created for – you will need to use each add-on resource’s access_token to get access to its data in the Platform API. All responses will be scoped to the add-on resource that the access_token was created for.

Once the oauth_grant:code has been exchanged, save the access_token and refresh_token on your side.

Please be sure to encrypt the access_token and refresh_token values, as well as your client_secret, when writing them to persistent storage. These secrets should not be plain text at rest, and their decryption keys should not be easily discoverable. If you are using Sequel in Ruby, consider evaluating the attr_vault gem.

Parameters

Name Type Description Example
grant_type form encoded string Specifies the type of code being passed. authorization_code
code form encoded string The oauth_grant:code provided in the provision request. 01234567-89ab-cdef-0123-456789abcdef
client_secret form encoded string Secret used for most OAuth interactions. Your client_secret can be found in the Add-on Partner Portal on the “OAuth Credentials” page, and should be stored encrypted. 01234567-89ab-cdef-0123-456789abcdef

Request Example

POST /oauth/token HTTP/1.1
Host: id.heroku.com:443
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=01234567-89ab-cdef-0123-456789abcdef&client_secret=01234567-89ab-cdef-0123-456789abcdef

Parameters

Name Type Description Example
access_token string Used to access the Platform API scoped to a single add-on resource. Normally expires every 8 hours, but may expire early in certain circumstances, such as a credential rotation HRKU-2af695e0-93e3-4821-ac2e-95f68435f128
refresh_token string Valid for the lifetime of the add-on and can be exchanged for a new access_token as many times as needed using a valid OAuth client_secret. 95a242fe-4c4a-4059-bc06-512de9672619
expires_in integer The number of seconds the access_token is valid for. The refresh_token is used to acquire a new access_token. 28800
token_type string The token type is used in the Authorization header of requests to the Heroku API. Bearer

Response Example

HTTP/1.1 200 OK
{
  "access_token": "HRKU-2af695e0-93e3-4821-ac2e-95f68435f128",
  "refresh_token": "95a242fe-4c4a-4059-bc06-512de9672619",
  "expires_in": 28800,
  "token_type": "Bearer"
}

Access Token Refresh

The access_token is valid for up to 8 hours but may expire early in certain circumstances, such as a credential rotation. The refresh_token is valid for the lifetime of the add-on and can be exchanged for a new access_token as many times as needed using a valid OAuth client_secret.

Parameters

Name Type Description Example
grant_type form encoded string Specifies the type of code being passed. refresh_token
refresh_token form encoded string The refresh_token provided in the Grant Code Exchange. 95a242fe-4c4a-4059-bc06-512de9672619
client_secret form encoded string Secret used for most OAuth interactions. Your client_secret can be found in the Add-on Partner Portal on the “OAuth Credentials” page, and should be stored encrypted. 01234567-89ab-cdef-0123-456789abcdef

Request Example

POST /oauth/token HTTP/1.1
Host: id.heroku.com:443
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=95a242fe-4c4a-4059-bc06-512de9672619&client_secret=f6a36ee4-3736-455e-9787-bb91ca679706

Parameters

Name Type Description Example
access_token string Used to access the Platform API scoped to a single add-on resource. Normally expires every 8 hours, but may expire early in certain circumstances, such as a credential rotation HRKU-2af695e0-93e3-4821-ac2e-95f68435f128
refresh_token string Valid for the lifetime of the add-on and can be exchanged for a new access_token as many times as needed using a valid OAuth client_secret. 95a242fe-4c4a-4059-bc06-512de9672619
expires_in integer The number of seconds the access_token is valid for. The refresh_token is used to acquire a new access_token. 28800
token_type string The token type is used in the Authorization header of requests to the Heroku API. Bearer

Response Example

HTTP/1.1 200 OK
{
  "access_token": "HRKU-2af695e0-93e3-4821-ac2e-95f68435f128",
  "refresh_token": "95a242fe-4c4a-4059-bc06-512de9672619",
  "expires_in": 28800,
  "token_type": "Bearer"
}

Add-on Config Update

Use the add-on resource uuid from the provision request to update the configuration of an add-on. See the Platform API Add-on Config Update for further details.

Add-on configuration is the data an app needs to communicate with and use your add-on. For example, databases have config vars such as DATABASE_URL. You can set several config vars during its provisioning. No release triggers when you update the config vars during add-on provisioning. After your add-on is available, you must mark it as provisioned and restart all attached apps so that they can use your add-on.

For some add-ons, the actual environment variable set on an application is different than the key. Use the same prefix for all environment variables that you send: your add-on’s name, capitalized. However, within the context of a Heroku app, the prefix can be different for a variety of reasons.

For example, if your add-on is named fast-db and you’re setting FAST_DB_URL, the variable name on the application defaults to FAST_DB_URL, but can be PRIMARY_DB_URL if the user added the add-on with the prefix PRIMARY_DB.

Optional Parameters

Name Type Description Example
config array [{"name":"FOO","value":"bar"}]

Request Example

PATCH /addons/01234567-89ab-cdef-0123-456789abcdef/config HTTP/1.1
Host: api.heroku.com:443
Content-Type: application/json
Accept: application/vnd.heroku+json; version=3
Authorization: Bearer HRKU-2af695e0-93e3-4821-ac2e-95f68435f128
{
  "config": [
    {
      "name": "MY_ADDON",
      "value": "bar"
    }
  ]
}

Response Example

HTTP/1.1 200 OK
Accept-Ranges: name
Content-Range: id 01234567-89ab-cdef-0123-456789abcdef..01234567-89ab-cdef-0123-456789abcdef; max=200
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 2400
[
  {
    "name": "MY_ADDON",
    "value": "bar"
  }
]

Add-on Action Provision

Mark an add-on as provisioned for use.

If this step is not taken within 12 hours of the provisioning request, provisioning will be considered to have failed and the add-on will be removed.

This endpoint is also documented in the Platform API reference. Use the UUID resource we sent during the provisioning request as the ID.

Request Example

POST /addons/01234567-89ab-cdef-0123-456789abcdef/actions/provision HTTP/1.1
Host: api.heroku.com:443
Content-Type: application/json
Accept: application/vnd.heroku+json; version=3
Authorization: Bearer HRKU-2af695e0-93e3-4821-ac2e-95f68435f128

Response Example

HTTP/1.1 201 Created
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 2400
{
  "actions": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "label": "Example",
    "action": "example",
    "url": "http://example.com?resource_id=:resource_id",
    "requires_owner": true
  },
  "addon_service": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql"
  },
  "app": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example"
  },
  "config_vars": [
    "FOO",
    "BAZ"
  ],
  "created_at": "2012-01-01T12:00:00Z",
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "acme-inc-primary-database",
  "plan": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql:dev"
  },
  "provider_id": "abcd1234",
  "state": "provisioned",
  "updated_at": "2012-01-01T12:00:00Z",
  "web_url": "https://postgres.heroku.com/databases/01234567-89ab-cdef-0123-456789abcdef"
}

Add-on Plan Change

When a user requests a plan change for an installed add-on, Heroku will send a PUT request to your API.

If you CAN NOT support plan changes, respond with status code 422 or 503 and return a message to display to the user as described in exceptions. For example, if it is impossible to change between the users current plan and the requested plan, a 422 status code with a explanatory message is appropriate. However, if the plan change is failing due to internal reasons and the user should try again later, a 503 may be more appropriate.

The uuid in the request URI (:resource_uuid) MUST be used to identify the add-on to manipulate. This is the same uuid provided by Heroku in the provision request body.

The plan change request PUT /heroku/resources/:resource_uuid sent from Heroku to the partner is expected to be idempotent. In other words, the same request may be sent to the partner multiple times, and the same response should be returned each time. However, if the resource has been deprovisioned, it should not be updated again and a 410 should be returned. In order to facilitate data expunging by the partner the time frame in which a change request may be retried is limited to 24 hours. After this period either a 404 or 410 may be returned.

Parameters

Name Type Description Example
plan string The name of the plan to change to. basic

Request Example

PUT /heroku/resources/:resource_uuid HTTP/1.1
Host: addon-slug-1234567890abherokuapp.com:443
Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=
Content-Type: application/json
Accept: application/vnd.heroku-addons+json; version=3
{
  "plan": "basic"
}

Optional Parameters

Name Type Description Example
message string Further instructions to the user after changing the plan Resource has been updated and is available!

Response Example

HTTP/1.1 200 OK
{
  "message": "Resource has been updated and is available!"
}

Add-on Deprovision

When an add-on is removed from a user’s application, Heroku sends a deprovision request to your API.

We support both synchronous and asynchronous add-on deprovisioning. If your deprovisioning process requires access to our platform to provide the best user experience, use asynchronous deprovisioning. This option allows you to make a clean teardown of the resource and notify Heroku upon completion. See Asynchronous Deprovisioning of Add-ons for a detailed overview.

For the deprovisioning process, we send a DELETE request to the endpoint you registered in your manifest. To identify the add-on to manipulate, you must use the uuid in the request URL (:resource_uuid) The uuid is the one Heroku provided in the provision request body.

Heroku can send the deprovision request multiple times. Subsequent requests respond with a 2xx or 410. In order to facilitate data deletion by the partner, the time frame to retry a deprovision request is limited to 24 hours. After this period, subsequent requests return with either a 404 or 410.

Asynchronous Deprovisioning (Beta)

Partners must request access to this beta feature by opening a support ticket. After we grant you access to this feature, we include an X-Async-Deprovision-Allowed HTTP header on deprovisioning requests with a value set to true or false. This value indicates whether the Asynchronous Deprovisioning workflow is allowed for that resource or not.

Under Asynchronous Deprovisioning, when an add-on receives a deprovisioning request from Heroku and the feature is enabled, it must do the following:

  • Issue a response with a 202 Accepted status code. This response lets Heroku know you still need access to Platform API for Partners in order to complete the deprovisioning.
  • Perform any actions required by your deprovisioning process on our platform authenticating with the OAuth access token.
  • Mark the add-on resource as deprovisioned when you don’t require further access to the Heroku platform for that resource. If you don’t mark a resource as deprovisioned, we’ll assume it’s done and deprovision it after around 12 hours.
  • Deprovision any infrastructure or assets that were assigned to the add-on resource.

You don’t remove any add-on config vars, log drains, or webhook subscriptions attached to your add-on, as they’re deleted when you mark the add-on as deprovisioned.

A release is created for the app that owns the add-on resource when you mark the resource as deprovisioned. Be sure to keep any infrastructure or assets linked with the resource accessible before you mark it deprovisioned.

See Asynchronous Deprovisioning of Add-ons for a higher-level overview of this workflow.

Request Example

DELETE /heroku/resources/:resource_uuid HTTP/1.1
Host: addon-slug-1234567890ab.herokuapp.com:443
Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=
Content-Type: application/json
Accept: application/vnd.heroku-addons+json; version=3
X-Async-Deprovision-Allowed: true

Response Example

HTTP/1.1 202 Accepted

Synchronous Deprovisioning

Heroku applies this workflow to all deprovisionings for add-ons that didn’t request access to the Asynchronous Deprovisioning feature. Also, Heroku uses this workflow when the asynchronous workflow isn’t allowed for a particular resource and the X-Async-Deprovision-Allowed header is set to false.

Under Synchronous Deprovisioning, your add-on integration receives a deprovisioning request after Heroku stops billing and removes the add-on resource and all other objects attached, including the Partner authorization. Your add-on service can’t use the Heroku platform because your access tokens were removed at that point.

You can use Synchronous Deprovisioning when your provisioning process doesn’t require further access to the Heroku platform. Under Synchronous Deprovisioning, you’re not required to mark the add-on resource as deprovisioned.

Under Synchronous Deprovisioning, you must:

  • Respond with a 204 No Content status code (preferred) or any other 2xx Successful response code. This response lets Heroku know that your service has acknowledged the request and no further retries are required from us.
  • Deprovision any infrastructure or assets that were assigned to the requisite resource.

Request Parameters

The request is the same as it is under Asynchronous Deprovisioning. The header X-Async-Deprovision-Allowed is only included for add-ons that requested access to the Asynchronous Deprovisioning feature.

Response Example

HTTP/1.1 204 No Content

Add-on Action Deprovision

Mark an add-on as deprovisioned.

If this step isn’t taken within 12 hours of the deprovisioning request, deprovisioning is considered completed and the add-on is removed.

This endpoint is also documented in the Platform API reference. Use the resource UUID we sent you during the provisioning request as the ID.

Request Example

POST /addons/01234567-89ab-cdef-0123-456789abcdef/actions/deprovision HTTP/1.1
Host: api.heroku.com:443
Content-Type: application/json
Accept: application/vnd.heroku+json; version=3
Authorization: Bearer HRKU-2af695e0-93e3-4821-ac2e-95f68435f128

Response Example

HTTP/1.1 200 Ok
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 2400
{
  "actions": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "label": "Example",
    "action": "example",
    "url": "http://example.com?resource_id=:resource_id",
    "requires_owner": true
  },
  "addon_service": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql"
  },
  "app": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example"
  },
  "config_vars": [
    "FOO",
    "BAZ"
  ],
  "created_at": "2012-01-01T12:00:00Z",
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "acme-inc-primary-database",
  "plan": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql:dev"
  },
  "provider_id": "abcd1234",
  "state": "deprovisioned",
  "updated_at": "2012-01-01T12:00:00Z",
  "web_url": "https://postgres.heroku.com/databases/01234567-89ab-cdef-0123-456789abcdef"
}

Add-on Info

The Platform API for Partners allows you to request info for an add-on owned by your service. You can use the Platform API for Partners to request app, collaborator, region, domain, pipeline and other information as well.

Request Example

GET /addons/01234567-89ab-cdef-0123-456789abcdef HTTP/1.1
Host: api.heroku.com:443
Content-Type: application/json
Accept: application/vnd.heroku+json; version=3
Authorization: Bearer HRKU-2af695e0-93e3-4821-ac2e-95f68435f128

Response Example

HTTP/1.1 200 OK
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 2400
{
  "actions": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "label": "Example",
    "action": "example",
    "url": "http://example.com?resource_id=:resource_id",
    "requires_owner": true
  },
  "addon_service": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql"
  },
  "app": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example"
  },
  "config_vars": [
    "FOO",
    "BAZ"
  ],
  "created_at": "2012-01-01T12:00:00Z",
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "acme-inc-primary-database",
  "plan": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "heroku-postgresql:dev"
  },
  "provider_id": "abcd1234",
  "state": "provisioned",
  "updated_at": "2012-01-01T12:00:00Z",
  "web_url": "https://postgres.heroku.com/databases/01234567-89ab-cdef-0123-456789abcdef"
}

Add-on Single Sign-on

Users of your add-on can be seamlessly signed into a personalized dashboard for the resources they create with your service. More details, including navigation bar integration can be found in Add-on Single Sign-on.

Parameters

Name Type Description Example
resource_id form encoded string The uuid provided by heroku in the provisioning call. 01234567-89ab-cdef-0123-456789abcdef
resource_token form encoded string SHA1 encoded resource_id:salt:timestamp. Used for authenticating the SSO request to your service. fcafa20c7ac7675276ea92ed04bc929674b711a5
timestamp form encoded string Time at which the request SSO request was initiated. 1267597772
nav-data form encoded string Includes information like the current app name and installed add-ons so the Heroku layout can build the appropriate view for the current app. eyJhZGRvbiI6IllvdXIgQWRkb24iLCJhcH...
email form encoded string Email of the authenticated user. user@example.com

Optional Parameters

Name Type Description Example
foo form encoded string Additional query string params MAY be included in the SSO URL. These params will be forwarded to your application in the POST body. See What is an Add-on for more information on SSO. bar

Request Example

POST /heroku/sso HTTP/1.1
Host: addon-slug-1234567890ab.herokuapp.com:443
Content-Type: application/x-www-form-urlencoded

resource_id=01234567-89ab-cdef-0123-456789abcdef&resource_token=fcafa20c7ac7675276ea92ed04bc929674b711a5&timestamp=1267597772&nav-data=eyJhZGRvbiI6IllvdXIgQWRkb24iLCJhcHBuYW1lIjoibXlhcHAiLCJhZGRvbnMiOlt7InNsdWciOiJjcm9uIiwibmFtZSI6IkNyb24ifSx7InNsdWciOiJjdXN0b21fZG9tYWlucyt3aWxkY2FyZCIsIm5hbWUiOiJDdXN0b20gRG9tYWlucyArIFdpbGRjYXJkIn0seyJzbHVnIjoieW91cmFkZG9uIiwibmFtZSI6IllvdXIgQWRkb24iLCJjdXJyZW50Ijp0cnVlfV19&email=user%40example.com&foo=bar

Response Example

HTTP/1.1 302 Found
Location: https://addon-slug-1234567890ab.herokuapp.com/dashboard

Keep reading

  • Add-on APIs

Feedback

Log in to submit feedback.

Using Webhooks as an Add-on Partner Platform API for Partners

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices