> העתק ציבורי של מדריך המפתחים של ViewStream (לקריאה גם על ידי סוכני AI). רשימת המדריכים: https://www.viewstream.co.il/he/developers/guide/index.md · תיעוד ה-API: https://api.viewstream.co.il/docs/

# תחילת עבודה עם ה-API של ViewStream

העמוד הזה מוביל אתכם מאפס ועד לקריאה מאומתת ראשונה. הוא מיועד למפתחים שמחברים ל-ViewStream מערכת ניהול תוכן (CMS),
כלי של מערכת חדשות או מערכת צד שרת (backend).

## כתובת בסיס

| מה | כתובת |
|---|---|
| ה-API לניהול (כל מה שבעמוד הזה) | `https://api.viewstream.co.il/v1` |
| תיעוד אינטראקטיבי (Swagger UI) | `https://api.viewstream.co.il/docs/` |
| מסמכי OpenAPI | `https://api.viewstream.co.il/openapi.yaml`, `/openapi.json`; ה-API של Sites Delivery: `/openapi/sites-delivery.yaml`, `.json` |

ה-API עובד ב-JSON על גבי HTTPS. כל בקשה עם כותרת (header) `Host` לא מוכרת נדחית עם `421 misdirected_request`
(מקור: `hostAllowList` ב-middleware.go (באנגלית)).

> **עמוד התיעוד פונה לסביבת הייצור.** "Try it out" ב-`/docs/` שולח בקשות אמיתיות עם המפתח שלכם. כדי להתנסות,
> השתמשו במפתח עם הרשאות קריאה בלבד.

## 1. יצירת מפתח API ב-Studio

נדרש תפקיד ב-Studio שכולל את `keys:manage` — **מהנדס (Engineer)** ומעלה.

1. ב-Studio, פתחו את **אינטגרציות** בתפריט הצד.
2. באזור **מפתחות API**, הקלידו **שם המפתח**, למשל `CMS production`
   (עד 120 תווים).
3. סמנו את ה**הרשאות** שהאינטגרציה צריכה. בחרו את הסט המצומצם ביותר; הטבלה שלמטה מפרטת מה כל הרשאה
   פותחת.
4. לחצו על **יצירת מפתח**.
5. העתיקו את המפתח מהתיבה *"המפתח החדש שלכם — מוצג פעם אחת…"* ושמרו אותו
   במאגר הסודות שלכם. ViewStream שומרת רק גיבוב (hash) שלו; אי אפשר להציג את המפתח שוב.

כללים שה-API אוכף (apikeys.go (באנגלית)):

- מפתח לעולם לא מקבל הרשאה (scope) שאין לכם בעצמכם (`422`, *"you cannot grant a scope you do not hold"*).
- מפתח שייך לארגון אחד בדיוק, וההרשאות שלו קבועות לכל חייו. כדי לשנות הרשאות, צרו מפתח חדש ובטלו את
  הישן.
- **ביטול** מבקש להקליד את קידומת המפתח; כל מערכת שמשתמשת במפתח מקבלת `401` מיד.
- אותן פעולות זמינות גם דרך ה-API: `GET /v1/api-keys`, `POST /v1/api-keys {name, scopes[]}`,
  `DELETE /v1/api-keys/{id}` (הרשאה `keys:manage`). המפתח המלא מוחזר פעם אחת, בשדה `key` של
  תשובת `201`.

מבנה המפתח: `vs_<קידומת בת 8 תווים>_<32 תווים אקראיים>` (אותיות וספרות). הקידומת היא מה ש-Studio מציג
ברשימת המפתחות ומה שנרשם ביומן הביקורת.

שמרו מפתחות על שרתים בלבד. לעולם אל תכניסו מפתח לדף אינטרנט, לאפליקציה לנייד או למאגר קוד ציבורי.

## 2. שליחת המפתח כ-bearer token

```bash
export VS_KEY='vs_ab12cd34_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'   # placeholder — use your own key
curl -s https://api.viewstream.co.il/v1/me -H "Authorization: Bearer $VS_KEY"
```

`GET /v1/me` לא דורש הרשאה. עבור מפתח, התשובה היא:

```json
{
  "user": null,
  "auth": "api_key",
  "current_tenant": {"id": "…", "slug": "acme", "name": "…", "mode": "platform", "cdn_hostname": "cdn.acme.vustream.net", "role": "api_key"},
  "tenants": [ { "…": "the same tenant" } ],
  "scopes": ["assets:read", "channels:read"]
}
```

- `mode` הוא `platform` (המוצר המלא) או `cdn` (ארגון CDN בלבד). ארגוני CDN בלבד מקבלים `403 feature_disabled` על
  סרטונים, העלאות, ערוצים, קליפים ותצורות נגן (`platformOnly` ב-
  middleware.go (באנגלית)).
- `scopes` הוא בדיוק מה שהמפתח רשאי לעשות.

