דילוג לתוכן
תיעוד Nodaro
תיעודמדריך הרכיביםמודליםתבניותסוכני AI (MCP)מפתחיםאירוח עצמימחקרהשוואות
REST API

תהליכים

הרצת תהליכים שמורים של Nodaro דרך ה-API עם ערכי קלט חדשים, המתנה לתוצאה או בדיקת הסטטוס, ורשימה, יצירה, עדכון, ייצוא והעברה של תהליכים.

תהליך הוא קנבס שמור של רכיבים מחוברים, וה-API יכול להריץ אותו, לתת לו ערכי קלט חדשים להרצה אחת ולנהל אותו כמו כל משאב אחר. הרצה מתחילה עם בקשה אחת שמחזירה executionId, ואז בודקים את הסטטוס של ההרצה מדי כמה שניות עד שהיא מסתיימת. הרצה קצרה יכולה גם לחכות לתוצאה שלה באותה בקשה.

נקודות קצה

הרצת תהליך

שיטהנתיבמה היא עושה
POST/v1/workflows/:id/runהרצת התהליך השמור, או של חלק מהרכיבים שלו. התגובה היא 202 עם executionId.
POST/v1/workflows/:id/render-final/estimateאומדן מחיר לרינדור סופי: הרכיבים שהוא מריץ והקרדיטים שלו. שום דבר לא נוצר ולא נגבים קרדיטים.
GET/v1/api/workflowsרשימת התהליכים שאסימון ה-API שלכם יכול להריץ. תומכת ב-?limit= וב-?cursor=.
GET/v1/api/schema?workflowId=…שדות הקלט והפלטים של תהליך, עם estimatedCredits.
POST/v1/api/runהרצת תהליך עם ערכי קלט חדשים. הוסיפו ?wait=true&timeout=… כדי לחכות לתוצאה.
GET/v1/api/status/:execIdהסטטוס של ההרצה, ספירת הרכיבים והקרדיטים שהוצאו, ואחרי שההרצה הושלמה גם ה-outcome שלה.
GET/v1/api/result/:execIdהפלטים של ההרצה, אחרי שהסטטוס שלה הוא completed או failed.
POST/v1/app/:slug/runהרצת אפליקציה שפורסמה עם שדות הטופס שלה. ראו את הדף מיני־אפליקציות.

ניהול תהליכים

שיטהנתיבמה היא עושה
GET/v1/projects/:projectId/workflowsהתהליכים של פרויקט אחד, בלי הרכיבים והחיבורים שלהם.
GET/v1/workflowsהתהליכים שלכם בכל הפרויקטים.
GET/v1/workflows/:idתהליך אחד עם הרכיבים, החיבורים וההגדרות שלו.
POST/v1/projects/:projectId/workflowsיצירת תהליך בפרויקט.
PATCH/v1/workflows/:idשינוי של כל צירוף של שדות התהליך.
DELETE/v1/workflows/:idמחיקת תהליך.
GET/v1/workflows/:id/exportייצוא התהליך כחבילת JSON. הוסיפו ?assets=true כדי לכלול את הדמויות, האובייקטים והמיקומים שלו.
POST/v1/workflows/importיצירת תהליך מחבילה.
POST/v1/workflows/:id/moveהעברת תהליך לפרויקט אחר.
GET/v1/workflows/shared-with-meתהליכים שאנשים אחרים שיתפו איתכם.
GET/v1/mcp-conversationsשיחות ה-MCP שלכם בחודש אחד. ראו את הסעיף שיחות MCP.

שיתוף, שותפים והרשאות לכל תהליך מתוארים בדף ה-API סביבות עבודה וארגונים.

שלוש דרכים להריץ תהליך

נקודת קצהפרטי גישהערכי קלטמתי להשתמש בה
POST /v1/workflows/:id/runכל אסימון. אסימוני OAuth צריכים את workflows:execute.הערכים השמורים. השדה nodeIds מריץ חלק מהרכיבים.מריצים את התהליך כמו שהוא שמור, בשביל החשבון שלכם או בשביל משתמש OAuth.
POST /v1/api/runאסימון API אישיהשדה inputs מחליף את הערכים של רכיבי הקלט בהרצה הזו.סקריפט צריך ערכים שונים בכל הרצה, או רוצה לחכות לתוצאה.
POST /v1/app/:slug/runכל אסימוןשדות הטופס של האפליקציה, ועוד דריסות גולמיות של רכיביםהתהליך פורסם כאפליקציה עם טופס שהשדות שלו נבחרו בקפידה.

חמש נקודות הקצה של /v1/api/ הן מסלול אסימוני ה-API המקורי. הן קיימות מלפני האפליקציות שפורסמו ועדיין נתמכות, אבל אינטגרציות חדשות שצריכות קלטים מפרסמות בדרך כלל את התהליך כאפליקציה ומשתמשות ב-POST /v1/app/:slug/run. הנתיב הזה מקבל את השדות של האפליקציה באובייקט inputs שטוח, ואובייקט inputOverrides אופציונלי של דריסות גולמיות בצורה { nodeId: { field: value } }. השניים ממוזגים, והשדה inputOverrides גובר בכל שדה ששניהם קובעים. קלט שטוח שהשדה שלו הוא מספר, כגון מחוון שהאפליקציה חושפת, מקבל מספר או מחרוזת מספרית: הערך "0.4" מגיע לרכיב כ-0.4. ערך שהוא לא מספר מועבר כמו שהוא, והרכיב מתייחס אליו כמו תמיד.

הרצת תהליך שמור

הנתיב POST /v1/workflows/:id/run מתחיל הרצה של התהליך כמו שהוא שמור. שלחו גוף ריק כדי להריץ את כל הרכיבים, או nodeIds כדי להריץ חלק מהם:

curl -s -X POST https://app.nodaro.ai/v1/workflows/8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f/run \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
{ "executionId": "3f9e2b1a-7c6d-4e5f-8a9b-0c1d2e3f4a5b", "status": "pending" }
const { executionId } = await client.workflows.run(workflowId)

// Or run only some nodes:
await client.workflows.run(workflowId, { nodeIds: ['text-prompt-1', 'generate-image-1'] })
nodaro workflows run 8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f --watch
nodaro workflows run 8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f --node text-prompt-1 generate-image-1

מאפיין

סוג

התגובה היא 202 Accepted עם { executionId, status }, כשהשדה status הוא pending או running. בדקו את הסטטוס של ההרצה מדי כמה שניות עם GET /v1/workflow-executions/:id, שמתואר בדף ה-API הרצות. עם --watch, ה-CLI בודק את הסטטוס בשבילכם ויוצא עם קוד 2 כשההרצה נכשלת ועם 130 כשהיא מבוטלת.

