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
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • 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
    • Model Context Protocol
    • Vector Database
    • Heroku Inference
      • Inference Essentials
      • AI Models
      • Inference API
      • Quick Start Guides
    • 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
  • Platform API for Partners

Platform API for Partners

English — 日本語に切り替える

Last updated February 18, 2025

Table of Contents

  • Tutorial
  • List of Standard Platform API Endpoints
  • Best Practices
  • FAQ

Add-on Partners can access a subset of the Heroku Platform API via OAuth. This subset is called the Platform API for Partners. The Platform API for Partners provides the same functionality of the Legacy App Info API, along with the following significant advantages:

  • The Platform API for Partners provides many official endpoints that the App Info API doesn’t support. These endpoints let you introspect security settings, discover other customer instances of the same add-on, and much more.
  • Platform API for Partners endpoints are more consistent and “better traveled.” Heroku uses these endpoints internally, and customers also use them directly.

As of September 2022, you can get a full list of apps where your add-on is installed using the addons.heroku.com API V3 /apps endpoint. Review the Apps section of this documentation for more details.

See List of standard Platform API endpoints for a complete list of endpoints available to add-ons.

When an add-on is provisioned, it acts as an authorization step for the add-on partner to access relevant records about the add-on resource and its associations via the Platform API.

The tokens created as part of provisioning can then be used to authenticate requests to a number of Platform API endpoints. Our Platform API has a well-documented schema and already serves all of our customer-facing tooling.

Of the new concepts introduced, your add-on now has an OAuth client secret and a number of OAuth authorizations, one token per provisioned add-on. The OAuth client secret is only used to authenticate requests to create the scoped tokens; it is not used to authenticate other requests to the Platform API.

Tutorial

All new add-ons have access to the Platform API by default. The Platform API is standard for all add-ons using the v3 API as well. If your add-on was created before May 15, 2017, your add-on needs a flag set on our end. Please open a new support ticket to enable the flag.

This tutorial assumes that you already have an add-on implemented for the existing Partner API integration. To get up to that point quickly, you can follow the Building an Add-on tutorial and refer to our add-on reference implementation.

As a prerequisite, your add-on should already implement the Add-on Partner API calls for provision, planchange, and deprovision.

When the flag is enabled on your add-on, provision requests contain a grant code that you can exchange for an access token scoped to that add-on resource. The process is described below.

Retrieving Your Client Secret

You need your client_secret for most OAuth interactions with Heroku. You can find your Add-on’s client_secret in the Add-on Partner Portal on the “OAuth Credentials” page.

Getting a Token For a New Add-on Installation

Receiving the Grant Code

When a provision request is POSTed to your add-on it contains an OAuth Grant (some fields are omitted):

{
  "options": {},
  "oauth_grant": {
    "code": "01234567-89ab-cdef-0123-456789abcdef",
    "type": "authorization_code",
    "expires_at": "2016-03-03T18:01:31-0800"
  },
  "plan": "basic",
  "region": "amazon-web-services::us-east-1",
  "uuid": "01234567-89ab-cdef-0123-456789abcdef"
}

Make sure to reply to the provisioning request with a successful response code. If your service requires a longer than usual amount of time to provision, take a look at our documentation on Asynchronous Provisioning.

The provided grant code can be exchanged within 5 minutes for an Access Token and a Refresh Token using Heroku’s authentication service, id.heroku.com.

Exchanging the Grant Code

It’s time to exchange the grant code after you’ve responded to the initial provisioning request with a successful response code.

A grant code won’t be valid if you don’t respond with success to the initial provisioning request. If you respond with something other than success, we assume the provisioning request has permanently failed and invalidate the grant code.

To exchange the grant code, you POST to https://id.heroku.com/oauth/token including the grant code and your client secret as Content-Type: application/x-www-form-urlencoded. For example, here’s how you might make the request with curl.

$ curl -X POST https://id.heroku.com/oauth/token \
-d "grant_type=authorization_code&code=01234567-89ab-cdef-0123-456789abcdef&client_secret=01234567-89ab-cdef-0123-456789abcdef"

This returns a payload containing the desired tokens (some fields elided):

{
  "access_token": "HRKU-4594b794-0c94-416b-a374-bb33a025411f",
  "refresh_token": "95a242fe-4c4a-4059-bc06-512de9672619",
  "expires_in": 2592000,
  "token_type": "Bearer"
}

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 plaintext at rest, and their decryption keys should not be easily discoverable. If you are using Sequel in Ruby, consider evaluating the attr_vault gem.

All calls that you make to the Platform API use the access token for that add-on as authentication. Note that the token can only be used to request data about the add-on resource it was created for – you need to use each add-on resource’s access token to get access to its data in the Platform API. All responses are scoped to the add-on resource that the access token was created for.

Getting a Token For An Existing Add-On Installation