אם הכותרת חסרה, שגויה, לא מוכרת או שהמפתח בוטל, ה-API עונה `401 invalid_credentials` עם
`WWW-Authenticate: Bearer realm="viewstream"`. אחרי כישלונות חוזרים מאותה כתובת IP (30 ב-10 דקות) או עבור
אותה קידומת מפתח (10 ב-10 דקות), ניסיונות נוספים מקבלים `429` עוד לפני שהמפתח נבדק
(middleware.go (באנגלית), `keyFailPerIP`, `keyFailPerPrefix`).

## 3. הרשאות

נתיב שדורש הרשאה שאין למפתח שלכם עונה `403 insufficient_scope`, ו-`detail` מציין את ההרשאה
(`"this route requires scope assets:write"`). חלק מהנתיבים מקבלים אחת משתי הרשאות; במקרה כזה `detail` מציין את שתיהן עם
"or".

הטבלה בנויה מ-auth/scopes.go (באנגלית) (רשימת ההרשאות וטבלת
התפקידים) ומהנתב public.go (באנגלית) (מה כל הרשאה פותחת). "התפקיד
הנמוך ביותר" הוא התפקיד הנמוך ביותר ב-Studio שכולל את ההרשאה; התפקידים מצטברים (לעורך יש כל מה שיש לצופה).