סטטוסקודמשמעות
402insufficient_creditsהרצת המשך או רינדור סופי שהקרדיטים שלכם לא מכסים. שום דבר לא נוצר.
403forbiddenמותר לכם לראות את התהליך, אבל לא להריץ אותו. בסביבת עבודה, הרצה דורשת גישת עריכה וחברות פעילה.
404not_foundאין תהליך כזה, או שאין לכם גישה לראות אותו.
409already_runningלתהליך כבר יש הרצה פעילה. התגובה כוללת את ה-executionId של ההרצה הזו.

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

המשך הרצה

הנתיב POST /v1/workflows/:id/run יכול להמשיך הרצה קודמת במקום להתחיל מההתחלה. שלחו continueFromExecutionId עם המזהה של ההרצה ההיא, יחד עם nodeIds. ההרצה מריצה רק את הרכיבים שב-nodeIds. כל רכיב אחר מעביר הלאה את מה שההרצה הקודמת יצרה, כמו שההרצה ההיא תיעדה אותו, ולעולם לא את התוצאות השמורות של התהליך. הקלטים שההרצה ההיא השתמשה בהם, כגון העלאה או קלט של אפליקציה, משמשים שוב, ושום רכיב שלפני הרכיבים שב-nodeIds לא רץ שוב, ולא משלמים עליו שוב.

  • רכיב שגם ההרצה הקודמת לא הריצה מעביר הלאה את התוצאות השמורות שלו, כמו שעשה בהרצה ההיא.
  • רכיב תוכנית עריכה מעביר הלאה את התוכנית שההרצה הקודמת יצרה, כשהבדיקה הנוכחית שלכם מוחלת עליה. בדיקה שנעשתה על תוכנית אחרת לא נלקחת בחשבון.
  • רכיב שההרצה הקודמת לא השלימה לא מעביר שום דבר ולא רץ שוב. Nodaro מדלג על רכיב שכל הקלטים שלו מגיעים מרכיבים כאלה, ועל הרכיבים שאחריו.
  • ה-inputOverrides של ההרצה הקודמת מוחלים שוב. ה-inputOverrides שאתם שולחים מוחלים מעליהם, שדה אחר שדה, והערכים שלכם גוברים.

דוגמה אחת היא רינדור סופי שבונים ידנית. הוא מריץ את הרינדור ואת כל הרכיבים שאחריו, כשהרינדור במצב סופי בהרצה הזו בלבד:

{
  "nodeIds": ["<render node id>", "<every node after it>"],
  "inputOverrides": { "<render node id>": { "quality": "final" } },
  "continueFromExecutionId": "<a completed run whose render made a Preview>"
}

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

סטטוסקודמשמעות
400continuation_subset_requiredהשדה nodeIds חסר או ריק, בלי continueMode.
400continuation_workflow_mismatchההרצה הקודמת הריצה תהליך אחר.
400continuation_version_mismatchההרצה הקודמת הריצה גרסת אפליקציה שפורסמה של התהליך. כדי להמשיך הרצת אפליקציה שנכשלה, השתמשו בניסיון החוזר של האפליקציה.
400validation_errorהשדה continueFromExecutionId הוא לא מזהה של הרצה.
404continuation_not_foundאין הרצה כזו, או שההרצה לא שלכם.
409continuation_not_completedההרצה הקודמת עדיין רצה, נכשלה או בוטלה.

המשך הרצה שנכשלה

אפשר להמשיך הרצה של תהליך שמור שנכשלה מהנקודה שבה היא נעצרה, ולשמור את מה שהיא השלימה. שלחו continueFromExecutionId עם המזהה של ההרצה שנכשלה ו-"continueMode": "from-failed":

{
  "continueFromExecutionId": "<the run that failed>",
  "continueMode": "from-failed"
}
  • רק מה שנשאר רץ. כל רכיב שההרצה שנכשלה השלימה מעביר הלאה את התוצאה שלו, ולא רץ שוב ולא משלמים עליו שוב. רכיב שנכשל רץ שוב במלואו, כולל כל פריט ברשימה.
  • הרכיבים שנלקחים בחשבון. השדה nodeIds הוא אופציונלי. בלעדיו, ההרצה ממשיכה על הרכיבים שעליהם היא התחילה: הרצה של רכיבים שציינתם ממשיכה על אותם רכיבים, והרצה מלאה על כל הרכיבים. הרצת המשך של הרצת המשך שומרת על הרכיבים של ההרצה הראשונה. כל רכיב שנשאר נכשל או מעוכב מתווסף אליהם, יחד עם מה שהרכיבים האלה צריכים במעלה הזרם.
  • כל רכיב שאתם מציינים נחשב. עם nodeIds, רכיב שאף הרצה בשרשרת לא הריצה אף פעם נחשב כרכיב שנשאר, ולכן הוא רץ ונכלל באומדן המחיר. מכאן שציון של כל הרכיבים מריץ גם את כל הרכיבים שכל ההרצות בשרשרת השאירו בחוץ. רכיב שרץ באחת ההרצות בשרשרת לא ירוץ שוב רק כי ציינתם אותו.
  • רכיבים שאף פעם לא רצים. רכיבי מקור והעלאה, טריגרים, בוררים וקונטיינרים מסוג קבוצה או איסוף מעבירים הלאה את מה שההרצה העבירה. רכיב שהוגדר לדילוג, בתהליך או ב-inputOverrides של ההרצה, אף פעם לא רץ. כשמציינים רק רכיבים כאלה, לא נשאר שום דבר להריץ.
  • שרשראות עם הרצות המשך ישנות. הרצת המשך שרצה לפני שהכלל הזה נכנס לתוקף תיעדה רכיב כזה כרכיב שהושלם. בשרשרת כזו, גם כשמציינים את הרכיב, הוא עדיין נחשב כרכיב שהסתיים, ולכן הוא לא רץ. כדי להריץ אותו, המשיכו את ההרצה החדשה ביותר בשרשרת עם nodeIds בלבד, בלי continueMode. זה עובד רק כשההרצה הזו הושלמה. כשהיא נכשלה, המשיכו קודם מנקודת הכשל, בלי הרכיב הזה.
  • הרצת ההמשך החדשה ביותר קובעת. הרצת המשך כוללת את כל מה שההרצות שלפניה השלימו, ולכן השרת תמיד בונה על הרצת ההמשך החדשה ביותר של ההרצה. כשהרצת ההמשך הזו נכשלה, הבקשה נדחית עם continuation_superseded, שמציין אותה: המשיכו אותה במקום זאת. כשהיא כבר הריצה את כל מה שנשאר, אותו קוד אומר שהעבודה הסתיימה. כשהיא השלימה רק חלק ממה שנשאר, ההרצה נבנית עליה. התגובה 202 מציינת ב-continuedFrom את ההרצה שממנה ההרצה החדשה ממשיכה.
  • הרצת המשך שנעצרה בתצוגה מקדימה. הרצת המשך נוספת הייתה נעצרת באותה תצוגה מקדימה, ולכן הבקשה נדחית עם continuation_preview_pending. התגובה מציינת את הרצת ההמשך הזו ב-executionId, את הרינדורים שלה ב-renderNodeIds ואת רכיבי הידוק פרק שלה ב-reviewNodeIds. השדה next שבתגובה מתאר את ההרצה שמשלימה אותם: שלחו את next כגוף הבקשה של POST /v1/workflows/:id/run.
  • היתרה נבדקת קודם. הרצת המשך שהקרדיטים שלכם לא מכסים נדחית עם 402 insufficient_credits לפני שהיא מתחילה. האומדן שלה מחושב לפי מה שהיא עדיין מריצה. רכיב שההרצה שנכשלה השלימה אף פעם לא נכלל באומדן. רכיב שציינתם ושאף הרצה בשרשרת שלו לא הריצה אף פעם נכלל באומדן, כי הוא רץ.
  • שלחו כותרת Idempotency-Key. שתי הרצות המשך שנשלחות באותו רגע יכולות להתחיל שתיהן. עם אותו מפתח, ניסיון חוזר של הבקשה מחזיר את ההרצה שכבר התחילה, עם "deduped": true.

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

