Heroku Connect API
Last updated August 28, 2023
Table of Contents
Heroku Connect provides an API to automate the creation, maintenance, and monitoring of sync operations between Salesforce and a Heroku PostgreSQL database.
A good way to work with the Heroku Connect API is to use the Heroku Connect CLI plugin. The plugin is useful for scripting Heroku Connect and offers some demonstration on how to make Heroku Connect API calls.
Version Info
Heroku supports version 3 of the Heroku Connect API. Heroku communicates certain changes made to the API, as well as any new API versions as outlined in the compatibility policy.
Getting Started
Check out the Quick Start: Heroku Connect API tutorial. This tutorial guides you through setting up Heroku Connect through the Heroku CLI and the Heroku Connect API.
Authentication
The Heroku Connect API requires a Heroku Platform API direct authorization token. This token is for your own application’s Heroku user only. Heroku Connect doesn’t support API access on behalf of other Heroku customers.
Supply this token with the Authorization
header, like this:
Authorization: Bearer <token>
Add User to the Heroku Connect Access List
By default, no users are present on a Heroku Connect add-on. Add your Heroku user account to the access list:
POST https://hc-central.heroku.com/auth/<app_name_or_app_uuid>
Example:
$ curl -X POST https://hc-central.heroku.com/auth/example-app \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
This returns all Connect add-ons across all regions that you have access to. You can filter the data with a tool like jq
. This data includes a region_url
. Adding /api/v3
to the end of this region_url
gives you the root Heroku Connect API v3 URL for your connection. See Root Endpoints for more info.
Request Methods
Most of the Heroku Connect API responds to either GET
or POST
requests. There are some cases that use other methods, including PUT
, DELETE
and PATCH
. Most HTTP libraries support these methods, but some environments, including Apex code on the Force.com platform, only support a subset. In order to use these additional endpoints, it’s possible to use a POST
request with an additional header that indicates the desired HTTP method:
X-HTTP-Method-Override: PATCH
JSON Encoded Request Payloads and Responses
POST
/PATCH
request payloads and all API responses are JSON-encoded. Supply the Content-Type
header for these requests:
Content-Type: application/json
Rate Limits
The API is rate-limited at 5,000 requests per connection per day. Attempting to access the API after this limit results in 429 Too Many Requests
. The response message also shows when you can expect to make another API request.
{"message":"Request was throttled. Expected available in 72170 seconds."}
Root Endpoints
Heroku Connect operates in many regions, each responding on a different domain. The root API URLs are as follows:
Region | Root API URL |
---|---|
Dublin (EU) | https://connect-dublin.heroku.com/api/v3 , orhttps://connect-2-dublin.heroku.com/api/v3 - see the note that follows this table. |
Frankfurt | https://connect-frankfurt.heroku.com/api/v3 |
London | https://connect-london.heroku.com/api/v3 |
Montreal | https://connect-montreal.heroku.com/api/v3 |
Mumbai | https://connect-mumbai.heroku.com/api/v3 |
Oregon | https://connect-oregon.heroku.com/api/v3 |
Singapore | https://connect-singapore.heroku.com/api/v3 |
Sydney | https://connect-sydney.heroku.com/api/v3 |
Tokyo | https://connect-tokyo.heroku.com/api/v3 |
Virginia (US) | https://connect-virginia.heroku.com/api/v3 ,https://connect-2-virginia.heroku.com/api/v3 , orhttps://connect-3-virginia.heroku.com/api/v3 , orhttps://connect-4-virginia.heroku.com/api/v3 - see the note that follows this table. |
In the Virginia (US) and Dublin (EU) regions, the root API URL depends on the cell that your connection is in. You can find the base URL of the cell by going to the connection’s Manage Connection page and using the Cell URL value.
Previously, we listed the Root API URL of the EU region as https://connect-eu.heroku.com/api/v3
and the Root API URL of the US region as https://connect-us.heroku.com/api/v3
. These URLs are aliases of the Dublin (EU) and Virginia (US) URLs, respectively, and continue to work.
You must use the API endpoint that corresponds to the region your app resides in, which you can check by using the Heroku CLI.
$ heroku info -a <app_name>
=== <app_name>
Git Url: git@heroku.com:<app_name>.git
Web Url: https://<app_name>-<random-identifier>.herokuapp.com/
Addons: heroku-postgresql:standard-0
herokuconnect:enterprise
…
Region: us
…
Select the endpoint prefix for a central location for your app. You can change this later if your needs expand into multiple regions.
Connection Endpoints
Use these endpoints to get info and help maintain your connection.
Get Connections List
Retrieve a list of all Heroku Connect connections you have access to, along with some details.
GET /connections
Example:
$ curl -X GET https://connect-3-virginia.heroku.com/api/v3/connections \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-H "Content-Type: application/json"
Example response:
{
"count":1,
"next":null,
"previous":null,
"results":[
{
"id":"c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
"_id":76070,
"name":"",
"addon_id":"c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
"app_name":"example-app",
"team_name":null,
"app_id":"a63e5256-3c1c-4382-ba99-158fc63f8945",
"schema_name":"salesforce",
"db_key":"DATABASE_URL",
"database":{
"host":"ec2-34-194-215-27.compute-1.amazonaws.com",
"database":"d6mah9u2hj7110",
"port":5432
},
"organization_id":"00D4W0000054k3cUAA",
"state":"POLLING_DB_CHANGES",
"mappings_summary_state":"OK",
"detail_url":"/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
…
}
Get Connection Details
Retrieve details about a specific connection.
GET /connections/<connection_id>
Query String Parameter | Type | Description | Example |
---|---|---|---|
deep |
boolean | Returns info about the connection’s mappings, in addition to the connection itself when set to true . Defaults to false |
true , false |
Example:
$ curl -X GET "https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4?deep=true" \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
Example response:
{
"id": "c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
"name": "example-app",
"resource_name": "herokuconnect-defined-93233",
"schema_name": "salesforce",
"db_key": "DATABASE_URL",
"state": "IDLE",
"mappings": [
{
"id": "7b5a2105-9845-43cd-9648-9406ee745bf5",
"object_name": "Account",
"state": "DATA_SYNCED",
…
},
{
"id": "3f87cb43-2b2b-4a40-a396-d3611cb776b4",
"object_name": "Contact",
"state": "DATA_SYNCED",
…
},
…
]
…
}
The response contains details about your connection, as well as mappings if deep
is true
. Check that the state of your connection and mappings to ensure things are working as expected. See the Connection States Reference and the Mapping States Reference articles for more info.
Configure a Connection’s Database and Schema
Set the Heroku Postgres database and the name of the schema used to store Salesforce data.
PATCH /connections/<connection_id>
Parameter | Type | Description | Example |
---|---|---|---|
database_key |
string | Corresponds to the config var for your Heroku Postgres database. | "DATABASE_URL" , "HEROKU_POSTGRESQL_AQUA_URL" |
schema_name |
string | The name of the schema used to store Salesforce data. Typically, the name used is "salesforce" . |
"salesforce" , "example-schema" |
Example request:
$ curl -X PATCH https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4 \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-H "Content-Type: application/json" \
-d '{"schema_name": "salesforce", "db_key": "DATABASE_URL"}'
Example response:
{
"id": "c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
"name": "example-app",
"resource_name": "herokuconnect-defined-93233",
"schema_name": "salesforce",
"db_key": "DATABASE_URL"
}
Authenticate the Connection to Your Salesforce Org
Retrieve the authorization URL.
POST /connections/<connection_id>/authorize_url
Parameter | Type | Description | Example |
---|---|---|---|
environment |
string | Specifies the type of your Salesforce org. Defaults to "sandbox" . |
"production" , "sandbox" , or "custom" |
domain |
string | Specifies a custom login domain, if using a custom environment. | "example.my.salesforce.com" |
api_version |
string | Specifies a Salesforce API version to use. Defaults to the latest supported version. | "52.0" |
next |
string | Final URL to redirect the user. Defaults to the Heroku Connect dashboard. | "https://example-redirect.com" |
Example request:
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/authorize_url \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-H "Content-Type: application/json" -d '{"environment": "production"}'
Example response:
{"redirect": "https://connect-3-virginia.heroku.com/oauth/start/…"}
The Salesforce user must open this URL to complete the authentication. In a typical application, you could retrieve the authorization URL and link it to a button to show to the user. When authentication is complete, it redirects the user to the url provided in the next
parameter, or the Heroku Connect dashboard if it wasn’t provided.
Pause the Connection
POST /connections/<connection_id>/actions/pause
Pause an active connection to prevent data sync.
Example:
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/actions/pause \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
A successful response has a 202 HTTP status code. Check the connection’s state to verify that it’s PAUSED
.
Connections can only be paused when they are in the IDLE
state. If your connection remains in the POLLING_DB_CHANGES
status for an extended period, check your logs to debug.
After the connection is paused, you can resume it using a related endpoint.
Resume the Connection
POST /connections/<connection_id>/actions/resume
Resume a paused connection.
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/actions/resume \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
A successful response has a 202 HTTP status code. Check the connection’s state to verify that it’s no longer PAUSED
.
Restart the Connection
You can restart a connection at any time, which clears system errors and attempts to sync data again. If the errors have been resolved, this action gets the connection back in working order. Otherwise, the connection and its mappings can revert to an error state when errors are next encountered. This action is equivalent to the Recover from error
button in the Heroku Connect Dashboard.
POST /connections/<connection_id>/actions/restart
Example:
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/actions/restart \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
A successful response has a 202 HTTP status code. Get the connection’s details to verify that it’s no longer in an error state.
Export Configuration
You can export a connection’s mapping configuration to JSON. The resulting export can be imported into another connection to configure its mappings.
POST /connections/<connection_id>/actions/export
Example:
curl -X GET https://connect-3-virginia.heroku.com/api/v3/connections/1ac07199-0ddb-43e9-9865-8d9721ca6c6e/actions/export \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
--output config.json
This example uses --output
to save the JSON response to a config.json
file.
Example response when --output
isn’t used:
{"mappings":[{"object_name":"Account","config":{"access":"read_write","sf_notify_enabled":false,"sf_polling_seconds":600,...}
The import configuration endpoint accepts both JSON files and JSON sent directly in the request body.
Import Configuration
The easiest way to configure mappings for a connection is to import an existing configuration. After exporting an existing configuration, you can import it with this endpoint:
POST /connections/<connection_id>/actions/import
This endpoint accepts the configuration details either as a standard file upload or directly as JSON in the request body.
Example:
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/actions/import \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-F "config=@config.json"
Or:
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/actions/import \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-H "Content-Type: application/json" \
-d @config.json
If you receive no error, use the connection details endpoint. Set the query string parameter deep
to true
to see a list of your connection’s mappings.
Mapping Endpoints
Use these endpoints to get info and help maintain your mappings.
Get Mappings List
To retrieve a list of your connection’s mappings, use the connection details endpoint and set the query string parameter deep
to true
. Setting this parameter returns a list of the connection’s mappings, including their id
s, which you can use for the other mapping endpoints described in this article. See Get Connection Details for more info.
Get Mapping Details
Retrieve details about a mapping.
GET /mappings/<mapping_id>
Example:
$ curl -X GET https://connect-3-virginia.heroku.com/api/v3/mappings/7b5a2105-9845-43cd-9648-9406ee745bf5 \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
The response contains configuration details for the mapping, status, and additional URLs for obtaining related information.
Example response:
{
"access": "read_only",
"actively_writing": false,
"config": {
"access": "read_only",
"fields": {
"CreatedDate": {},
"Id": {},
"IsDeleted": {},
"SystemModstamp": {}
},
"indexes": {
"Id": {
"unique": false
},
"SystemModstamp": {
"unique": false
}
},
"revision": 12345,
"sf_notify_enabled": true,
"sf_polling_seconds": 600
},
"connection": {
"id": "c08fdb87-a196-46aa-8b44-5ad6e9e253c4"
},
"counts": {
"db": 0,
"errors": 0,
"pending": 0,
"sf": 0
},
"detail_url": "https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4",
"id": "7b5a2105-9845-43cd-9648-9406ee745bf5",
"object_name": "Account",
"state": "DATA_SYNCED",
"state_description": "OK",
"times": {
"db_poll": "<date>",
"db_write": "<date>",
"sf_poll": "<date>",
"sf_write": "<date>",
},
}
Create a Mapping
In addition to importing an entire configuration at once, you can add a single mapping at a time to an existing connection.
POST /connections/<connection_id>/mappings
The JSON payload of this API endpoint contains detailed configuration for the mapping itself:
Name | Type | Description | Example |
---|---|---|---|
object_name |
string | The name of the Salesforce object to map. | "Account" |
config |
object | Heroku Connect configuration info. Contains other fields that follow in this table. | See the example that follows this table. |
access |
string | Indicates whether to configure the mapping for read-only access from Salesforce to Heroku Postgres or read-write in both directions. | "read_only" or "read_write" |
fields |
object | Represents the fields to map for the object. Each field name is an attribute on the object, with its value being an empty object. | See the example that follows this table. |
indexes |
object | Represents the indexes to include for the object. Each index is provided as an attribute whose name is the field name. The value is an object with a unique Boolean setting, indicating whether the index requires unique values. |
See the example that follows this table. |
Example:
curl -X POST https://connect-3-virginia.heroku.com/api/v3/connections/c08fdb87-a196-46aa-8b44-5ad6e9e253c4/mappings \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8" \
-H 'Content-Type: application/json' \
-d @- << EOF
{
"object_name": "Account",
"config": {
"access": "read_only",
"sf_notify_enabled": true,
"sf_polling_seconds": 600,
"fields": {
"CreatedDate": {},
"Id": {},
"IsDeleted": {},
"Name": {},
"SystemModstamp": {}
},
"indexes": {
"Id": {
"unique": true
},
"SystemModstamp": {
"unique": false
}
}
}
}
EOF
If the values provided are valid, the response code to this endpoint is a 201 Created, with full details for the created mapping in the payload of the response. The response payload has the same output as the mapping details endpoint.
If there were any errors in the input, the response code is 400 Bad Request, with details about the errors in the JSON payload for the response.
Edit a Mapping
You can edit existing mappings individually.
PUT /mappings/<mapping_id>
The payload is nearly identical to what you’d send when creating a mapping. The difference is the presence of a revision
attribute. Existing mappings have a revision
attribute in their mapping details, which you can retrieve with the API.
The revision
value must be sent back, unchanged, in the PUT edit mapping request. This value allows the API to ensure that the mapping hasn’t been updated by someone else before you had a chance to post it back. The ideal workflow would be to retrieve the details for the mapping, extract the config
attribute, make appropriate changes, then PUT it back to the same URL.
Successful responses return a 200 OK, with the entire mapping payload included.
Like the creation endpoint, most errors return a 400 Bad Request with details included in the response payload. If the revision
sent back doesn’t match what’s current for the mapping, a 409 Conflict returns. This 409 prevents multiple people or processes from modifying the same mapping in conflicting ways.
Delete a Mapping
You can delete mappings individually.
DELETE /mappings/<mapping_id>
$ curl -X DELETE https://connect-3-virginia.heroku.com/api/v3/mappings/7b5a2105-9845-43cd-9648-9406ee745bf5 \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
This endpoint returns with a 204 No Content indicating that you deleted the mapping. Additional tasks, including removing data from your database, can still run after this response returns.
Reload a Mapping
If a table in your PostgreSQL database gets out of sync with Salesforce, use the API to clear out the Postgres table and pull fresh data from Salesforce.
POST /mappings/<mapping_id>/actions/reload
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/mappings/7b5a2105-9845-43cd-9648-9406ee745bf5/actions/reload \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
A successful response has a 202 HTTP status code. Get the mapping’s details to check its current state.
Abort a Mapping
Aborting a mapping cancels all operations running on that mapping, allowing for other actions to take place. Aborting a mapping can be useful if an operation is running longer than expected, or was started accidentally.
POST /mappings/<mapping_id>/actions/abort
$ curl -X POST https://connect-3-virginia.heroku.com/api/v3/mappings/7b5a2105-9845-43cd-9648-9406ee745bf5/actions/abort \
-H "Authorization: Bearer 86b831b4-c3e8-4a3f-93bf-ca9ffa6dfdc8"
A successful response has a 202 HTTP status code. Aborting some operations result in normal sync with the next poll. Other operations require reloading the mapping after aborting before sync can resume. See States and Aborted Mapping Operations for when a reload is required. Get the mapping’s details to check its current state.
Compatibility Policy
The Heroku Connect API is under regular development, and changes occur over time. Some changes, such as new endpoints, new input, or new payload content, don’t affect existing behavior. These changes can happen at any time. Other changes that modify or remove existing behavior have the following policy to help ensure compatibility with existing applications.
For stable endpoints, Heroku communicates upcoming incompatible changes to all users at least 30 days before their deployment. This notification includes the nature of the change, the reasoning behind it, and steps you must take to migrate from the old to the new behavior. This document also includes these details for the 30-day duration. After the 30 days have passed, the new behavior goes live and the old behavior is removed from this document.
Unless otherwise stated, all documented API endpoints are stable. This document explicitly identifies any endpoints or behaviors that are experimental. Experimental features are made available in order to get feedback from users of the API, and can change at any time, with no notice.
Before releasing a new version, it’s made available as an experimental feature until it’s ready to replace the existing version. At that time, the root endpoints update. Heroku communicates this change before removing the old version with the same 30-day notice outlined in the compatibility policy.