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
View 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
      • Node.js Behavior in Heroku
      • Working with Node.js
      • 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
      • Working with PHP
      • PHP Behavior in Heroku
    • 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
    • Heroku Inference
      • AI Models
      • Inference Essentials
      • Inference API
      • Quick Start Guides
  • 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
  • Platform API
  • OAuth

OAuth

English — 日本語に切り替える

Last updated April 23, 2025

Table of Contents

  • Integrating with Client Libraries
  • A Note on Architecture
  • Prefixed OAuth Tokens
  • Web Application Authorization
  • Scopes
  • Direct Authorization
  • Revoking Authorization
  • Resources and Examples
  • Limit Access to Apps via OAuth

OAuth provides a way to authorize and revoke access to your account to yourself and third parties. Third parties can use this to provide services, such as monitoring and scaling your applications. You can also use these tokens obtained with OAuth to grant access for your own scripts on your machine or to other applications.

The Heroku Platform API implements OAuth version 2.0 as the preferred authentication mechanism. For further details of the specific API endpoints see the Platform API Reference.

Third parties who wish to provide services to Heroku users should implement web application authorization. Users who would like to use a personal OAuth token should instead use direct authorization.

Integrating with Client Libraries

To integrate with existing client libraries, you should use these endpoints:

  • Tokens: https://id.heroku.com/oauth/token
  • Authorizations: https://id.heroku.com/oauth/authorize

Additional details and directions follow if you need to do non-web flows or customize usage.

A Note on Architecture

An OAuth authorization can be generated in one of two ways: via web authorization flow, or from the Heroku API. The web authorization flow (located at the domain id.heroku.com) is designed to easily support common OAuth conventions and be accessible to widely-used libraries. The component supporting this web flow is itself built on the Heroku API (located at the domain api.heroku.com), which is the canonical source for all OAuth data. Both components will be covered in this article.

Prefixed OAuth Tokens

Heroku OAuth access tokens are 65 characters long and prefixed with HRKU-.

Token example: "HRKU-AALJCYR7SRzPkj9_BGqhi1jAI1J5P4WfD6ITENvdVydAPCnNcAlrMMahHrTo"

Using a prefixed token helps identify potentially leaked tokens in code or logs by searching for the HRKU- prefix.

If you notice a token in your store that doesn’t have the HRKU- prefix, then this token hasn’t been regenerated since the change was implemented. After regenerating the token, it will have the HRKU- prefix.

Web Application Authorization

Web application authorization allows third parties to ask for and gain access to the resources of a Heroku user, which they can then use to provide services and features on top of the Heroku platform.

Register Client

The client is what identifies you, the third-party integrator, to Heroku and to authorizing users. When you register a client, you provide a callback URL and a name. The name is displayed to users when authorization is requested, so choose a name that identifies your site or application.

There are three ways to register a client: on dashboard (easiest), using the Heroku CLI’s oauth commands or using the API directly.

When you register a client, you get an ID and a secret that you use to authorize Heroku users against.

OAuth Flow

This section describes the flow required to authorize your app to get access to a Heroku user’s account.

Redirect to Heroku

From your app, redirect the user to authorize:

GET https://id.heroku.com/oauth/authorize?client_id={client-id}&response_type=code&scope={scopes}&state={anti-forgery-token}

Include client-id in the request, which is the public identifier of an OAuth client. Also make sure to include response_type, and to set it to code, which is the only currently supported grant type.

The scope URL parameter is a space-delimited (and url-encoded) list of the authorization scopes you are requesting. See available scopes below.

The state parameter is a unique string used to maintain state between Heroku’s OAuth provider and your app. When Heroku redirects users back to your app’s redirect_uri, this parameter’s value will be included in the response (see below). This parameter’s value should be an anti-forgery token to protect against cross-site request forgery (CSRF).

Redirect Back

The user will then be redirected back, based on the client redirect uri:

GET {redirect-uri}?code={code}&state={anti-forgery-token}

Token Exchange

Given the code from the redirect url, a token may now be acquired.

POST /oauth/token

Curl Example

$ 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"

Response

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
{
  "access_token":"HRKU-01234567-89ab-cdef-0123-456789abcdef",
  "expires_in":28799,
  "refresh_token":"01234567-89ab-cdef-0123-456789abcdef",
  "token_type":"Bearer",
  "user_id":"01234567-89ab-cdef-0123-456789abcdef",
  "session_nonce":"2bf3ec81701ec291"
}

Use the access token’s token value in the Authorization header in subsequent requests. For example, given the token 01234567-89ab-cdef-0123-456789abcdef, you’d set the header to Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef.

Access tokens acquired through the direct authorization flow don’t expire.

Token Refresh

Access tokens expire 8 hours after they are issued. The refresh token can be used to make a request for a new access token, similar to the initial access token exchange. Refresh tokens don’t expire.

POST /oauth/token

Curl Example

$ curl -X POST https://id.heroku.com/oauth/token \
-d "grant_type=refresh_token&refresh_token=036b9495-b39d-4626-b53a-34399e7bc737&client_secret=fa86a593-d854-4a3f-b68c-c6cc45fb6704"

Response