סטטוסקודמשמעות
409continuation_not_failedההרצה לא נכשלה.
409continuation_supersededהרצת המשך חדשה יותר של ההרצה נכשלה (המשיכו אותה במקום זאת), או שהיא השלימה את כל מה שנשאר. היא מצוינת ב-executionId וב-supersededBy: { executionId, status }.
409continuation_preview_pendingהרצת ההמשך החדשה ביותר נעצרה בתצוגה מקדימה. שלחו קודם את ה-next שלה.
409continuation_subset_requiredלא נשאר מה להמשיך, או שאף אחד מהרכיבים שעליהם ההרצה הראשונה התחילה כבר לא נמצא בתהליך. ציינו את הרכיבים ב-nodeIds, או התחילו הרצה חדשה.
409already_runningהרצה של התהליך הזה, כולל הרצת המשך, עדיין רצה. ה-executionId שלה נמצא בתגובה.

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

רינדור סופי

במקום לפרט את הרכיבים בעצמכם, ציינו את הרינדור ותנו לשרת לחשב את השאר. שלחו renderFinal עם מזהה הרכיב של הרינדור ועם continueFromExecutionId, ובלי nodeIds או inputOverrides. השרת מריץ את מה שהכפתור רינדור סופי מריץ בעורך: את הרינדור של רכיב החלת רשימת עריכה במצב סופי בהרצה הזו בלבד, ואז את כל הרכיבים שאחריו. כשרכיב מחליף מצלמות נמצא בין רכיב תוכנית עריכה לרינדור, רכיב מחליף מצלמות רץ שוב קודם. רכיב תוכנית עריכה לא רץ שוב. ההרצה היא אז הרצת המשך, עם אותן בדיקות.

{
  "renderFinal": { "renderNodeId": "<render node id>" },
  "continueFromExecutionId": "<a completed run whose render made a Preview>"
}

קבלו קודם אומדן מחיר עם POST /v1/workflows/:id/render-final/estimate וגוף בקשה { renderNodeId, continueFromExecutionId }. אומדן המחיר לא יוצר שום דבר ולא גובה קרדיטים. התגובה היא 200 עם { data: { renderNodeId, nodeIds, inputOverrides, estimatedCredits, holdCredits, sufficient, available } }:

  • השדות nodeIds ו-inputOverrides הם הרכיבים שההרצה מריצה והדריסה שהיא רצה איתה, { "<render node id>": { "quality": "final" } }.
  • השדה estimatedCredits הוא המחיר של הרכיבים שההרצה מריצה, כשהרינדור במצב סופי. כשההרצה מריצה רכיב LLM, התגובה מוסיפה estimatedCreditsIsEstimate: true: על הרכיב הזה משלמים לפי השימוש בפועל, ולכן הציגו את הסכום כ-≈N.
  • השדה holdCredits הוא מה שמשוריין להרצה בזמן הרינדור. לרכיב קליפ UGC משוריינים קרדיטים בערך פי שניים מהמחיר שלו, והחלק שלא נדרש חוזר כשהקליפ מסתיים. הערך holdCredits אף פעם לא נמוך מ-estimatedCredits.
  • השדה sufficient אומר אם הקרדיטים שלכם מכסים את השריון הזה, והשדה available הוא הקרדיטים שזמינים לכם להוצאה. הערך available הוא null כשתקציב של סביבת עבודה או חשבון החיוב של פריסה משלמים.
  • כל שלושת הסכומים הם null במהדורה בלי קרדיטים.

בקשת האומדן נדחית עם הקודים של הרצות ההמשך שלמעלה. שני הנתיבים דוחים בקשות גם עם הקודים האלה:

סטטוסקודמשמעות
400render_final_node_not_foundאין בתהליך רכיב עם המזהה הזה.
400render_final_not_a_renderהרכיב הוא לא רינדור של רכיב החלת רשימת עריכה.
400validation_errorהשדה renderFinal נשלח עם nodeIds או inputOverrides, או בלי continueFromExecutionId.

רינדור סופי בודק את היתרה שלכם לפני שהוא מתחיל, מול ה-holdCredits של אומדן המחיר. בקשה להרצה שאתם לא יכולים לכסות נדחית עם 402 insufficient_credits, עם required, שהוא השריון הזה, ועם available, ושום הרצה לא נוצרת. הבדיקה מכסה רק את היתרה. מודל שהתוכנית שלכם לא מאפשרת, או מגבלה יומית, עדיין נדחים ברכיב עצמו כשההרצה מגיעה אליו.

הרצת תהליך עם ערכי קלט חדשים

הנתיב POST /v1/api/run מקבל אובייקט inputs שמחליף את הערכים של רכיבי הקלט בהרצה האחת הזו. האימות בנתיב הזה נעשה עם אסימון API אישי. המפתחות של inputs הם מזהי רכיבים, או, לנוחותכם, תוויות ייחודיות של רכיבים. בתוך כל מפתח, ציינו את שדה הקלט של הרכיב, כגון text בפרומפט טקסט.

פרומפטטקסטtext-prompt-1יצירת תמונהgenerate-image-1
התהליך שבדוגמה: רכיב טקסט, שהרצה דרך ה-API מחליפה את הטקסט שלו, מזין רכיב יצירת תמונה.