If you have been a Heroku Add-on Partner since before the Platform API for Partners was available, you have a number of existing add-on installations for which you never received an OAuth Grant.

To allow you to backfill the Access Token and Refresh Token for these installations, we have an endpoint available where you can retrieve the OAuth Grant. For security reasons, this endpoint is blocked by default and must manually be opened to each Add-on Partner. Please open a new support ticket to let us know that you are interested in using this endpoint.

As noted above, always encrypt the access_token, refresh_token and client_secret values when writing them to persistent storage.

We also encourage you to test out the OAuth flow for new installations on a test add-on before pursuing a backfill of Access Tokens and Refresh Tokens. Testing with the flow for new installations allows you to build out the functionality to exchange an OAuth Grant for the tokens.

Once you receive confirmation from us that the endpoint is open, you can begin to retrieve OAuth Grants. The endpoint is in the App Info API, so you need to retrieve your username and password for that API.

GET https://<username>:<password>@api.heroku.com/vendor/resources/:resource_uuid/oauth-grant
Content-Type: application/json

{
  "oauth_grant": {
    "code": "01234567-89ab-cdef-0123-456789abcdef",
    "type": "authorization_code",
    "expires_at": "2016-03-03T18:01:31-0800"
  }
}

If you previously had an OAuth Grant code issued, and this code has yet to expire, this endpoint returns the existing OAuth Grant. If the code has already expired, the endpoint generates a new one for you. If you have previously exchanged any Grant code for an Access Token & Refresh Token, this endpoint errors. If you have lost the Refresh Token provided by this exchange, please contact us.

The OAuth Grant code in the response expires within 5 minutes. You must follow the flow outlined above to exchange the Grant code for the Access Token and Refresh Token.

Accessing the API Using the Access Token

To access the API using the Access Token, use it like any other OAuth token on our Platform API, passing it to the API in the Authorization header. For example, to get details about the add-on:

GET /addons/01234567-89ab-cdef-0123-456789abcdef
Host: api.heroku.com:443
Content-Type: application/json
Accept: application/vnd.heroku+json; version=3
Authorization: Bearer 4594b794-0c94-416b-a374-bb33a025411f

Refreshing the Token

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.

To retrieve a new Access Token, use the same endpoint in the Heroku authentication service (id.heroku.com) once again. This time, your grant_type is “refresh_token” which you also pass along:

$ curl -X POST https://id.heroku.com/oauth/token \
-d "grant_type=refresh_token&refresh_token=95a242fe-4c4a-4059-bc06-512de9672619&client_secret=f6a36ee4-3736-455e-9787-bb91ca679706"

That returns a payload containing the new access token (some fields elided):

{
  "access_token": "HRKU-2af695e0-93e3-4821-ac2e-95f68435f128",
  "refresh_token": "95a242fe-4c4a-4059-bc06-512de9672619",
  "expires_in": 2592000,
  "token_type": "Bearer"
}

As noted above, always encrypt the access_token, refresh_token and client_secret values when writing them to persistent storage.

Using the Platform API to Set Config Var

The new integration includes the ability to config var through the Platform API rather than through the existing Add-on Partner App Info API. To accomplish this, you start with the add-on resource UUID from the provision request and the access token for that add-on resource.

You can view existing configuration for this add-on resource with the GET form of the endpoint:

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

And update it by using the PATCH form:

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

{
  "config": [
    {
      "name": "MY_ADDON",
      "value": "bar"
    }
  ]
}

See the Platform API Add-on Config Update documentation for further details.

Accessing App Details Through the Platform API

Request information about apps attached to your add-on resource in the Platform API. The endpoints which return an app usually take either the app’s UUID or the app’s name. To get your attached apps, you first have to request /addons/:resource_uuid or /addons/:resource_uuid/addon-attachments. The former gives you the primary app in the app object, and the latter gives you all attached apps through a list of attachments.

In using the app information, prefer the UUID for requests to the Platform API, and display the app name to the user. The app name is also suitable for making requests.

For example, if we request the /addons/:resource_uuid endpoint for an add-on resource we own, and get back (some fields elided): json { "app": { "id": "01234567-89ab-cdef-0123-456789abcdef", "name": "example" }, ... }

Then we can see that the app that the add-on resource was created on has ID 01234567-89ab-cdef-0123-456789abcdef. We can use this UUID to request information about the app from other endpoints. For example, we can use this app UUID with the app domains or app collaborators endpoints.

Log Drains

If your add-on has access to the ability to configure log drains for an app, it has access to the log drains endpoints in the Platform API. These endpoints all take the add-on resource UUID as an identifier. Please see the Log drain endpoints documentation for further details.

Log drains are not available for Fir-generation apps. Your add-on can’t access application logs from those apps.

List of Standard Platform API Endpoints

These endpoints are accessible by all add-ons that integrate with the Platform API:

Add-ons only see instances of the same add-on service from these endpoints. Add-ons only see instances of apps to which they are attached from these endpoints.

Add-on Resources

  • GET /addons/{add_on_id_or_name}
  • GET /addons
  • GET /users/{account_email_or_id_or_self}/addons
  • GET /apps/{app_id_or_name}/addons

Add-on Attachments

  • GET /addons/{add_on_id_or_name}/addon-attachments
  • GET /apps/{app_id_or_name}/addon-attachments
  • GET /apps/{app_id_or_name}/addon-attachments/{add_on_attachment_id_or_name}

Add-on Configuration

  • GET /addons/{add_on_id_or_name}/config
  • PATCH /addons/{add_on_id_or_name}/config

App Info

  • GET /apps/{app_id_or_name}
  • GET /apps
  • GET /users/{account_email_or_id_or_self}/apps
  • POST /filters/apps

App Collaborators

  • GET /apps/{app_id_or_name}/collaborators

Domains

  • GET /apps/{app_id_or_name}/domains

Log Drains

  • GET /addons/{add_on_id_or_name}/log-drains
  • PUT /addons/{add_on_id_or_name}/log-drains/{log_drain_id_or_url_or_token}
  • POST /apps/{app_id_or_name}/log-drains
  • DELETE /apps/{app_id_or_name}/log-drains/{log_drain_id_or_url_or_token}
  • GET /apps/{app_id_or_name}/log-drains/{log_drain_id_or_url_or_token}
  • GET /apps/{app_id_or_name}/log-drains

Pipelines

  • GET /pipelines/{pipeline_id_or_name}
  • GET /pipelines
  • GET /pipelines/{pipeline_id}/pipeline-couplings
  • GET /pipeline-couplings
  • GET /pipeline-couplings/{pipeline_coupling_id}
  • GET /apps/{app_id_or_name}/pipeline-couplings

Team Members

  • GET /teams/{team_name_or_id}/members

And More

We can enable other endpoints on a per-partner basis, if the use case warrants it. For example, you might want to look at the app’s formations, releases, or builds. Reach out to us and let us know what you are trying to accomplish!

Best Practices

Collect data just-in-time, if possible, and only store the add-on resource UUID, your own ID, and the combination of access token and refresh token for the add-on. Many fields on Heroku can change, including the owner’s email address and the app name, so we recommend catching it before it is needed.

Use only UUIDs as identifiers for Heroku add-on resources and Heroku apps. All previous identifiers (like the confusing “app123@heroku.com” identifiers) are not to be used with the Platform API.

FAQ

What happens if Heroku API is down as my Access Token is about to expire?

The Refresh Token given to Add-on Partners is long-lived. It can be used even if the Access Token expires. When the Heroku API becomes available again, exchange your Refresh Token for a new Access Token.

What do I do if an Access Token has been exposed?

If the OAuth client secret has not been exposed and your connection to the Heroku API is not compromised, use the Refresh Token to get a new Access Token, which expires the old one.

If the OAuth client secret has been compromised, see next question.

If the OAuth refresh token has been compromised, open a support ticket.

What do I do if my Oauth client secret has been exposed?

Perform a Credential Rotation immediately.

How do I perform a Credential Rotation?

Log into the Add-on Partner Portal with your Heroku Account, click on OAuth Credentials, then press the Reset button.

A new OAuth client secret is temporarily displayed on your screen. All existing Access Tokens become immediately invalid and must be refreshed using the new OAuth client secret.

It is imperative that you enable Two-Factor Authentication on the Heroku accounts of all Add-on admins so that an attacker can not reset your credentials and retrieve new ones.

How do I know which API endpoints I have access to?

A dynamic way to show this is unavailable. Endpoints for which your add-on has insufficient access returns an authorization error.

All add-ons have access to a shared base set of endpoints which may be expanded over time. If your add-on has specific needs, you are be able to work with our partner team and engineers to grant your add-on extended privileges and wider API access on a case-by-case basis.

How does rate limiting work when using the Platform API?

Each resource gets its own rate limit when accessed with a resource-scoped token. This way, many calls against one resource do not impact the ability to make API calls for other resources owned by your add-on. Use the RateLimit-Remaining response header on any response to check the current token count. The rate limit counts and documentation for the Platform API apply.

Can you give me some more concrete ideas of how to use this?

  • Syncing user access as an Ecosystem Partner
  • Inspecting Heroku Pipelines as an Add-on Partner
  • Implemented Credential Rotations as an Add-on Partner
  • Asynchronous Provisioning of Add-ons
  • Using Webhooks as an Add-on Partner
  • Customer Plan Usage Control Guidelines for Add-on Partners

Keep reading

  • Add-on APIs

Feedback

Log in to submit feedback.

Using Webhooks as an Add-on Partner Using Webhooks as an Add-on Partner

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