HTTP/1.1 201 Created
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 1200
{
  "access_token":"HRKU-811235f4-16d3-476e-b940-ed5dfc7d6513",
  "expires_in":7199,
  "refresh_token":"036b9495-b39d-4626-b53a-34399e7bc737",
  "token_type":"Bearer",
  "user_id":"01234567-89ab-cdef-0123-456789abcdef",
  "session_nonce":"2bf3ec81701ec291"
}

Subsequent requests should authenticate by adding the access token’s token value to the Authorization header and specifying type Bearer. For example, given the access token 01234567-89ab-cdef-0123-456789abcdef, request headers should be set to Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef.

Scopes

The following scopes are supported by the API:

  • global: Read and write access to all of your account, apps and resources. Equivalent to the default authorization obtained when using the CLI.
  • identity: Read-only access to your account information.
  • read and write: Read and write access to all of your apps and resources, excluding account information and configuration variables. This scope lets you request access to an account without necessarily getting access to runtime secrets such as database connection strings.
  • read-protected and write-protected: Read and write access to all of your apps and resources, excluding account information. This scope lets you request access to an account including access to runtime secrets such as database connection strings.

Direct Authorization

Direct authorization is used to provide a simpler workflow when users are creating authorizations for themselves. It allows the exchange of an expiring token for a non-expiring token.

Token Exchange Requests

As multi-factor authentication is a mandatory Heroku security feature, accounts must pass a Heroku Platform API token to exchange for a non-expiring token. You can’t exchange your username and password for this purpose.

POST /oauth/authorizations

You can get your API token using the heroku auth:token command.

You can then create a direct authorization request by including this token:

$ curl -X POST https://api.heroku.com/oauth/authorizations \
-H "Accept: application/vnd.heroku+json; version=3" \
-H "Authorization: Bearer <token retrieved from heroku auth:token>" \
-H "Content-Type: application/json" \
-d "{\"description\":\"sample authorization\"}"

Include a description to help distinguish this authorization from others. Similar to the web flow, you can scope the authorization to particular permissions on the account.

Token Exchange Response

The response to any of the previous direct authorization token exchange requests looks like this example:

HTTP/1.1 201 Created
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 1200
{
  "access_token": {
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "token": "HRKU-01234567-89ab-cdef-0123-456789abcdef"
  },
  "client": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example",
    "redirect_uri": "https://example.com/auth/heroku/callback"
  },
  "created_at": "2012-01-01T12:00:00Z",
  "grant": {
    "code": "01234567-89ab-cdef-0123-456789abcdef",
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef"
  },
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "refresh_token": {
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "token": "01234567-89ab-cdef-0123-456789abcdef"
  },
  "scope": [
    "global"
  ],
  "updated_at": "2012-01-01T12:00:00Z"
}

Subsequent requests should use the access token’s token value in the Authorization header. For example, given the token 01234567-89ab-cdef-0123-456789abcdef, you’d set the header to Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef.

Access tokens acquired through the direct authorization flow do not expire.

Revoking Authorization

Revoking an authorization will block associated tokens from making further requests.

DELETE /oauth/authorizations/{authorization-id}

Curl Example

$ curl -X DELETE https://api.heroku.com/oauth/authorizations/$AUTHORIZATION_ID \
-H "Accept: application/vnd.heroku+json; version=3" \
-H "Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef"

Response

HTTP/1.1 200 OK
ETag: "0123456789abcdef0123456789abcdef"
Last-Modified: Sun, 01 Jan 2012 12:00:00 GMT
RateLimit-Remaining: 1200
{
  "access_token": {
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "token": "HRKU-01234567-89ab-cdef-0123-456789abcdef"
  },
  "client": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "example",
    "redirect_uri": "https://example.com/auth/heroku/callback"
  },
  "created_at": "2012-01-01T12:00:00Z",
  "grant": {
    "code": "01234567-89ab-cdef-0123-456789abcdef",
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef"
  },
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "refresh_token": {
    "expires_in": 2592000,
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "token": "01234567-89ab-cdef-0123-456789abcdef"
  },
  "scope": [
    "global"
  ],
  "updated_at": "2012-01-01T12:00:00Z"
}

Resources and Examples

  • Platform API Reference
  • Heroku CLI plugin to manage OAuth clients and authorizations
  • Ruby sample app demonstrating OAuth
  • Go sample app demonstrating OAuth
  • OmniAuth Strategy for Heroku
  • Ruby Rack middleware Heroku Bouncer
  • Python WSGI middleware

Limit Access to Apps via OAuth

Heroku administrators can deny OAuth access to team-owned resources from all non-Heroku products and services. Turn off third-party OAuth access to the Heroku Platform API in the Settings tab of the team. Team members can ​still​ OAuth with Heroku, but team resources aren’t accessible.

Limiting access to apps via OAuth

When third-party OAuth access is disabled, API calls attempted against team apps return a failure. Previously configured services set up with an app in a personal account or team risk breaking if you transfer that app to a team with third-party OAuth access disabled.

Some third-party add-ons use OAuth and can be blocked regardless of Add-on Controls settings.

Keep reading

  • Platform API

Feedback

Log in to submit feedback.

Setting Up Apps Using the Platform API Pipelines Using the Platform API

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