הדוגמה שלמטה מריצה תהליך שבו רכיב טקסט עם המזהה text-prompt-1 מחובר לרכיב יצירת תמונה.

מציאת שדות הקלט

הנתיב GET /v1/api/schema מפרט את הקלטים של התהליך, עם השדה שכל אחד מהם מקבל, את הפלטים שלו ואת אומדן הקרדיטים להרצה:

curl -s "https://app.nodaro.ai/v1/api/schema?workflowId=$WORKFLOW_ID" \
  -H "Authorization: Bearer $NODARO_API_KEY"
{
  "workflowId": "8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f",
  "name": "Sunset stills",
  "estimatedCredits": 50,
  "inputs": [
    { "nodeId": "text-prompt-1", "key": "text", "label": "Prompt", "type": "text" }
  ],
  "outputs": [
    { "nodeId": "generate-image-1", "label": "Generate Image", "type": "image" }
  ]
}

כשבתהליך יש רכיב LLM שמשלמים עליו לפי השימוש בפועל, התגובה מוסיפה estimatedCreditsIsEstimate: true, והשדה estimatedCredits הוא אומדן: הציגו אותו כ-≈N. התגובה מתארת גם תהליך שמציין מודל LLM שעדיין אין לו מחיר. במקרה הזה השדה estimatedCredits מושמט, והשדה estimatedCreditsUnpriced: { reason: "llm_model_unpriced", modelId, message } מסביר למה. ההרצה של תהליך כזה נדחית. ראו בדף ה-API מודל שעדיין אין לו מחיר.

התחלת ההרצה

curl -s -X POST https://app.nodaro.ai/v1/api/run \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "workflowId": "8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f",
        "inputs": {
          "text-prompt-1": { "text": "a cat at sunset" }
        }
      }'
{ "executionId": "3f9e2b1a-7c6d-4e5f-8a9b-0c1d2e3f4a5b", "status": "pending" }

בדיקת הסטטוס עד שההרצה מסתיימת

הנתיב GET /v1/api/status/:execId מחזיר את הסטטוס, את ספירת הרכיבים ואת הקרדיטים שהוצאו עד כה. בדקו את הסטטוס כל 2–5 שניות, עד שהוא completed, failed, cancelled, timed_out או discarded.

קבלת התוצאה

הנתיב GET /v1/api/result/:execId מחזיר את הפלטים של הרצה בסטטוס completed או failed. בהרצה שהסתיימה בסטטוס cancelled, timed_out או discarded, השתמשו במקום זאת ב-errorMessage מתגובת הסטטוס: להרצות האלה אין מטען של תוצאה, ונתיב התוצאה ממשיך להחזיר 202.

{
  "executionId": "3f9e2b1a-7c6d-4e5f-8a9b-0c1d2e3f4a5b",
  "status": "completed",
  "outcome": "succeeded",
  "creditsUsed": 50,
  "durationMs": 12450,
  "errorMessage": null,
  "outputs": [
    {
      "nodeId": "generate-image-1",
      "label": "Generate Image",
      "type": "image",
      "url": "https://…/output.png"
    }
  ]
}

הרצף כולו כסקריפט אחד, ואותן קריאות מ-TypeScript:

BASE="https://app.nodaro.ai"
WORKFLOW_ID="8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f"

EXEC=$(curl -s -X POST "$BASE/v1/api/run" \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"workflowId\": \"$WORKFLOW_ID\", \"inputs\": {\"text-prompt-1\": {\"text\": \"a cat at sunset\"}}}" \
  | jq -r .executionId)

while true; do
  STATUS=$(curl -s -H "Authorization: Bearer $NODARO_API_KEY" \
    "$BASE/v1/api/status/$EXEC" | jq -r .status)
  echo "Status: $STATUS"
  case "$STATUS" in completed|failed|cancelled|timed_out|discarded) break;; esac
  sleep 5
done

curl -s -H "Authorization: Bearer $NODARO_API_KEY" "$BASE/v1/api/result/$EXEC" | jq .
// The /v1/api/ lane has no dedicated SDK method: call it with client.request.
const schema = await client.request('GET', '/v1/api/schema', {
  query: { workflowId },
})

const { executionId } = await client.request<{ executionId: string }>('POST', '/v1/api/run', {
  body: { workflowId, inputs: { 'text-prompt-1': { text: 'a cat at sunset' } } },
})

const final = ['completed', 'failed', 'cancelled', 'timed_out', 'discarded']
let status = 'pending'
while (!final.includes(status)) {
  await new Promise((r) => setTimeout(r, 3_000))
  ;({ status } = await client.request<{ status: string }>('GET', `/v1/api/status/${executionId}`))
}

const result = await client.request('GET', `/v1/api/result/${executionId}`)

ה-CLI מריץ תהליכים רק עם הערכים השמורים שלהם. כדי להעביר ערכים מהטרמינל, פרסמו את התהליך כאפליקציה והריצו את הפקודה nodaro apps run <slug> --input prompt="…".

מאפיין

סוג

אסימון מוגבל לתהליכים יכול להריץ רק את התהליכים שבמגבלת התהליכים שלו. בקשה לכל תהליך אחר נדחית עם 403 forbidden. הנתיבים POST /v1/api/run ו-GET /v1/api/workflows נספרים במגבלה לדקה של האסימון; קריאות הסטטוס, התוצאה והסכמה לא נספרות. ראו את דף ה-API מגבלות קצב.

סינכרוני או אסינכרוני

הנתיב POST /v1/api/run אסינכרוני כברירת מחדל: הוא מחזיר מיד 202 Accepted עם { executionId, status: "pending" }, ומשם בודקים את הסטטוס מדי כמה שניות.

בתהליך קצר, השאירו את החיבור פתוח עד שההרצה מסתיימת:

POST /v1/api/run?wait=true&timeout=120
  • השרת בודק את ההרצה כל 5 שניות, למשך timeout שניות לכל היותר. ברירת המחדל היא 120 והמקסימום הוא 600.
  • אם ההרצה מסתיימת בזמן, התגובה היא אותו מטען כמו של GET /v1/api/result/:execId. ה-status שלו הוא completed, failed, cancelled, timed_out או discarded.
  • אם לא, התגובה היא 202 עם { executionId, status: "pending" }, ומשם בודקים את הסטטוס מדי כמה שניות.

השתמשו בצורה הסינכרונית בהרצות שאתם מצפים שיסתיימו בפחות מדקה, כגון יצירת טקסט ועבודה קלה על תמונות. השתמשו בצורה האסינכרונית בתהליכים שמרנדרים וידאו או מגדילים וידאו. ב-SDK, הגדירו ב-createClient ערך timeoutMs גבוה מה-timeout שלכם, כי כברירת מחדל הלקוח מוותר אחרי 60 שניות.

