תהליכים
הרצת תהליכים שמורים של 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 כשהיא מבוטלת.
| סטטוס | קוד | משמעות |
|---|---|---|
| 402 | insufficient_credits | הרצת המשך או רינדור סופי שהקרדיטים שלכם לא מכסים. שום דבר לא נוצר. |
| 403 | forbidden | מותר לכם לראות את התהליך, אבל לא להריץ אותו. בסביבת עבודה, הרצה דורשת גישת עריכה וחברות פעילה. |
| 404 | not_found | אין תהליך כזה, או שאין לכם גישה לראות אותו. |
| 409 | already_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. אחרת הבקשה נדחית לפני שנוצרת הרצה כלשהי:
| סטטוס | קוד | משמעות |
|---|---|---|
| 400 | continuation_subset_required | השדה nodeIds חסר או ריק, בלי continueMode. |
| 400 | continuation_workflow_mismatch | ההרצה הקודמת הריצה תהליך אחר. |
| 400 | continuation_version_mismatch | ההרצה הקודמת הריצה גרסת אפליקציה שפורסמה של התהליך. כדי להמשיך הרצת אפליקציה שנכשלה, השתמשו בניסיון החוזר של האפליקציה. |
| 400 | validation_error | השדה continueFromExecutionId הוא לא מזהה של הרצה. |
| 404 | continuation_not_found | אין הרצה כזו, או שההרצה לא שלכם. |
| 409 | continuation_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.
בקשה להמשיך הרצה שנכשלה נדחית גם עם הקודים האלה, בנוסף לקודים שלמעלה:
| סטטוס | קוד | משמעות |
|---|---|---|
| 409 | continuation_not_failed | ההרצה לא נכשלה. |
| 409 | continuation_superseded | הרצת המשך חדשה יותר של ההרצה נכשלה (המשיכו אותה במקום זאת), או שהיא השלימה את כל מה שנשאר. היא מצוינת ב-executionId וב-supersededBy: { executionId, status }. |
| 409 | continuation_preview_pending | הרצת ההמשך החדשה ביותר נעצרה בתצוגה מקדימה. שלחו קודם את ה-next שלה. |
| 409 | continuation_subset_required | לא נשאר מה להמשיך, או שאף אחד מהרכיבים שעליהם ההרצה הראשונה התחילה כבר לא נמצא בתהליך. ציינו את הרכיבים ב-nodeIds, או התחילו הרצה חדשה. |
| 409 | already_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במהדורה בלי קרדיטים.
בקשת האומדן נדחית עם הקודים של הרצות ההמשך שלמעלה. שני הנתיבים דוחים בקשות גם עם הקודים האלה:
| סטטוס | קוד | משמעות |
|---|---|---|
| 400 | render_final_node_not_found | אין בתהליך רכיב עם המזהה הזה. |
| 400 | render_final_not_a_render | הרכיב הוא לא רינדור של רכיב החלת רשימת עריכה. |
| 400 | validation_error | השדה renderFinal נשלח עם nodeIds או inputOverrides, או בלי continueFromExecutionId. |
רינדור סופי בודק את היתרה שלכם לפני שהוא מתחיל, מול ה-holdCredits של אומדן המחיר. בקשה להרצה שאתם לא יכולים לכסות נדחית עם 402 insufficient_credits, עם required, שהוא השריון הזה, ועם available, ושום הרצה לא נוצרת. הבדיקה מכסה רק את היתרה. מודל שהתוכנית שלכם לא מאפשרת, או מגבלה יומית, עדיין נדחים ברכיב עצמו כשההרצה מגיעה אליו.
הרצת תהליך עם ערכי קלט חדשים
הנתיב POST /v1/api/run מקבל אובייקט inputs שמחליף את הערכים של רכיבי הקלט בהרצה האחת הזו. האימות בנתיב הזה נעשה עם אסימון API אישי. המפתחות של inputs הם מזהי רכיבים, או, לנוחותכם, תוויות ייחודיות של רכיבים. בתוך כל מפתח, ציינו את שדה הקלט של הרכיב, כגון text בפרומפט טקסט.
הדוגמה שלמטה מריצה תהליך שבו רכיב טקסט עם המזהה 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.
| פרמטר שאילתה | משמעות |
|---|---|
month | YYYY-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 עושה את אותו הדבר ופועל לפי אותם כללים. אפשר להעביר עבודה שיצרתם. בתוך ארגון, מנהל של סביבת עבודה יכול גם להעביר עבודה בין שתי סביבות עבודה שהוא מנהל. בפרויקט אישי, גם פרויקט המקור וגם פרויקט היעד חייבים להיות שלכם.
| סטטוס | קוד | משמעות |
|---|---|---|
| 400 | validation_error | התהליך כבר נמצא בפרויקט הזה. |
| 403 | not_permitted | אין לכם הרשאה להעביר את התהליך, או להעביר אותו לשם. |
| 404 | not_found | אין תהליך כזה, או שאין לכם פרויקט כזה. |
| 409 | move_blocked | העבודה נוצרה במסגרת מטלה. |
| 409 | workspace_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:read | GET /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:execute | POST /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.
דפים קשורים
הרצות
רכיבים
הטמעת מיני־אפליקציה
הרצת תהליכים
ה-API של Webhooks
עודכן לאחרונה