| הרשאה | התפקיד הנמוך ביותר | מה היא פותחת (הנתיבים העיקריים) |
|---|---|---|
| `assets:read` | צופה (Viewer) | `GET /assets`, `/assets/{id}`, `/trash`, `/jobs`, `/jobs/{id}`, `/jobs/failures`, `/collections`, `/posters/…`, `/subtitles/settings`, `/subtitles/tracks`, `/subtitles/…/cues`, `/summaries/settings`, `/programmes/{id}/summary`, `/assets/{id}/summary`, `/images/…`, `/assets/{id}/ai-video`, `/assets/{id}/packaging`, `/library/imports`, `/player-configs`, `/player-config-assignments`, `/tenant/branding`, `/tenant/defaults` |
| `assets:write` | עורך (Editor) | יצירה/עדכון/קידוד מחדש/מחיקה/שחזור של סרטונים; **העלאות** (`/uploads…`); פוסטרים; מדורים; ייבוא לספרייה; עריכת כתוביות והרצה מחדש; עריכה ויצירה מחדש של סיכומים; שדרוג תמונה ווידאו; ניסיון חוזר/התעלמות ממשימות; יחד עם `channels:read` גם פרסום תוכנית ל-VOD |
| `assets:publish` | מפרסם (Publisher) | השדה `publish` של `PATCH /assets/{id}`; פרסום תוכניות של צפייה חוזרת ל-VOD |
| `assets:purge` | מנהל (Admin) | `DELETE /assets/{id}?permanent=true`, `POST /trash/empty`, `PATCH /trash/settings` |
| `clips:read` | צופה | `GET /clips`, `/clips/{id}` |
| `clips:write` | עורך | `POST /clips`, `DELETE /clips/{id}` |
| `clips:publish` | מפרסם | נבדקת רק כש-`POST /clips` כולל `"publish": true` (ראו את ההערה ב-[recipes.md](recipes.md#יצירת-קליפ)) |
| `channels:read` | צופה | `GET /channels…`, תוכניות, EPG (`/channels/{id}/epg/…`, `/epg/catalog`, `/epg/destinations`), מצב הקלטה/ציר זמן/תמונות ממוזערות, רשימת צפייה חוזרת וחיפוש בה, כלל שידור חי ל־VOD, גבולות תוכנית, החשכות, הגדרות קליטה ואירועי קליטה, אריזה, סנכרון שפתיים, החרגות מצפייה חוזרת (קריאה) |
| `channels:write` | מהנדס (Engineer) | יצירה/שינוי/מחיקה של ערוצים; הגדרות קליטה (`PUT /ingest`, בדיקה, החלה, השבתה, העברה, כתובות IP מורשות); מצב הקלטה; הגדרות פרסומות והפסקות פרסומות; גבולות תוכנית; סמנים; מקור EPG וייבוא; מתקבלת גם במקום `epg:write`/`epg:publish` (מפתחות ישנים) |
| `channels:operate` | מהנדס | שליטה בשידור חי: `POST /channels/{id}/ingest/switch`, `/slate`, `/restart`; חשיפת סודות קליטה, החלפה/חשיפה של סיסמת SRT; אישור התראות |
| `uploads` | עורך | **לא חוסמת אף נתיב כיום** — `/v1/uploads…` בודק `assets:write`. ראו סתירות |
| `prewarm` | מהנדס | `POST /prewarm`, `GET /prewarm/{id}`; תשאול המשימה עם `GET /jobs/{id}` |
| `delivery:write` | מהנדס | `POST /purge`; הפצות (יצירה, עדכון, מחיקה, החלפת סוד, חתימת URL); מדיניות צפייה וצירופים; החשכות (יצירה, מחיקה); CDN של שותפים וניתוב (steering); תצורות נגן ושיוך תבניות (כתיבה) |
| `webhooks:manage` | מהנדס | `/webhooks…`, `/inbound-hooks…`, `/event-destinations…`, `/event-inbox` |
| `storage:manage` | מהנדס | `POST /storage/usage/refresh` בלבד (`GET /storage/keys` ו-`/storage/usage` דורשים `stats:read`) |
| `keys:manage` | מהנדס | `/api-keys…`; `/playback/keys` (רשימה, החלפה, ייצוא) |
| `stats:read` | צופה | `/stats/…` (זמן אמת, סקירה, סדרות זמן, פילוח, מובילים, תעבורה, QoE, CDN, השלמת צפייה, תוכניות, סשנים, פרסומות, אתרים, הגנה, ייצוא נתונים גולמיים); דוחות ותזמוני דוחות (קריאה); הפצות, מדיניות, שותפי CDN, ניתוב (קריאה); שימוש באחסון; דליפות, ביטולים והגדרות אבטחה (קריאה); ניטורים, התראות ותקינות השירות (קריאה, כחלופה ל-`channels:read`) |
| `stats:pii` | מנהל | עמודות ברמת הצופה בייצוא גולמי, מזהי צופים בחיפוש סשנים, כתובות IP מגובבות בייצוא אירועים, `DELETE /stats/viewers/{vid}` |
| `events:read` | צופה | `GET /events/stream` (Server-Sent Events) ו-`GET /notifications` |
| `team:manage` | מנהל | משתמשים, הזמנות, יומן הביקורת של הארגון (`GET /audit`); תזמוני דוחות (או `notifications:manage`) |
| `notifications:manage` | מנהל | כללי התראה; יצירה/שינוי של ניטורים, יעדי התראות, השהיה; אישור התראות; תזמוני דוחות |
| `billing:read` | בעלים (Owner) | `GET /billing/usage`, `/billing/statements` |
| `tenant:settings` | בעלים | `PUT /tenant/branding`, `/tenant/defaults`, `/subtitles/settings`, `/summaries/settings`, `/images/settings`, `/packaging/settings`, `/lipsync/settings`; כללי החרגה מצפייה חוזרת ודריסות |
| `sites:read` | צופה | `GET /sites…`, `/pages/{id}…`, `/series…`, `/people…` |
| `sites:write` | עורך | עריכת עמודים (טיוטות), תפריטים, הפניות, תוכניות (`/series`), אנשים; קישורי תצוגה מקדימה; בדיקת עמוד |
| `sites:publish` | מפרסם | פרסום עמודים, תפריטים וערכות עיצוב; ביטול גרסה מתוזמנת |
| `sites:admin` | מהנדס | יצירה/מחיקה של אתרים, דומיינים, ערכת עיצוב, נתיבים |
| `playback:sign` | מהנדס | `POST /playback/tokens` (כתובות צפייה עם טוקן, עבור צד השרת שלכם) |
| `security:manage` | מהנדס | `PUT /security/settings`, `POST /security/revocations`, `POST /security/leaks/{id}/dismiss` |
| `epg:write` | עורך | עריכת לוח השידורים: תוכניות, פעולות טיוטה, תיקונים, העתקה/הזזה, תבניות (או `channels:write`) |
| `epg:publish` | מפרסם | פרסום/החזרה לאחור של לוח השידורים, מצב תהליך עבודה, יעדי EPG (או `channels:write`) |
| `support:read` | צופה | `GET /support/requests`, `/support/requests/{id}` (פניות התמיכה של הארגון וההתכתבות בהן) |
| `support:write` | צופה | `POST /support/requests` (10 לארגון בשעה), `/support/requests/{id}/messages`, `/support/requests/{id}/close` |

כל נתיב תחת `/v1`, חוץ מהתחברות, הזמנות ו-`GET /v1/me`, `/v1/tenants`, דורש גם ארגון נוכחי; עבור
מפתח API זה תמיד הארגון של המפתח.

## 4. הקריאה השימושית הראשונה

הצגת הסרטונים המוכנים החדשים ביותר:

```bash
curl -s "https://api.viewstream.co.il/v1/assets?status=ready&limit=10" \
  -H "Authorization: Bearer $VS_KEY"
```

```json
{"items": [{"id": "0192…", "title": "…", "status": "ready", "published": true, "playback": {"hls": "https://cdn…/master.m3u8", "poster": "…"}, "…": "…"}],
 "next_cursor": "MDE5Mj…"}
```

הצעדים הבאים:

- [conventions.md](conventions.md) — שגיאות, עימוד, הגבלות קצב, משימות אסינכרוניות, זרם האירועים, פורמטי זמן.
- [recipes.md](recipes.md) — העלאת סרטון, צפייה חוזרת, טוקנים לצפייה, קליפים, סטטיסטיקה, ניטורים, Webhooks.
- [player-integration.md](player-integration.md) — הצבת הנגן בעמוד.