הנתיב POST /v1/workflows/:id/run ונתיבי היצירה הם תמיד אסינכרוניים. בהרצה של רכיב יחיד, המתודה nodes.runAndWait של ה-SDK בודקת בשבילכם את הסטטוס של המשימה: ראו את דף ה-API הרצת רכיב יחיד.

הרצות שלא מוצאות שום דבר חדש

להרצה מתוזמנת אין לעיתים קרובות מה לעשות, כי בפיד שהיא קוראת אין פוסטים חדשים. הרצה כזו מסתיימת בסטטוס completed, לא failed:

  • Nodaro מדלג על רכיב ששולח טקסט למודל או לקול כשהטקסט שלו ריק, והטקסט הזה הגיע מרכיב שלא הפיק כלום בהרצה הזו. הוא מדלג גם על הרכיבים שאחריו. הרכיבים האלה הם יצירת טקסט, יצירת תסריט, טקסט לדיבור, יצירת מוזיקה וטקסט לאודיו.
  • Nodaro מדלג גם על רכיב פלט ששולח את מה שמחובר אליו, כגון רכיב פלט Webhook ורכיבי הפרסום לרשתות החברתיות, כשאף אחד מהחיבורים שלו לא העביר כלום בהרצה הזו.
  • על רכיב שדולג לא משלמים. רכיב פיד ערוץ טלגרם שלא מחזיר פוסטים חדשים לא עולה כלום.

בהרצה כזו, הנתיבים GET /v1/api/status/:execId ו-GET /v1/api/result/:execId, והתגובה של ?wait=true, כוללים "outcome": "nothing_new". בכל הרצה אחרת שהושלמה, הערך הוא "succeeded". בהרצה שנכשלה או שבוטלה אין outcome, רק status. השדה errorMessage נשאר null, כי שום דבר לא השתבש. ב-GET /v1/workflow-executions/:id, המצב של כל רכיב שדולג הוא { "status": "skipped", "skipReason": "empty_input" }.

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

מה הרצה לא יכולה לשנות

בקשת הרצה לא יכולה לשנות את היעדים של רכיבים שפונים לשירות חיצוני. התהליך עצמו קובע לאן הוא שולח נתונים ומאיפה הוא מביא אותם, בכל נקודת קצה של הרצה, כולל POST /v1/workflows/:id/run, POST /v1/api/run ו-POST /v1/app/:slug/run.

הרכיבים שפונים לשירות חיצוני הם רכיב פלט Webhook, רכיבי הפרסום לרשתות החברתיות, כגון רכיב פרסום לרשתות, והרכיבים שמביאים נתונים מבחוץ, כגון גריפת אתר, פיד ערוץ טלגרם וכתובת וידאו. ברכיבים האלה, דריסה לא יכולה לשנות:

  • שום שדה שהשם שלו מסתיים ב-Url או ב-Urls;
  • את target, targets, query, channel, chatId, connectionId, credentialId, platform, webhook, endpoint, host או privacy;
  • את שדות הבחירה actor ו-mode, שקובעים מאיזה שדה יעד הרכיב קורא.

הכלל חל גם על ערכים שמקוננים בתוך אובייקט או ברשומה של fieldMappings, וגם על ערך ריק, לא רק על כתובת חדשה: ריקון של יעד היה גורם לרכיב לקרוא במקומו את הטקסט מהרכיב שבמעלה הזרם. בקשה כזו נדחית עם 400 locked_field עוד לפני שמשהו רץ. השגיאה מציינת עד עשרה מהשדות הבעייתיים וסופרת את השאר, ודריסה שמקוננת ביותר מ-32 רמות ברכיב כזה נדחית על הסף.

עדיין אפשר לדרוס שדות רגילים ברכיבים האלה, כגון כיתוב או מגבלה, ואת שדות ה-url של המדיה ברכיבי קלט, כגון העלאות ואודיו ייחוס.

הרצה גם לא יכולה לשנות מה רכיב תת־תהליך מריץ. ניסיון לשנות את workflowId, selectedRouteId או routeSnapshot שלו נדחה עם 400 locked_field, בין אם קובעים אותם ישירות ובין אם דרך רשומה של fieldMappings. התהליך עצמו קובע איזה תהליך הרכיב מריץ, ואיזה חלק ממנו.

ברכיבים של סרטון UGC, הרצה יכולה לקבוע רק את source, gender ו-photoUrl של רכיב יוצר/ת UGC, ואת targetDurationSec של רכיב תסריט UGC. בקשה שקובעת כל שדה אחר, כגון תוצאה שנשמרה, תסריט או קליפ, נדחית עם 400 locked_field. הרצה של רכיב יוצר/ת UGC שמוגדר לאפשרות התמונה שלי נדחית עם 400 ugc_photo_required לפני שנגבים קרדיטים, אם מי שמריץ אותה לא נתן תמונה של עצמו. ראו את הדף יוצר/ת UGC ואת הסעיף סרטון UGC באפליקציה.

באפליקציה שפורסמה, כשהאפליקציה חושפת מודל או הגדרה מהירה עם רשימה קבועה של אפשרויות, הערך מוגבל לרשימה הזו: ערך מחוץ לרשימה נדחה עם 400 validation_error, וכך גם מספר מחוץ לטווח של הגדרה. ערך null ב-inputOverrides מנקה את השדה הזה ברכיב בהרצה הזו, ולכן ברירת המחדל של הרכיב עצמו חלה. ערך null בקלט שטוח, לעומת זאת, מושמט, ולכן הערך השמור חל. ראו את הסעיף שדות של מודל ושל הגדרות מהירות בדף הטמעת מיני־אפליקציה.

תיקוני פרמטרים

נתיבי היצירה של תמונות ושל סרטונים מקבלים אוסף אחד של ערכים ל-aspectRatio, ל-resolution ול-quality, בלי קשר למודל. אף מודל לא תומך בכל האוסף. במקום לדחות ערך שהמודל שנבחר לא מקבל, השרת מתקן אותו לערך שהמודל כן מקבל, ומודיע לכם מה הוא שינה. דחייה באמצע תהליך הייתה מכשילה גם את הרכיבים שרצו לצד הרכיב שנדחה, שכבר יצרו תוצאה ושכבר שילמתם עליהם.

הנתיבים שמתקנים ערכים הם POST /v1/generate-image, /v1/image-to-image, /v1/edit-image, /v1/text-to-video ו-/v1/generate-video:

{
  "jobId": "0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10",
  "adjustments": [
    {
      "field": "aspectRatio",
      "from": "3:2",
      "to": "auto",
      "reason": "GPT Image 2 does not support aspectRatio \"3:2\" — using \"auto\" instead. Supported: auto, 1:1, 16:9, 9:16, 4:3, 3:4."
    },
    {
      "field": "resolution",
      "from": "4K",
      "to": "1K",
      "reason": "GPT Image 2 only renders 1K at the \"auto\" aspect ratio."
    }
  ]
}
  • adjustments לא מופיע כששום דבר לא השתנה. התגובה לבקשה תקינה היא בדיוק { "jobId": "…" }.
  • to לא מופיע כשלמודל אין הגדרה כזו והערך הושמט, למשל aspectRatio שנשלח למודל הגדלה.
  • הקרדיטים נקבעים לפי הערך המתוקן. בקשה ל-GPT Image 2 עם auto ב-2K מרונדרת ומחויבת ב-1K, כי auto מרנדר רק ב-1K.
  • aspectRatio: "auto" שומר על הצורה של התמונה שלכם ב-/v1/image-to-image וב-/v1/edit-image. מודל שיש לו auto משלו מקבל אותו כמו שהוא. במודל בלי auto כזה, השרת קורא את הגודל של imageUrl, משתמש ביחס הקרוב ביותר שהמודל תומך בו ומדווח על הבחירה ב-adjustments. למשל, תמונה לאורך בגודל 1104 × 1472 שנשלחת ל-seedream-5-pro-i2i מרונדרת ב-3:4. כשאי אפשר לקרוא את הגודל, הערך auto חוזר ליחס הראשון ברשימה של המודל. במודלים האלה היחס אף פעם לא משנה את המחיר.
  • /v1/generate-image עושה את אותו הדבר כשתמונה מחוברת. התמונה היא התמונה הראשונה שהבקשה שולחת למודל: השדה baseImageUrl (השלמה או עידון) כשהוא מוגדר, ואחרת תמונת הייחוס הראשונה (referenceImageUrls, או הראשונה שנבנית מ-connectedReferences). בלי תמונה, הערך auto במודל בלי auto משלו נותן את היחס הראשון ברשימה של המודל.
  • גם תהליכים שמורים מתוקנים. תהליך שנשמר דרך ה-API או דרך MCP מקבל את אותם תיקונים כשהוא נכתב. החריג הוא auto ברכיב מסוג generate-image, image-to-image, modify-image או edit-image: הוא נשמר כמו שהוא, ומקבל ערך לפי התמונה כשהתהליך רץ.
  • הערכים שכל מודל מקבל מופיעים ב-GET /v1/models. ראו בדף ה-API גילוי מודלים.

תיקונים בנתיבי הווידאו

הנתיבים /v1/text-to-video ו-/v1/generate-video מחזירים adjustments באותו מבנה. הנתיב /v1/generate-video גם חוזר על ה-reason של כל תיקון במערך warnings שלו, לצד אזהרות שלא קשורות לפרמטרים, כגון voice_unsupported_for_provider. בדקו את adjustments כשאתם צריכים לדעת איזו הגדרה זזה. השניים אף פעם לא סותרים זה את זה.

  • ערך שאין לו תמיכה עובר לאפשרות הקרובה ביותר, אף פעם לא לזולה ביותר או לראשונה. בקשה ל-4k במודל שמגיע לכל היותר ל-1080p מרונדרת ב-1080p, לא ב-480p, ויחס 9:21 לאורך הופך ל-9:16, לא ל-16:9.
  • כש-resolution מושמט, הבקשה נשלחת ברמת הרזולוציה שלפיה היא מתומחרת. כשהפלטפורמה מגדירה למודל רמת ברירת מחדל, משלמים לפי הרמה הזו, והמודל מתבקש לרנדר בה. הערך מופיע ב-input_data של המשימה, כך שתמיד אפשר לראות מה נשלח.
  • צורת הכתיבה מתוקננת לפני התמחור. הערך 4K מתפרש כ-4k, ולכן הוא מתומחר ומרונדר ברמת ה-4K.
  • חלק מהמודלים מרנדרים רמה קבועה לכל ערך אחר. MiniMax H3 מרנדר 2K לכל ערך שהוא לא 768P, ומשפחת Wan 3.0 מרנדרת 720p. במודלים האלה, התיקון מכוון לרמה שהמודל ייצר בפועל, כך שהמחיר תואם לרינדור. הרשומה של המודל ב-GET /v1/models מצהירה על כך ב-unlistedResolutionRendersAs.
  • משלמים לפי האורך שהמודל מרנדר. בקשה בלי duration מרונדרת, ומחויבת, לפי אורך ברירת המחדל של המודל עצמו, defaultDuration ב-GET /v1/models. ערך duration שהמודל לא מציע עובר לאורך הקרוב ביותר שהוא כן מציע, ובתיקו נבחר האורך הקצר יותר. השינוי מדווח ב-adjustments. למשל, בקשה ל-7 שניות ב-Kling מרונדרת ומחויבת לפי 5 שניות, ובמודל LTX 2.3 היא מרונדרת ומחויבת לפי 6 שניות.
  • duration: -1 פירושו אוטומטי במודלים שתומכים בכך, משפחת Seedance 2 (autoDuration: true ב-GET /v1/models). המודל בוחר את אורך הקליפ, שהוא האורך של קליפ המקור כשהמודל עורך סרטון ייחוס. בהרצה במצב אוטומטי משוריינים קרדיטים לפי הקליפ הארוך ביותר של המודל, והקרדיטים על ההפרש מוחזרים לפי האורך שנמסר. עם סרטוני ייחוס שהאורך שלהם נמדד, השריון נקבע במקום זאת לפי האורך של הקליפ הראשון, מעוגל כלפי מעלה לשנייה שלמה ועוד שנייה אחת, ולעולם לא יותר מהקליפ הארוך ביותר של המודל. מודלים אחרים מתעלמים מ--1 ומרנדרים את אורך ברירת המחדל שלהם.

נתיבי התמונות של דמויות ומיקומים (/v1/generate-character, /v1/generate-character-asset, /v1/generate-location ו-/v1/generate-location-asset) מתקנים את quality ואת resolution באותו אופן, אבל לא מחזירים adjustments. הערך המתוקן מופיע רק ב-input_data של המשימה, מ-GET /v1/jobs/:id.

ניהול תהליכים

רשימה וקריאה

הנתיב GET /v1/projects/:projectId/workflows מחזיר את התהליכים של פרויקט בלי nodes, edges ו-settings. הנתיב GET /v1/workflows/:id מחזיר תהליך אחד במלואו. בארגון, הרשימה נקבעת לפי סביבת העבודה שבה אתם פועלים: ראו את דף ה-API סביבות עבודה.

