TL;DR
Heroku API memungkinkan otomasi deployment, pengelolaan aplikasi, konfigurasi add-on, dan penskalaan infrastruktur dengan RESTful endpoint dan autentikasi berbasis token. Mendukung OAuth 2.0, rate limit 10.000 request/jam, serta endpoint untuk aplikasi, dyno, build, dan pipeline. Panduan ini membahas setup autentikasi, endpoint utama, integrasi CI/CD, dan strategi deployment produksi.
Pendahuluan
Heroku mendukung jutaan aplikasi secara global. Untuk pengembang yang ingin mengotomatiskan deployment, membuat pipeline CI/CD, atau membangun alat manajemen multi-aplikasi, integrasi Heroku API wajib diimplementasikan.
Tanpa otomasi, tim dengan 10+ aplikasi Heroku dapat kehilangan 8-12 jam tiap minggu untuk deployment manual dan pengubahan konfigurasi. Dengan integrasi API yang baik, Anda bisa mengotomasi deployment, menskalakan dyno sesuai traffic, dan menyinkronkan konfigurasi di berbagai environment.
Panduan ini berisi langkah-langkah praktis integrasi Heroku API: autentikasi token, manajemen aplikasi & dyno, pipeline, provisioning add-on, hingga troubleshooting. Setelah mengikuti panduan, integrasi Heroku Anda siap produksi.
💡 Tips: Apidog menyederhanakan pengujian integrasi API. Uji endpoint Heroku, validasi alur autentikasi, periksa response, dan debug konfigurasi dalam satu workspace. Bisa impor spesifikasi API, mock response, dan share skenario pengujian ke tim.
Apa Itu Heroku API?
Heroku menyediakan Platform API RESTful untuk manajemen aplikasi dan infrastruktur. Dengan API ini, Anda bisa:
- Membuat, mengkonfigurasi, dan menghapus aplikasi
- Menskalakan dyno & manajemen proses
- Manajemen build & rilis
- Provisioning & konfigurasi add-on
- Manajemen pipeline & promosi
- Manajemen domain & sertifikat SSL
- Pengaturan log drain & monitoring
- Manajemen tim & kolaborator
Fitur Utama
| Fitur | Deskripsi |
|---|---|
| Desain RESTful | HTTP standar & respons JSON |
| Otentikasi Token | Bearer token, support OAuth 2.0 |
| Permintaan Rentang | Paginasi hasil besar |
| Pembatasan Laju | 10.000 request/jam/akun |
| Pembuatan Idempoten | Retry aman untuk operasi write |
| Kompresi Gzip | Kompresi respons untuk efisiensi bandwidth |
Gambaran Arsitektur API
Struktur API Heroku:
https://api.heroku.com/
Mengikuti spesifikasi JSON:API untuk resource & relasi konsisten.
Perbandingan Versi API
| Versi | Status | Otentikasi | Kasus Penggunaan |
|---|---|---|---|
| Platform API (v3) | Current | Bearer token | Semua integrasi baru |
| Integrasi GitHub | Current | OAuth 2.0 | App terhubung GitHub |
| Registri Kontainer | Current | Auth Docker | Deployment kontainer |
Memulai: Pengaturan Autentikasi
Langkah 1: Buat Akun Heroku
- Kunjungi Heroku
- Klik Daftar dan buat akun
- Verifikasi email
- Selesaikan setup akun
Langkah 2: Install Heroku CLI
Install CLI untuk generate token API & test perintah:
# macOS
brew tap heroku/brew && brew install heroku
# Windows
npm install -g heroku
# Linux
curl https://cli-assets.heroku.com/install.sh | sh
Langkah 3: Generate Token API
Autentikasi via CLI:
# Login Heroku (akan buka browser)
heroku login
Ambil token API:
# Token sementara (short-lived)
heroku authorizations:create --short-lived
# Token jangka panjang (untuk CI/CD)
heroku authorizations:create --description "CI/CD Pipeline" --expires-in "1 year"
Keamanan: Simpan token di environment variable, jangan hardcode.
# file .env
HEROKU_API_KEY="kunci_api_anda"
HEROKU_APP_NAME="nama-aplikasi-anda"
Langkah 4: Pahami Autentikasi Token
Header API:
Authorization: Bearer {api_key}
Accept: application/vnd.heroku+json; version=3
Harus disertakan di setiap request.
Langkah 5: Coba Panggilan API Pertama
Tes autentikasi:
curl -n https://api.heroku.com/account \
-H "Accept: application/vnd.heroku+json; version=3" \
-H "Authorization: Bearer $HEROKU_API_KEY"
Respons:
{
"id": "user-id-here",
"email": "developer@example.com",
"name": "Developer Name",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2026-03-20T14:22:00Z"
}
Langkah 6: Implementasi Autentikasi di Kode
Reusable API client (Node.js):
const HEROKU_API_KEY = process.env.HEROKU_API_KEY;
const HEROKU_BASE_URL = 'https://api.heroku.com';
const herokuRequest = async (endpoint, options = {}) => {
const response = await fetch(`${HEROKU_BASE_URL}${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${HEROKU_API_KEY}`,
'Accept': 'application/vnd.heroku+json; version=3',
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Heroku API Error: ${error.message}`);
}
return response.json();
};
// Contoh penggunaan
const account = await herokuRequest('/account');
console.log(`Login sebagai: ${account.email}`);
Manajemen Aplikasi
Membuat Aplikasi Baru
const createApp = async (appName, region = 'us') => {
const response = await herokuRequest('/apps', {
method: 'POST',
body: JSON.stringify({
name: appName,
region: region
})
});
return response;
};
// Penggunaan
const app = await createApp('my-awesome-app-2026');
console.log(`Aplikasi dibuat: ${app.name}`);
console.log(`URL Git: ${app.git_url}`);
console.log(`URL Web: ${app.web_url}`);
Respons Aplikasi
{
"id": "app-uuid-here",
"name": "my-awesome-app-2026",
"region": { "name": "us" },
"created_at": "2026-03-25T10:00:00Z",
"updated_at": "2026-03-25T10:00:00Z",
"git_url": "https://git.heroku.com/my-awesome-app-2026.git",
"web_url": "https://my-awesome-app-2026.herokuapp.com",
"owner": { "email": "developer@example.com" },
"build_stack": { "name": "heroku-24" }
}
List Aplikasi
const listApps = async (limit = 50) => {
const response = await herokuRequest(`/apps?limit=${limit}`);
return response;
};
// Penggunaan
const apps = await listApps();
apps.forEach(app => {
console.log(`${app.name} - ${app.web_url}`);
});
Detail Aplikasi
const getApp = async (appName) => {
const response = await herokuRequest(`/apps/${appName}`);
return response;
};
// Penggunaan
const app = await getApp('my-awesome-app-2026');
console.log(`Stack: ${app.build_stack.name}`);
console.log(`Wilayah: ${app.region.name}`);
Update Konfigurasi Aplikasi
const updateApp = async (appName, updates) => {
const response = await herokuRequest(`/apps/${appName}`, {
method: 'PATCH',
body: JSON.stringify(updates)
});
return response;
};
// Ubah nama aplikasi
const updated = await updateApp('old-app-name', {
name: 'new-app-name'
});
Hapus Aplikasi
const deleteApp = async (appName) => {
await herokuRequest(`/apps/${appName}`, {
method: 'DELETE'
});
console.log(`Aplikasi ${appName} berhasil dihapus`);
};
Manajemen Dyno
Skalakan Dyno
const scaleDyno = async (appName, processType, quantity) => {
const response = await herokuRequest(`/apps/${appName}/formation/${processType}`, {
method: 'PATCH',
body: JSON.stringify({
quantity: quantity
})
});
return response;
};
// Skalakan dyno web ke 3
const formation = await scaleDyno('my-app', 'web', 3);
console.log(`Diskalakan ke ${formation.quantity} dyno ${processType}`);
Lihat Formasi Dyno
const getFormation = async (appName, processType = null) => {
const endpoint = processType
? `/apps/${appName}/formation/${processType}`
: `/apps/${appName}/formation`;
const response = await herokuRequest(endpoint);
return response;
};
// Penggunaan
const formation = await getFormation('my-app');
formation.forEach(proc => {
console.log(`${proc.type}: ${proc.quantity} dyno (@ ${proc.size})`);
});
Ukuran Dyno
| Jenis Dyno | Kasus Penggunaan | Biaya/Bulan |
|---|---|---|
| eco | Proyek hobi, demo | $5 |
| basic | App produksi kecil | $7 |
| standard-1x | Beban kerja standar | $25 |
| standard-2x | App performa tinggi | $50 |
| performance | App kritis produksi | $250+ |
| private | Isolasi perusahaan | Kustom |
Restart Dyno
const restartDynos = async (appName, processType = null) => {
const endpoint = processType
? `/apps/${appName}/formation/${processType}`
: `/apps/${appName}/dynos`;
await herokuRequest(endpoint, {
method: 'DELETE'
});
console.log(`Dyno dimulai ulang untuk ${appName}`);
};
Dyno Sekali Pakai
const runCommand = async (appName, command) => {
const response = await herokuRequest(`/apps/${appName}/dynos`, {
method: 'POST',
body: JSON.stringify({
command: command,
size: 'standard-1x'
})
});
return response;
};
// Jalankan migrasi database
const dyno = await runCommand('my-app', 'npm run migrate');
console.log(`Dyno dimulai: ${dyno.id}`);
Variabel Konfigurasi
Dapatkan Variabel
const getConfigVars = async (appName) => {
const response = await herokuRequest(`/apps/${appName}/config-vars`);
return response;
};
// Penggunaan
const config = await getConfigVars('my-app');
console.log(`DATABASE_URL: ${config.DATABASE_URL}`);
console.log(`NODE_ENV: ${config.NODE_ENV}`);
Set Variabel
const setConfigVars = async (appName, variables) => {
const response = await herokuRequest(`/apps/${appName}/config-vars`, {
method: 'PATCH',
body: JSON.stringify(variables)
});
return response;
};
// Penggunaan
const updated = await setConfigVars('my-app', {
NODE_ENV: 'production',
API_SECRET: 'kunci-rahasia-anda',
LOG_LEVEL: 'info'
});
Best Practice Variabel
- Jangan hardcode rahasia: Gunakan env variable untuk data sensitif.
- Pisahkan per environment: Variabel staging ≠production.
- Rotasi rahasia rutin: Update API key/kata sandi tiap kuartal.
-
Prefix variabel: Misal
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET.
Manajemen Build & Rilis
Deploy Build
const createBuild = async (appName, sourceBlobUrl) => {
const response = await herokuRequest(`/apps/${appName}/builds`, {
method: 'POST',
body: JSON.stringify({
source_blob: {
url: sourceBlobUrl
}
})
});
return response;
};
// Deploy kode
const build = await createBuild('my-app', 'https://storage.example.com/source.tar.gz');
console.log(`Build dimulai: ${build.id}`);
console.log(`Status: ${build.status}`);
Status Build
const getBuild = async (appName, buildId) => {
const response = await herokuRequest(`/apps/${appName}/builds/${buildId}`);
return response;
};
// Polling status build
const checkBuildStatus = async (appName, buildId, maxAttempts = 30) => {
for (let i = 0; i < maxAttempts; i++) {
const build = await getBuild(appName, buildId);
if (build.status === 'succeeded') {
console.log('Build berhasil!');
return build;
} else if (build.status === 'failed') {
throw new Error(`Build gagal: ${build.output}`);
}
console.log(`Build running... percobaan ${i + 1}`);
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error('Waktu build habis');
};
List Rilis
const listReleases = async (appName, limit = 10) => {
const response = await herokuRequest(`/apps/${appName}/releases?limit=${limit}`);
return response;
};
// Penggunaan
const releases = await listReleases('my-app');
releases.forEach(release => {
console.log(`v${release.version} - ${release.description} - ${release.created_at}`);
});
Rollback Rilis
const rollback = async (appName, releaseId) => {
const response = await herokuRequest(`/apps/${appName}/releases`, {
method: 'POST',
body: JSON.stringify({
rollback: releaseId
})
});
return response;
};
// Rollback ke versi 42
const rollbackRelease = await rollback('my-app', 42);
console.log(`Rollback ke v${rollbackRelease.version}`);
Manajemen Pipeline
Buat Pipeline
const createPipeline = async (pipelineName) => {
const response = await herokuRequest('/pipelines', {
method: 'POST',
body: JSON.stringify({
name: pipelineName
})
});
return response;
};
// Penggunaan
const pipeline = await createPipeline('my-app-pipeline');
console.log(`Pipeline dibuat: ${pipeline.id}`);
Tambahkan App ke Pipeline
const addAppToPipeline = async (pipelineId, appName, stage) => {
const response = await herokuRequest('/pipeline-couplings', {
method: 'POST',
body: JSON.stringify({
pipeline: pipelineId,
app: appName,
stage: stage // 'development', 'staging', 'production'
})
});
return response;
};
// Penggunaan
await addAppToPipeline(pipelineId, 'my-app-dev', 'development');
await addAppToPipeline(pipelineId, 'my-app-staging', 'staging');
await addAppToPipeline(pipelineId, 'my-app-prod', 'production');
Promote Slug ke Stage Berikutnya
const promoteSlug = async (slugId, toApp) => {
await herokuRequest('/promotions', {
method: 'POST',
body: JSON.stringify({
from: toApp, // Sumber
to: toApp, // Target (stage berikutnya)
slug: slugId
})
});
console.log(`Slug ${slugId} dipromosikan ke ${toApp}`);
};
Manajemen Add-On
Provisioning Add-On
const provisionAddon = async (appName, addonPlan, config = {}) => {
const response = await herokuRequest('/addon-attachments', {
method: 'POST',
body: JSON.stringify({
app: appName,
plan: addonPlan,
config: config
})
});
return response;
};
// Provision PostgreSQL
const db = await provisionAddon('my-app', 'heroku-postgresql:mini', {});
console.log(`Database disediakan: ${db.addon.name}`);
console.log(`DATABASE_URL: ${db.addon.config_vars.DATABASE_URL}`);
Add-On Populer
| Add-On | Paket | Harga Mulai | Kasus Penggunaan |
|---|---|---|---|
| heroku-postgresql | mini | $5/bln | Database produksi |
| heroku-redis | mini | $5/bln | Caching, sesi |
| papertrail | choklad | $7/bln | Log agregasi |
| sentry | developer | Gratis | Pelacakan error |
| mailgun | sandbox | Gratis | Email service |
| newrelic | lite | Gratis | App monitoring |
List Add-On
const listAddons = async (appName) => {
const response = await herokuRequest(`/apps/${appName}/addons`);
return response;
};
// Penggunaan
const addons = await listAddons('my-app');
addons.forEach(addon => {
console.log(`${addon.plan.name} - $${addon.pricing.plan.price} - ${addon.state}`);
});
Hapus Add-On
const removeAddon = async (appName, addonId) => {
await herokuRequest(`/apps/${appName}/addons/${addonId}`, {
method: 'DELETE'
});
console.log(`Addon ${addonId} dihapus dari ${appName}`);
};
Domain & SSL
Tambah Domain Kustom
const addDomain = async (appName, domainName) => {
const response = await herokuRequest(`/apps/${appName}/domains`, {
method: 'POST',
body: JSON.stringify({
hostname: domainName
})
});
return response;
};
// Penggunaan
const domain = await addDomain('my-app', 'api.example.com');
console.log(`Target CNAME: ${domain.cname}`);
Konfigurasi SSL
const addSslCertificate = async (appName, domainId, certificateChain, privateKey) => {
const response = await herokuRequest(`/apps/${appName}/domains/${domainId}/ssl_endpoint`, {
method: 'PATCH',
body: JSON.stringify({
ssl_cert: {
cert_chain: certificateChain,
private_key: privateKey
}
})
});
return response;
};
SSL Otomatis (ACM)
const enableACM = async (appName, domainName) => {
const response = await herokuRequest(`/apps/${appName}/domains/${domainName}/sni_endpoint`, {
method: 'POST',
body: JSON.stringify({
kind: 'acm'
})
});
return response;
};
Pembatasan Laju & Kuota
Info Rate Limit
- Batas: 10.000 permintaan/jam/akun
- Window: 60 menit rolling
- Reset: Otomatis setelah window habis
- Jika melewati batas, response HTTP 429.
Implementasi Penanganan Rate Limit
Gunakan exponential backoff untuk retry:
const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await herokuRequest(endpoint, options);
// Cek header rate limit (jika tersedia)
const remaining = response.headers.get('RateLimit-Remaining');
const resetTime = response.headers.get('RateLimit-Reset');
if (remaining < 100) {
console.warn(`Kuota rendah: ${remaining}, reset pada ${resetTime}`);
}
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Rate limit tercapai. Ulangi dalam ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Header Rate Limit
| Header | Deskripsi |
|---|---|
RateLimit-Limit |
Maksimal request/jam |
RateLimit-Remaining |
Sisa request di window |
RateLimit-Reset |
Unix timestamp reset window |
Troubleshooting Umum
Masalah: Autentikasi 401
Solusi:
- Cek API key:
heroku authorizations - Pastikan token belum expired
- Cek spasi di env var
- Generate ulang token jika perlu:
heroku authorizations:create
Masalah: Nama App Sudah Dipakai
Solusi:
- Gunakan nama unik (tambah tim/sufiks/random)
- Generate nama UUID:
app-${Date.now()} - Prefix:
team-app-env
const generateUniqueAppName = (baseName) => {
const timestamp = Date.now().toString(36);
const random = Math.random().toString(36).substring(2, 6);
return `${baseName}-${timestamp}-${random}`;
};
Masalah: Formasi Dyno Gagal
Solusi:
- Pastikan process type ada di Procfile
- Cek kuota dyno tersedia
- Pastikan app tidak suspend
- Cek penggunaan dyno:
heroku ps --app=my-app
Masalah: Build Timeout
Solusi:
- Optimasi buildpack
- Cache dependencies dengan benar
- Pisahkan build besar jadi deployment kecil
- Gunakan slug prebuilt untuk deployment cepat
Masalah: Rate Limit Terlampaui (HTTP 429)
Solusi:
- Implementasi request queue
- Exponential backoff untuk retry
- Batch request jika bisa
- Monitor header rate limit
// Pembatas laju sederhana
class HerokuRateLimiter {
constructor(requestsPerMinute = 150) {
this.queue = [];
this.interval = 60000 / requestsPerMinute;
this.processing = false;
}
async add(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
this.process();
});
}
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
const { requestFn, resolve, reject } = this.queue.shift();
try {
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
}
if (this.queue.length > 0) {
await new Promise(r => setTimeout(r, this.interval));
}
}
this.processing = false;
}
}
Daftar Periksa Deployment Produksi
Sebelum go live:
- [ ] Gunakan token API jangka panjang (CI/CD)
- [ ] Simpan token di secret manager (Vault, AWS Secrets Manager)
- [ ] Implementasi rate limit & request queue
- [ ] Penanganan error komprehensif
- [ ] Logging untuk semua API call
- [ ] Monitor dyno hours
- [ ] Konfigurasikan log drain eksternal
- [ ] Setup pipeline promotion untuk CI/CD
- [ ] Aktifkan Automatic Certificate Management
- [ ] Backup database terjadwal
Monitoring & Alert
Contoh tracking metrik & alert:
const metrics = {
apiCalls: {
total: 0,
successful: 0,
failed: 0,
rateLimited: 0
},
dynoHours: {
used: 0,
quota: 1000
},
deployments: {
successful: 0,
failed: 0,
avg_duration: 0
}
};
// Alert tingkat kegagalan tinggi
const failureRate = metrics.apiCalls.failed / metrics.apiCalls.total;
if (failureRate > 0.05) {
sendAlert('Tingkat kegagalan Heroku API di atas 5%');
}
// Alert dyno hours
if (metrics.dynoHours.used > metrics.dynoHours.quota * 0.8) {
sendAlert('Penggunaan jam dyno di atas 80%');
}
Kasus Penggunaan Dunia Nyata
Pipeline CI/CD Otomatis
- Tantangan: Deployment manual = rawan error + lambat
- Solusi: GitHub Actions + Heroku API
- Hasil: Deployment tanpa downtime, rilis 90% lebih cepat
Alur:
- Push GitHub trigger workflow
- CI menjalankan test
- Heroku API melakukan build dari source blob
- Promote ke staging/production
- Notifikasi ke tim
Manajemen Multi-Lingkungan
- Tantangan: Sinkronisasi konfigurasi manual
- Solusi: Pusatkan manajemen konfigurasi via API
- Hasil: Konfigurasi konsisten, hemat 8 jam/minggu
Poin Integrasi:
- Sinkronisasi environment variable dev/staging/prod
- Provision add-on otomatis
- Operasi massal orientasi klien
Autoscale Berdasarkan Traffic
- Tantangan: Scaling manual saat traffic tinggi
- Solusi: Autoscale berbasis load dengan API
- Hasil: 0 downtime saat traffic spike 10x
Logika:
- Monitor response time via API metrik
- Scale up saat p95 latency > 500ms
- Scale down saat traffic rendah
- Alert jika penggunaan tinggi terus-menerus
Kesimpulan
Heroku API = akses lengkap ke fungsionalitas platform. Inti implementasi:
- Bearer token membutuhkan penyimpanan dan rotasi aman
- Rate limit (10K/jam) butuh monitoring aktif
- Manajemen pipeline = workflow CI/CD robust
- Error handling wajib untuk deployment andal
- Apidog memudahkan pengujian API & kolaborasi tim
Bagian FAQ
Untuk apa Heroku API digunakan?
Heroku API memungkinkan manajemen aplikasi, dyno, add-on, dan infrastruktur secara terprogram. Umum digunakan untuk otomasi CI/CD, manajemen multi-app, autoscaling, dan dashboard monitoring.
Bagaimana cara mendapatkan kunci API Heroku?
Install Heroku CLI, jalankan heroku login, lalu buat otorisasi via heroku authorizations:create. Simpan token di environment variable.
Apakah Heroku API gratis?
API-nya gratis, tapi resource (dyno, add-on, dsb) berbayar. Batas rate API: 10.000 request/jam per akun.
Otentikasi apa yang digunakan Heroku API?
Bearer token. Tambahkan header Authorization: Bearer {api_key} di setiap request. Token bisa short-lived (1 jam) atau long-lived (hingga 1 tahun).
Bagaimana menangani rate limit Heroku API?
Pantau header RateLimit-Remaining, implementasi request queue & exponential backoff saat menerima HTTP 429. Usahakan di bawah 150 request/menit.
Bisakah deployment tanpa Git?
Bisa. Gunakan API Builds dari URL source blob (upload kode ke S3/GCS, referensikan URL di request build).
Bagaimana mengotomatiskan deployment?
Manfaatkan API Pipeline untuk CI/CD. Build, promote slug, dan integrasi dengan GitHub atau CI lain.
Perbedaan release dan build?
Build meng-compile source jadi slug. Release menggabungkan slug + config var jadi versi aplikasi yang siap deploy.
Bagaimana rollback deployment gagal?
List releases, lalu POST ke /releases dengan rollback: <release_id>. Heroku akan membuat release baru di versi sebelumnya.
Bisakah kelola beberapa akun Heroku?
Bisa. Gunakan token API berbeda per akun. Switch dengan mengubah env var HEROKU_API_KEY.

Top comments (0)