# Shager REST API hızlı başlangıç: yeni bir anahtardan 40 hesapta takip edilen bir gönderiye yedi çağrıda

_2026-09-19 · curl ve TypeScript ile Shager REST API'sine uygulamalı tur: kimlik doğrulama, çalışma alanları, kanallar, medya, hesap başına taslaklar, planlama, tıklamalar._

Shager'ın REST API'si `https://app.shager.ai/api/v1` adresinde çalışır, `Authorization: Bearer shgr_live_...` ile kimlik doğrular, her sonucu `{ "data": ... }`, her hatayı da `{ "error": { "code", "message" } }` olarak döndürür. Eksiksiz bir dağıtım yedi çağrıdan oluşur: anahtarı kontrol edin, bir çalışma alanı seçin, kanallarını listeleyin, medyayı yükleyin, hesap başına açıklamalarla bir taslak oluşturun, onu planlayın, sonra durumu ve tıklamaları okuyun. Makinenin okuyabileceği spesifikasyon [OpenAPI 3.1 belgesinde](https://app.shager.ai/api/v1/openapi.json).

İki ortam değişkenini ayarladığınızda aşağıdaki her şey yazıldığı gibi çalışır. Aynı işlemler aynı adlarla MCP araçları olarak da var; yani burada öğrendikleriniz Claude Code, Codex veya Cursor'a da aynen taşınır.

## İlk çağrıdan önce neye ihtiyacınız var?

Bir anahtara. Ya bir insan ihtiyacınız olan yetkilerle https://app.shager.ai/dashboard/agents adresinden bir anahtar oluşturur ya da ajanınız [kendi kendine kayıt](/en/blog/agent-self-signup-and-claim) yoluyla bir test ortamı açar. Yetki kapsamları şöyle çalışır:

| Yetki | İzin verdikleri |
|---|---|
| `read` | `whoami`, çalışma alanlarını, kanalları, grupları ve gönderileri listelemek, bir gönderiyi okumak, analizler |
| `write` | Çalışma alanı, grup, medya, taslak gönderi, bağlantı linki ve onay isteği oluşturmak, iptal etmek |
| `publish` | Planlama, `schedule_at` içeren `create_post` dahil |

```bash
export SHAGER_API_KEY="shgr_live_your_key_here"
export API="https://app.shager.ai/api/v1"
```

## 1. çağrı: ben kimim?

```bash
curl -s "$API/me" -H "Authorization: Bearer $SHAGER_API_KEY"
```

```json
{ "data": { "organization_id": "...", "organization": "Northwind Agency", "sandbox": false, "scopes": ["read", "write"] } }
```

`sandbox` değeri true ise, bir insan anahtarı sahiplenene kadar planlama ve bağlantı linkleri engellidir. `scopes` içinde `publish` yoksa taslak oluşturabilir ama planlayamazsınız. Bunu baştan bilmek, ileride kafa karıştıran bir 403 hatasından kurtarır.

## 2. çağrı: bir çalışma alanı seçin ya da oluşturun

Bir çalışma alanı genellikle bir müşteri ya da bir markadır.

```bash
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}'
```

Oluştururken `timezone` değerini (bir IANA adı) mutlaka belirtin. Planlanan zamanlar farklarıyla birlikte saklanır ve Shager onları insanlara çalışma alanının saat dilimine göre gösterir. `approval_required: true`, gönderilerin planlanabilmesi için müşteri tarafından onaylanması gerektiği anlamına gelir; yeni müşteriler için iyi bir varsayılandır.

Sonraki komutların çalışması için yanıttaki kimliği dışa aktarın:

```bash
export WS="the_workspace_id"
```

## 3. çağrı: kanalları ve grupları listeleyin

```bash
curl -s "$API/workspaces/$WS/channels" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/groups" -H "Authorization: Bearer $SHAGER_API_KEY"
```

Her kanal `id`, `network`, `name`, `handle`, `status`, desteklediği `formats` ve `connected_by_client` alanlarıyla döner. Gruplar `id`, `name` ve `channel_ids` döndürür. Kırk hesabı kırk kimlik listelemeden hedeflemenin yolu gruplardır: `create_post` aracına `group_ids` verin, gruptaki tüm aktif kanallar dahil edilsin.

Çalışma alanında henüz kanal yoksa, `POST /workspaces/{workspace_id}/connect-links` ile bir bağlantı linki oluşturup hesap sahibine gönderin. Hesap sahibi Facebook, Instagram, YouTube, X, LinkedIn veya TikTok hesabını Shager'a giriş yapmadan kendisi bağlar.

## 4. çağrı: medyayı bir URL'den yükleyin

```bash
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 dosyayı sunucu tarafında indirir ve `id`, `kind`, `mime_type` ve `size_bytes` döndürür. Reels, Shorts ve hikayeler için biliyorsanız `width`, `height` ve `duration_ms` değerlerini verin. Böylece Shager, gönderim anında hata vermek yerine her platformun biçim kurallarını gönderi planlanmadan önce kontrol edebilir.

## 5. çağrı: hesap başına açıklamalarla bir taslak oluşturun

Asıl önemli çağrı bu. İşte düz `fetch` ile TypeScript'te yazılmış hâli; tekrar tekrar kullanacağınız küçük bir yardımcı fonksiyon da dahil:

```typescript
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
```

Her alanın size kazandırdıkları:

1. `per_channel` her hesaba kendi açıklamasını verir. Pratikte bunları bir ajan yazar; yukarıdaki şablon o adımın yerini tutan bir örnektir. Gerekçesi [ölçekli paylaşımda spam engellerinden kaçınmak](/en/blog/avoid-spam-blocks-when-posting-at-scale) yazısında.
2. `format`, platformun desteklediği yerlerde uygulanır; aksi hâlde `SHORT` ile `REEL` arasındaki seçim her platform için ayrıca belirlenir. `youtube_title` ve `youtube_privacy` yalnızca YouTube kanallarını etkiler.
3. `cta_url`, her hesap için ayrı bir kısa link ve UTM seti üretir; `utm_content` hesabı tanımlar. [Hesap başına potansiyel müşteri ilişkilendirmesi](/en/blog/utm-per-account-lead-attribution) bunun üzerine kuruludur.
4. `stagger_seconds`, aynı platformdaki hesaplar arasında rastgele bir bekleme süresi belirler. Varsayılan değer `[30, 90]`.

`schedule_at` olmadan sonuç bir taslaktır. Sonraki çağrılar için kimliğini `export POST_ID="the_post_id"` ile saklayın.

## 6. çağrı: onay ya da planlama

Çalışma alanı onay gerektiriyorsa gönderiyi müşteriye gönderin. Yanıt, onaylayan kişinin giriş yapmadan açabileceği bir `approval_url` içerir:

```bash
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}'
```

Onaylandıktan sonra (ya da onay gerekmiyorsa) planlayın. Bunun için `publish` yetkisi gerekir ve `schedule_at` farkı belirtilmiş bir ISO 8601 zamanı olmalıdır:

```bash
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"}'
```

Shager bu noktada her hedefi kendi platformunun kurallarına göre doğrular. Herhangi bir hesap gönderiyi reddedecekse, gerekçesiyle birlikte 422 `rejected` alırsınız ve hiçbir şey kuyruğa girmez.

## 7. çağrı: durumu ve tıklamaları kontrol edin

```bash
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`, her hedef için `state`, `dispatch_at`, `published_at`, yayındaki `url` ve varsa `error` içeren bir satır döndürür. Analizler `total_clicks`, `by_account` ve `by_post` döndürür; Shager'ın takip linklerindeki tıklamaları bot trafiğini hariç tutarak sayar. Yayınlanmaya başlamamış planlanmış bir gönderiyi iptal etmek için `POST /workspaces/{workspace_id}/posts/{post_id}/cancel`.

## Kodunuz hangi hataları ele almalı?

| Durum ve kod | Anlamı | Ne yapmalı |
|---|---|---|
| 401 `unauthorized` | Başlık eksik veya hatalı | `Authorization: Bearer shgr_...` gönderin |
| 403 `forbidden` | Anahtarda gerekli yetki yok | Taslak oluşturun ya da bir insandan `publish` isteyin |
| 403 `sandbox_unclaimed` | Sahiplenilmemiş kendi kendine kayıt anahtarı | Sahiplenme linkini bir insana iletin |
| 404 `not_found` | Yanlış çalışma alanı, gönderi veya kanal kimliği | Yeniden listeleyin; kimlikler çalışma alanına özgüdür |
| 409 `not_scheduled` | Planlanmamış bir gönderiyi iptal etmeye çalışmak | Önce gönderinin durumunu okuyun |
| 422 `rejected` | Bir platform kuralı karşılanmadı | Mesajı gösterin; sorunu adıyla söyler |
| 429 `rate_limited` | Anahtar başına dakikada 120 istek aşıldı | Bekleyip yeniden deneyin |

İyi tasarlanmış bir istemci hız sınırına nadiren takılır. Tek bir `create_post` yüzlerce hesabı kapsar; hesap başına bir çağrıya ihtiyacınız olmamalı.

## Sık sorulan sorular

### Bir SDK var mı?

Özel bir SDK yok. Tipli istemciler istiyorsanız OpenAPI 3.1 belgesi standart üreticilerle çalışır; API de yukarıdaki gibi bir yardımcı fonksiyonun genellikle yeteceği kadar küçük. Bir Shager CLI'ı da yolda.

### REST ve MCP gerçekten aynı mı?

Evet. Her MCP aracı, aynı ad, girdiler, yetkiler, hız sınırı ve denetim kaydıyla tek bir REST işlemine karşılık gelir. Betiklerden ve servislerden REST'i, ajan istemcilerinden MCP'yi kullanın. Araçların tam listesi [ajanlar sayfasında](/en/agents).

### Aynı gönderide Facebook'a ve YouTube'a farklı metin nasıl gönderirim?

Her kanalın kimliği ve açıklamasıyla `per_channel` kullanın; YouTube başlığı için de `youtube_title`. Tek bir gönderi nesnesi, birçok hedef; her birinin kendi açıklaması, biçimi ve gerekiyorsa ilk yorumu olur.

## Sonraki adım

Bu sıra elle sorunsuz çalıştığında, onu bir ajanın tekrarlayabileceği bir yapıya dönüştürün. [Shager için bir Claude becerisi geliştirmek](/en/blog/build-a-claude-skill-for-shager), bu çağrıları ve çevresindeki kuralları yeniden kullanılabilir bir beceri olarak nasıl paketleyeceğinizi gösteriyor.

---
Source: https://shager.ai/tr/blog/shager-rest-api-quickstart