curl -s https://app.nodaro.ai/v1/projects/$PROJECT_ID/workflows \
  -H "Authorization: Bearer $NODARO_API_KEY" | jq '.data[] | {id, name}'
const { data: workflows } = await client.workflows.list({ projectId })
const { data: workflow } = await client.workflows.get(workflows[0].id)
console.log(workflow.nodes.length)
nodaro workflows list --project $PROJECT_ID --json
nodaro workflows get 8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f

יצירה ועדכון

צרו תהליך בפרויקט עם POST /v1/projects/:projectId/workflows. כל השדות חוץ מהפרויקט הם אופציונליים, ושדה שלא שולחים מקבל את ברירת המחדל של השרת:

const { data: wf } = await client.workflows.create({
  projectId,
  name: 'My workflow',
  nodes: [],
  edges: [],
})

הנתיב PATCH /v1/workflows/:id משנה כל צירוף של שדות. כדי שעדכון יהיה בטוח מפני עריכה במקביל, שלחו expectedVersion, הערך השלם של version מהקריאה האחרונה שלכם. כשהתהליך השתנה מאז, העדכון נדחה עם 409 workflow_conflict, והשגיאה כוללת את currentVersion, currentUpdatedAt ו-currentRecord, התהליך הנוכחי כולו. מזגו את השינוי שלכם לתוך currentRecord ושמרו שוב, בלי קריאה נוספת. השדה expectedUpdatedAt, חותמת זמן, עובד באותו אופן.

import { WorkflowConflictError } from '@nodaro/sdk'

try {
  await client.workflows.update(id, { name: 'Renamed', expectedVersion: 7 })
} catch (err) {
  if (err instanceof WorkflowConflictError && err.currentRecord) {
    await client.workflows.update(id, { name: 'Renamed', expectedVersion: err.currentVersion })
  } else throw err
}
  • ערכי מצב ההרצה ב-data של רכיב, כגון סטטוס ההרצה שלו, המשימה הנוכחית וההתקדמות, מוסרים בשמירה ואף פעם לא נשמרים.
  • השדה thumbnailUrl קובע את תמונת השער של התהליך מכתובת של תמונה שכבר מאוחסנת. הערך null מנקה אותה.
  • שמירה ששולחת רק edges ומחברת שכבה של רכיב שכבה על וידאו כותבת מחדש את הרכיב הזה, ולכן היא נדחית עם 409 workflow_conflict כשהתהליך השתנה מאז שקראתם אותו, גם בלי expectedVersion.
  • השדה visibility הוא private או workspace. רק היוצר או מנהל של סביבת העבודה יכולים לשנות אותו, ובקשה לתהליך שלא נמצא בסביבת עבודה נדחית עם 400 not_workspace_scoped.

מחיקה

הנתיב DELETE /v1/workflows/:id מוחק תהליך. היוצר ומנהל של סביבת העבודה יכולים למחוק אותו, אבל שותף אף פעם לא. מחיקה של תהליך שלא קיים, או שאתם לא יכולים לראות, נדחית עם 404, כך שמחיקה שלא קרתה אף פעם לא נראית כמו הצלחה. בקשה של שותף שיכול לראות את התהליך אבל אין לו הרשאה למחוק אותו נדחית עם 403.

ייצוא וייבוא

הנתיב GET /v1/workflows/:id/export מחזיר את התהליך כחבילת JSON ניידת. עם ?assets=true, החבילה כוללת גם את הדמויות, האובייקטים והמיקומים שהתהליך משתמש בהם, אם הם שלכם. כשרכיבים מצביעים על מדיה שהתקנה אחרת לא יכולה להגיע אליה, כגון קבצים ב-localhost או ברשת פרטית, החבילה מפרטת אותה ב-portability.unreachableMedia. מי שיש לו גישת צפייה מקבל את התהליך בלי טיוטות ה-Studio של הבעלים: משבצות המדיה הריקות, הסימונים של הרצות שעדיין רצות ותוכניות הקול של הטייקים. במקרה כזה, החבילה לא כוללת נכס שרק החלקים האלה משתמשים בו. גם GET /v1/workflows/:id משמיט את אותם חלקים בשביל מי שיש לו גישת צפייה.

הנתיב POST /v1/workflows/import יוצר תהליך מחבילה:

POST /v1/workflows/import
{ "projectId": "<project uuid>", "workflow_json": { "version": 1, "name": "…", "nodes": [], "edges": [] } }

הייבוא יוצר מחדש בחשבון שלכם את הדמויות, האובייקטים, היצורים והמיקומים שבחבילה, ומעדכן את הרכיבים כך שיצביעו עליהם. הוא מעתיק מדיה נגישה לאחסון של ההתקנה הזו: עד 25 קבצים למדיה של התהליך ועוד 25 לנכסים שבחבילה, עם תמונות עד 20 MB ווידאו או אודיו עד 50 MB. התגובה כוללת את התהליך החדש ו-importReport:

שדהמשמעות
rehostedכמה קבצים הועתקו להתקנה הזו.
unreachableמדיה בשרתים פרטיים. הרכיבים ממשיכים להצביע על המקום המקורי שלה, ולא רצים עד שמעלים את הקובץ שוב.
skippedמדיה שאי אפשר היה להעתיק, עם הסיבה, כגון HTTP 404.
assetIdMapכל מזהה של נכס בחבילה, ממופה לרשומה שנוצרה בשבילו.
assetsSkippedנכסים שלא היה להם מקום במכסת האחסון שלכם. התהליך בכל זאת נוצר.

מה-CLI: nodaro workflows export <id> --with-assets --output bundle.json, ואז nodaro workflows import bundle.json --project <projectId>. ראו את המדריך ייבוא וייצוא כדי לדעת מה עובר עם התהליך.

שיחות MCP

GET /v1/mcp-conversations?month=2026-10&sources=claude,chatgpt

הנתיב הזה מפרט את שיחות ה-MCP שלכם בחודש אחד, מהחדש לישן. כל שיחה היא תהליך שעוזר AI בנה מהשלבים של השיחה. ראו את הדף איך שיחות MCP הופכות לתהליכים. אסימון OAuth צריך את workflows:read.

פרמטר שאילתהמשמעות
monthYYYY-MM. ברירת המחדל היא החודש האחרון שיש בו שיחות.
sourcesהמקורות שנשארים ברשימה, מופרדים בפסיקים: claude, claude-code, chatgpt או שם של לקוח אחר באותיות קטנות. ברירת המחדל היא כל המקורות.

