Panduan Cepat REST API Shager: Dari Kunci Baru Hingga Postingan Terlacak di 40 Akun dalam Tujuh Panggilan
Tur praktis REST API Shager dengan curl dan TypeScript: autentikasi, workspace, channel, media, draf per akun, penjadwalan, cek status, dan klik.

REST API Shager berada di https://app.shager.ai/api/v1, melakukan autentikasi dengan Authorization: Bearer shgr_live_..., mengembalikan setiap hasil sebagai { "data": ... } dan setiap error sebagai { "error": { "code", "message" } }. Satu siklus distribusi lengkap hanya butuh tujuh panggilan: cek kunci, pilih workspace, daftar channel-nya, unggah media, buat draf dengan caption per akun, jadwalkan, lalu baca status dan klik. Spesifikasi yang bisa dibaca mesin tersedia di dokumen OpenAPI 3.1.
Semua contoh di bawah langsung jalan begitu Anda mengatur dua variabel lingkungan. Operasi yang sama juga tersedia sebagai tool MCP dengan nama yang sama, jadi apa yang Anda pelajari di sini juga berlaku di Claude Code, Codex, atau Cursor.
Apa yang Anda perlukan sebelum panggilan pertama?
Sebuah kunci. Bisa dibuat oleh manusia di https://app.shager.ai/dashboard/agents dengan cakupan yang Anda perlukan, atau agen Anda membuat sandbox lewat pendaftaran mandiri. Cara kerja cakupannya:
| Cakupan | Mengizinkan |
|---|---|
read |
whoami, daftar workspace, channel, grup, dan postingan, membaca postingan, analitik |
write |
Membuat workspace, grup, media, draf postingan, tautan koneksi, permintaan persetujuan, pembatalan |
publish |
Penjadwalan, termasuk create_post dengan schedule_at |
export SHAGER_API_KEY="shgr_live_your_key_here"
export API="https://app.shager.ai/api/v1"

Panggilan 1: siapa saya?
curl -s "$API/me" -H "Authorization: Bearer $SHAGER_API_KEY"
{ "data": { "organization_id": "...", "organization": "Northwind Agency", "sandbox": false, "scopes": ["read", "write"] } }
Kalau sandbox bernilai true, penjadwalan dan tautan koneksi diblokir sampai seorang manusia mengklaim kuncinya. Kalau publish tidak ada di scopes, Anda bisa membuat draf tetapi tidak bisa menjadwalkannya. Mengetahui hal ini sejak awal menghindarkan Anda dari error 403 yang membingungkan di kemudian hari.
Panggilan 2: pilih atau buat workspace
Satu workspace biasanya mewakili satu klien atau brand.
curl -s "$API/workspaces" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s -X POST "$API/workspaces" \
-H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
-d '{"name": "Summit Physio", "timezone": "Europe/London", "approval_required": true}'
Selalu atur timezone (nama zona IANA) saat membuat workspace. Waktu jadwal disimpan bersama offset-nya, dan zona workspace menentukan cara Shager menampilkannya kepada manusia. approval_required: true berarti postingan harus disetujui klien sebelum bisa dijadwalkan, default yang baik untuk klien baru.
Ekspor ID dari respons agar perintah-perintah berikutnya berjalan:
export WS="the_workspace_id"
Panggilan 3: daftar channel dan grup
curl -s "$API/workspaces/$WS/channels" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/groups" -H "Authorization: Bearer $SHAGER_API_KEY"
Setiap channel dikembalikan dengan id, network, name, handle, status, formats yang didukung, dan connected_by_client. Grup mengembalikan id, name, dan channel_ids. Lewat grup, Anda bisa menyasar empat puluh akun tanpa menulis empat puluh ID; kirim group_ids ke create_post dan setiap channel aktif di grup itu ikut disertakan.
Kalau workspace belum punya channel, buat tautan koneksi dengan POST /workspaces/{workspace_id}/connect-links dan kirimkan ke pemilik akun. Mereka menghubungkan sendiri Facebook, Instagram, YouTube, X, LinkedIn, atau TikTok, tanpa perlu login ke Shager.

