Setting Up Apps Using the Platform API
Last updated May 14, 2025
Table of Contents
This article describes how to use the app-setups
resource of the Heroku Platform API to programmatically set up a Heroku app. The app-setups
resource, together with an app.json
manifest file in your source code, enables you to automate app configuration and deployment.
App setups power Heroku Button. Add a Heroku Button to your README
or documentation to help others deploy your app quickly.
Use Cases
Use app.json
and app-setups
to:
- Help collaborators deploy your app to Heroku for testing or staging.
- Distribute a ready-to-deploy app or framework for others to try on Heroku.
How App Setups Work
The app-setups
resource accepts a .tar
archive of your app’s source code. It looks for the app.json
manifest and uses it to orchestrate the initial setup on Heroku. This process streamlines deployment and release.
Prepare Your App
This example uses the heroku/node-js-sample
app. The process applies to any language, but this guide focuses on Node.js.
Add an
app.json
file to your app’s root directory. For example, you can include:- Config vars to customize the app.
- Add-ons, such as Papertrail for logging and Heroku Postgres for the database.
- A
postdeploy
command to prepare the database.
Obtain the tarball URL for your app. For public GitHub repos, use:
https://github.com/<username>/<repo name>/tarball/master/
For the sample app, use https://github.com/heroku/node-js-sample/tarball/master/.
Create an App Setup
Call the https://api.heroku.com/app-setups
endpoint with your source tarball. The request body must include the tarball URL.
Example using cURL:
curl -n -X POST https://api.heroku.com/app-setups \
-H "Content-Type:application/json" \
-H "Accept:application/vnd.heroku+json; version=3" \
-d '{"source_blob": { "url":"https://github.com/heroku/node-js-sample/tarball/master/"}}'
To override environment variables defined in app.json
, add an overrides
section:
curl -n -X POST https://api.heroku.com/app-setups \
-H "Content-Type:application/json" \
-H "Accept:application/vnd.heroku+json; version=3" \
-d '{"source_blob": { "url":"https://github.com/heroku/node-js-sample/tarball/master/"}, "overrides": {"env": { "NODE_ENV":"development" }}}'
Heroku starts the setup and returns a response with an ID for tracking:
{
"id": "df1c2983-fbde-455b-8e7b-e17c16bdf757",
"failure_message": null,
"status": "pending",
"app": {
"id": "888ee9fb-c090-499b-a115-2f335a1f0ef5",
"name": "example-app"
},
"build": {
"id": null,
"status": null
},
"manifest_errors": [],
"postdeploy": {
"output": null,
"exit_code": null
},
"resolved_success_url": null,
"created_at": "2014-05-09T18:41:35+00:00",
"updated_at": "2014-05-09T18:41:35+00:00"
}
If app creation fails, you receive a response with details:
{
"id": "invalid_params",
"message": "You've reached the limit of 5 apps for unverified accounts. Add a credit card to verify your account."
}
Check Setup Status
Poll the API for status updates using the returned ID:
curl -n https://api.heroku.com/app-setups/df1c2983-fbde-455b-8e7b-e17c16bdf757 \
-H "Content-Type:application/json" \
-H "Accept:application/vnd.heroku+json; version=3"
When the build is kicked off, you see a response like:
{
"id": "df1c2983-fbde-455b-8e7b-e17c16bdf757",
"failure_message": null,
"status": "pending",
"app": {
"id": "888ee9fb-c090-499b-a115-2f335a1f0ef5",
"name": "example-app"
},
"build": {
"id": "06503167-f75e-4ad6-bd06-4d5da3825eb5",
"status": "pending"
},
"resolved_success_url": null
// ...
}
If there are issues during setup, the response indicates the errors:
{
"id": "df1c2983-fbde-455b-8e7b-e17c16bdf757",
"failure_message": "app.json not found",
"status": "failed",
"app": {
"id": "888ee9fb-c090-499b-a115-2f335a1f0ef5",
"name": "example-app"
}
// ...
}
If setup fails, Heroku deletes the app, but the setup status remains available.
Get Build Details
After the build completes, use the app name and build ID to get detailed build output:
curl -n -X GET https://api.heroku.com/apps/example-app/builds/06503167-f75e-4ad6-bd06-4d5da3825eb5/result \
-H "Content-Type:application/json" \
-H "Accept:application/vnd.heroku+json; version=3"
This returns detailed build results, including every line of the build output:
{
"build": {
"id": "06503167-f75e-4ad6-bd06-4d5da3825eb5",
"status": "succeeded"
},
"exit_code": 0,
"lines": [
{
"stream": "STDOUT",
"line": "\n"
},
{
"stream": "STDOUT",
"line": "-----> Node.js app detected\n"
}
// ...
]
}
The output of the postdeploy
script is provided inline within the response to the polling request for the overall setup status:
"postdeploy": {
"output": "",
"exit_code": 0
}
When the status is succeeded
, the resolved_success_url
is populated with a fully-qualified URL to redirect users after setup. The value is derived from the success_url
attribute in the app.json
manifest file:
"resolved_success_url": "http://example-app.herokuapp.com/"
What Happens During Setup
- The API provisions add-ons after creating the app, before building.
- The
env
section inapp.json
defines config vars. You can override these when calling the API. - The
scripts.postdeploy
command runs on a one-off dyno after the app is released.
Application Metadata
Fields like name
, description
, website
, repository
, and logo
provide information for users, but aren’t used by the API during setup.
{
"name": "Node.js Sample",
"description": "A barebones Node.js app using Express 4.",
"website": "https://nodejs.org"
}
Environment Variables
The env
section defines config vars for the app:
{
"env": {
"NODE_ENV": "production",
"COOKIE_SECRET": {
"description": "This gets generated",
"generator": "secret"
},
"SETUP_BY": {
"description": "Who initiated this setup",
"required": false
}
}
}
A variable can have a description and a default value. The Platform API request may include an overrides
section to provide values to override these defaults. Required variables must be provided, or setup fails. Optional variables can be specified with "required": false
. The secret
generator creates a 64-character hex string.
Add-ons
The API provisions add-ons after creating the app:
{
"addons": ["heroku-postgresql:essential-0", "papertrail"]
}
If no tier is specified, the free tier is used.
Post-deployment Scripts
You can specify a postdeploy
script in app.json
. It runs on a one-off dyno after the app is built and released.
{
"scripts": {
"postdeploy": "npm run db:migrate"
}
}
For multiple commands, use a script file and reference it in postdeploy
.
After Deployment
Your app is ready to serve traffic. The app has config vars and add-ons provisioned as defined in app.json
.
Example config vars:
heroku config -a example-app
=== example-app Config Vars
COOKIE_SECRET: 1e1867380b9365f2c212e31e9c43a87c17e82be0ce1a61406ea8274fac0680dc
DATABASE_URL: postgres://...
HEROKU_POSTGRESQL_ONYX_URL: postgres://...
PAPERTRAIL_API_TOKEN: ...
NODE_ENV: development
SETUP_BY: MyDeployerScript
Example add-ons:
heroku addons -a example-app
=== example-app Configured Add-ons
heroku-postgresql:essential-0 HEROKU_POSTGRESQL_ONYX
papertrail:choklad
The database is migrated, and the app is ready to serve traffic.
The Git repo is set up for you. To continue development, clone the app’s repo:
heroku git:clone example-app