התגובה כוללת:

  • month: החודש שמוצג.
  • months: כל חודש שיש בו שיחות, מהחדש לישן, עם מספר השיחות בו.
  • sources: המקורות של החודש שמוצג, עם מספר השיחות של כל אחד. מקור מאחד את החיבורים של מוצר אחד: "Claude Code (nodaro)" ו-"Claude Code (staging)" הם מקור claude-code אחד. השדה connections מפרט אותם.
  • data: השיחות. לכל שיחה יש:
    • השדות id ו-projectId. שיחה היא תהליך, ולכן פותחים אותה, משנים את שמה, מייצאים, מעתיקים או מוחקים אותה עם נתיבי התהליכים.
    • השדות name, client, clientLabel ו-clientName.
    • השדות startedAt, lastActivityAt ו-live. הערך live הוא true כל עוד עברו פחות מ-30 דקות מהשלב האחרון.
    • firstRequest: הבקשה הראשונה שלכם, כשהעוזר העביר אותה.
    • השדות nodeCount ו-counts לפי סוג: image, video ו-audio.
    • credits: הקרדיטים שנגבו על המשימות של השיחה, או null כשלא גובים קרדיטים.
    • cover: { url, kind, setByUser }. תמונת השער שקבעתם, ואם לא קבעתם, התוצאה האחרונה.

הנתיב DELETE /v1/workflows/:id על שיחה מוחק את התהליך שלה. המשימות שהעוזר יצר לא מתויקות בתהליך, ולכן התמונות והסרטונים שלהן נשארים בספרייה שלכם. הרצות שהתחילו בעורך נמחקות יחד עם התהליך, כמו בכל תהליך. אי אפשר למחוק את התהליך המרכזי של חודש: הנתיב מחזיר 409 mcp_hub. מפתח API אישי שמוגבל לחלק מהתהליכים לא יכול להציג את רשימת השיחות, ובקשה שלו נדחית עם 403.

העברה לפרויקט אחר

POST /v1/workflows/:id/move
{ "projectId": "…" }

העברה היא כתיבה לתהליך, ולכן אסימון OAuth צריך את workflows:write. גם הנתיב PATCH /v1/workflows/:id עם projectId עושה את אותו הדבר ופועל לפי אותם כללים. אפשר להעביר עבודה שיצרתם. בתוך ארגון, מנהל של סביבת עבודה יכול גם להעביר עבודה בין שתי סביבות עבודה שהוא מנהל. בפרויקט אישי, גם פרויקט המקור וגם פרויקט היעד חייבים להיות שלכם.

סטטוסקודמשמעות
400validation_errorהתהליך כבר נמצא בפרויקט הזה.
403not_permittedאין לכם הרשאה להעביר את התהליך, או להעביר אותו לשם.
404not_foundאין תהליך כזה, או שאין לכם פרויקט כזה.
409move_blockedהעבודה נוצרה במסגרת מטלה.
409workspace_archivedסביבת העבודה שאליה מעבירים נמצאת בארכיון.

העברה שמשנה את סביבת העבודה מסירה את ההרשאות של השותפים בתהליך ומדווחת עליהן, כדי שתוכלו להודיע לאנשים שאיבדו את הגישה:

{
  "data": { "id": "8c2d7f1e-3a4b-4c5d-9e6f-7a8b9c0d1e2f", "projectId": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716" },
  "droppedCollaborators": [{ "userId": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f70812", "name": "Sam" }]
}

בצורת ה-PATCH, השדה droppedCollaborators מופיע רק כשהוסרה הרשאה.

שתי הצורות מחזירות ב-data את התהליך שהועבר, כמו שהוא עכשיו. כשהגישה שלכם אליו אחרי ההעברה נמוכה מ-edit, אתם מקבלים אותו כמו מי שיש לו גישת view. זה קורה, למשל, כשמנהל של סביבת עבודה מעביר עבודה של אחד החברים בה לסביבת עבודה שבה מנהלים יכולים רק לצפות בעבודות. ראו את דף ה-API סביבות עבודה וארגונים.

הרשאות OAuth לתהליכים

הרשאהנתיבים
workflows:readGET /v1/projects/:projectId/workflows, GET /v1/workflows, GET /v1/workflows/:id, GET /v1/workflows/:id/export, GET /v1/mcp-conversations
workflows:writeיצירה, עדכון, מחיקה, ייבוא והעברה, וגם POST /v1/workflows/:parentId/sub-workflows
workflows:executePOST /v1/workflows/:id/run

אסימוני API אישיים לא צריכים הרשאות. ראו את הדף אפליקציות OAuth.

רכיבים של הפקות Studio

חלק מהרכיבים על הקנבס שייכים להפקת Studio ותלויים בפריימים מקושרים. צריך ליצור אותם דרך ה-API של הפקות Studio: הרצה שלהם דרך POST /v1/workflows/:id/run, או יצירה ישירה של אחד מהם, נדחית עם 400 sequence_execution_required. ראו את דף ה-API הפקות Studio.

שאלות נפוצות

איך מריצים תהליך של Nodaro דרך ה-API?

שלחו POST /v1/workflows/:id/run. הבקשה מריצה את התהליך השמור ומחזירה 202 עם executionId, ואיתו בודקים את הסטטוס מדי כמה שניות. כדי לשנות ערכי קלט בהרצה אחת, הוסיפו אובייקט inputOverrides שהמפתחות שלו הם מזהי רכיבים, או השתמשו ב-POST /v1/api/run עם אובייקט inputs.

איך מעבירים ערכי קלט להרצה של תהליך?

שלחו אובייקט inputs ל-POST /v1/api/run. המפתחות שלו הם מזהי רכיבים או תוויות ייחודיות של רכיבים, ובתוך כל מפתח נמצא השדה של הרכיב, למשל text. נקודת הקצה GET /v1/api/schema מפרטת את שדות הקלט של תהליך.

האם אפשר לחכות לתוצאה של תהליך בבקשה אחת?

כן. הוסיפו ל-POST /v1/api/run את פרמטרי השאילתה wait=true ו-timeout=120. השרת משאיר את החיבור פתוח עד 600 שניות ומחזיר את הפלטים, או מחזיר 202 עם executionId כשההרצה עדיין נמשכת, ומשם ממשיכים לבדוק את הסטטוס מדי כמה שניות.

למה ה-API שינה את יחס הגובה־רוחב או את הרזולוציה ששלחתי?

המודל שבחרתם לא תומך בערך הזה, ולכן Nodaro תיקן אותו לערך הקרוב ביותר שהמודל מקבל, במקום להכשיל את ההרצה. התגובה מפרטת כל שינוי בשדה adjustments, והקרדיטים נגבים לפי הערך המתוקן.

האם הרצה דרך ה-API יכולה לשנות לאן תהליך שולח את התוצאות שלו?

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

עודכן לאחרונה

בדף הזה