Panggilan 4: unggah media dari URL
curl -s -X POST "$API/workspaces/$WS/media" \
-H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
-d '{
"url": "https://cdn.summitphysio.example/video/knee-mobility.mp4",
"file_name": "knee-mobility.mp4",
"width": 1080, "height": 1920, "duration_ms": 42000
}'
Shager mengunduh file di sisi server dan mengembalikan id, kind, mime_type, dan size_bytes. Untuk Reel, Short, dan story, sertakan width, height, dan duration_ms kalau Anda mengetahuinya. Dengan begitu, Shager bisa memeriksa aturan format setiap platform sebelum postingan dijadwalkan, bukan gagal saat pengiriman.
Panggilan 5: buat draf dengan caption per akun
Inilah panggilan yang paling penting. Berikut versinya dalam TypeScript dengan fetch biasa, termasuk helper kecil yang akan Anda pakai berulang kali:
const API = "https://app.shager.ai/api/v1";
async function shager<T>(method: string, path: string, body?: unknown): Promise<T> {
const res = await fetch(`${API}${path}`, {
method,
headers: {
Authorization: `Bearer ${process.env.SHAGER_API_KEY}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
const json = await res.json();
if (!res.ok) {
const err = new Error(`${res.status} ${json.error.code}: ${json.error.message}`);
(err as any).status = res.status;
throw err;
}
return json.data as T;
}
const WS = process.env.SHAGER_WORKSPACE_ID!;
const mediaId = process.env.SHAGER_MEDIA_ID!; // the id returned by call 4
const channels = await shager<Array<{ id: string; name: string; network: string; status: string }>>(
"GET", `/workspaces/${WS}/channels`,
);
const post = await shager<{ id: string; status: string }>("POST", `/workspaces/${WS}/posts`, {
label: "Knee mobility, week 42",
caption: "Three minutes a day for stiffer knees. Full routine in the video.",
channel_ids: channels.map((c) => c.id),
media_ids: [mediaId],
format: "REEL",
youtube_title: "3-minute knee mobility routine",
youtube_privacy: "public",
per_channel: channels.map((c) => ({
channel_id: c.id,
caption: `${c.name}: three minutes a day for stiffer knees. Our physios show the routine.`,
})),
cta_url: "https://summitphysio.example/book",
cta_text: "Book an assessment",
campaign: "knee-mobility-oct",
first_comment: "Book an assessment: https://summitphysio.example/book",
stagger_seconds: [45, 120],
});
console.log(post.id, post.status); // DRAFT
Manfaat setiap field:
per_channelmemberi setiap akun caption sendiri. Dalam praktiknya, agenlah yang menulis caption-caption ini; template di atas hanya pengganti untuk langkah itu, dan alasannya ada di menghindari blokir spam dalam skala besar.formatditerapkan di platform yang mendukungnya, dan pilihanSHORTatauREELditentukan per platform.youtube_titledanyoutube_privacyhanya berlaku untuk channel YouTube.cta_urlmenghasilkan tautan pendek dan set UTM terpisah per akun, denganutm_contentsebagai penanda akun. Di atas inilah atribusi prospek per akun dibangun.stagger_secondsmengatur jeda acak antarakun di platform yang sama. Default-nya[30, 90].
Tanpa schedule_at, hasilnya adalah draf. Simpan ID-nya untuk panggilan berikutnya dengan export POST_ID="the_post_id".
Panggilan 6: persetujuan atau penjadwalan
Kalau workspace mewajibkan persetujuan, kirimkan ke klien. Responsnya menyertakan approval_url yang bisa dibuka peninjau tanpa login:
curl -s -X POST "$API/workspaces/$WS/posts/$POST_ID/approval" \
-H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
-d '{"reviewer_name": "Dana Ellis", "reviewer_email": "dana@summitphysio.example", "send_email": true}'
Setelah disetujui (atau kalau persetujuan tidak diwajibkan), jadwalkan. Langkah ini memerlukan cakupan publish, dan schedule_at wajib berformat ISO 8601 dengan offset:
curl -s -X POST "$API/workspaces/$WS/posts/$POST_ID/schedule" \
-H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
-d '{"schedule_at": "2026-10-20T08:30:00+01:00"}'
Pada titik ini Shager memvalidasi setiap tujuan terhadap aturan platformnya. Kalau ada akun yang akan menolak postingan, Anda menerima 422 rejected beserta alasannya, dan tidak ada yang masuk antrean.
Panggilan 7: cek status dan klik
curl -s "$API/workspaces/$WS/posts/$POST_ID" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/posts?status=SCHEDULED&limit=50" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/analytics?from=2026-10-01T00:00:00Z&to=2026-10-31T23:59:59Z" \
-H "Authorization: Bearer $SHAGER_API_KEY"
get_post mengembalikan satu baris per tujuan dengan state, dispatch_at, published_at, url postingan yang sudah tayang, dan error jika ada. Analitik mengembalikan total_clicks, by_account, dan by_post, yang menghitung klik di tautan terlacak Shager tanpa lalu lintas bot. Untuk membatalkan postingan terjadwal yang belum mulai dipublikasikan, gunakan POST /workspaces/{workspace_id}/posts/{post_id}/cancel.
Error mana yang harus ditangani kode Anda?
| Status dan kode | Arti | Yang perlu dilakukan |
|---|---|---|
401 unauthorized |
Header tidak ada atau salah format | Kirim Authorization: Bearer shgr_... |
403 forbidden |
Kunci tidak punya cakupan yang diperlukan | Buat draf saja, atau minta publish ke manusia |
403 sandbox_unclaimed |
Kunci pendaftaran mandiri yang belum diklaim | Tampilkan tautan klaim kepada manusia |
404 not_found |
ID workspace, postingan, atau channel salah | Ambil ulang daftarnya; ID berlaku per workspace |
409 not_scheduled |
Membatalkan postingan yang tidak terjadwal | Baca status postingan lebih dulu |
422 rejected |
Ada aturan platform yang tidak terpenuhi | Tampilkan pesannya; masalahnya disebutkan di sana |
429 rate_limited |
Lebih dari 120 permintaan per menit per kunci | Tunggu sebentar lalu coba lagi |
Batas laju ini jarang menjadi masalah bagi klien yang dirancang dengan baik. Satu create_post bisa mencakup ratusan akun, jadi Anda tidak perlu satu panggilan per akun.
FAQ
Apakah ada SDK?
Belum ada yang khusus. Dokumen OpenAPI 3.1 bisa dipakai dengan generator standar kalau Anda ingin klien bertipe, dan API-nya cukup ringkas sehingga helper seperti contoh di atas biasanya sudah cukup. CLI Shager sedang disiapkan.
Apakah REST dan MCP benar-benar sama?
Ya. Setiap tool MCP sepadan dengan satu operasi REST, dengan nama, input, cakupan, batas laju, dan pencatatan audit yang sama. Pakai REST dari skrip dan layanan, dan MCP dari klien agen. Daftar lengkap tool-nya ada di halaman agen.
Bagaimana cara mengirim teks berbeda ke Facebook dan YouTube dalam satu postingan?
Gunakan per_channel berisi ID dan caption setiap channel, serta youtube_title untuk judul YouTube. Satu objek postingan, banyak tujuan, masing-masing dengan caption, format, dan komentar pertama sendiri kalau diperlukan.
Langkah berikutnya
Begitu rangkaian ini berjalan mulus secara manual, bungkus menjadi sesuatu yang bisa diulang oleh agen. Membangun skill Claude untuk Shager menunjukkan cara mengemas panggilan-panggilan ini beserta aturannya menjadi skill yang bisa dipakai ulang.


