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"
Permintaan curl yang membuat postingan dengan REST API Shager: caption, grup akun, tautan terlacak, dan waktu publikasi.
Operasi yang sama dengan server MCP, didokumentasikan dalam OpenAPI.

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.

Diagram: brief, draf per akun, persetujuan klien, publikasi bertahap, dan laporan klik per akun.
Lima tahap tetap. Persetujuan per postingan bersifat opsional untuk tiap klien; publikasi butuh pemilik manusia dan izin publikasi terpisah pada kunci.

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:

  1. per_channel memberi 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.
  2. format diterapkan di platform yang mendukungnya, dan pilihan SHORT atau REEL ditentukan per platform. youtube_title dan youtube_privacy hanya berlaku untuk channel YouTube.
  3. cta_url menghasilkan tautan pendek dan set UTM terpisah per akun, dengan utm_content sebagai penanda akun. Di atas inilah atribusi prospek per akun dibangun.
  4. stagger_seconds mengatur 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.

Coba di akun Anda sendiri.

Gratis selama masa peluncuran, tanpa kartu. Hubungkan akun, tulis sekali, lalu Shager yang memublikasikan dan mengukur hasilnya.