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

ארגונים וסביבות עבודה

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

זמין ב-Nodaro Cloud

client.organizations מנהל ארגונים, כלומר בתי ספר או צוותים, עם החברים, ההזמנות, יומן הביקורת ודוחות השימוש שלהם. המשאב client.workspaces מנהל את סביבות העבודה שבתוכם, כגון כיתה או פרויקט של צוות, עם החברים וקודי ההצטרפות שלהן. המתודות קוראות לנקודות הקצה שבדף ה-API סביבות עבודה וארגונים. המושגים מוסברים בדף סביבות עבודה.

ארגונים הם יכולת של Nodaro Cloud, שמופעלת בנפרד בכל מופע. במופע שבו הם לא מופעלים, כל מתודה בדף הזה זורקת NotFoundError.

השתייכות ופעולה

השתייכות לסביבת עבודה ופעולה בתוכה הן שני דברים שונים. שני המשאבים האלה מנהלים מי שייך לאן. כדי לפעול בסביבת עבודה, כך שהרשימות יציגו את מה שיש בה ועבודה חדשה תיכנס אליה, צרו לקוח עם client.withWorkspace(workspaceId) או העבירו את workspaceId לפונקציה createClient:

const classroom = client.withWorkspace(workspaceId)
await classroom.workflows.run(workflowId) // runs in the class
await client.workflows.run(workflowId)    // runs in your personal space

המתודה client.me() מחזירה את הארגונים ואת סביבות העבודה שאתם שייכים אליהם, ואת lastWorkspaceId.

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

מתודות

מתודהמה היא עושה
organizations.list()רשימת הארגונים שאתם שייכים אליהם
organizations.get(id)קריאת ארגון אחד
organizations.create(input)יצירת בית ספר או צוות
organizations.update(id, input)שינוי השם או ההגדרות של ארגון
organizations.delete(id)מחיקת ארגון
organizations.transferOwnership(id, userId)העברת הבעלות לחבר אחר
organizations.leave(id)עזיבת ארגון
organizations.listMembers(), updateMember(), removeMember()ניהול החברים
organizations.invite(orgId, input)הזמנת אנשים באימייל
organizations.listInvitations(), revokeInvitation(), resendInvitation()ניהול ההזמנות שנשלחו
organizations.previewInvitation(), acceptInvitation()הצגה וקבלה של הזמנה
organizations.audit(orgId, opts?)קריאת יומן הביקורת
organizations.usage(), usageRows(), usageCsv()קריאת השימוש בקרדיטים
workspaces.list()רשימת סביבות העבודה שאתם שייכים אליהן
workspaces.listForOrg(orgId, opts?)רשימת סביבות העבודה של ארגון
workspaces.get(id)קריאת סביבת עבודה אחת
workspaces.create(orgId, input)יצירת סביבת עבודה
workspaces.update(id, input)שינוי סביבת עבודה
workspaces.setArchived(id, archived)העברה של סביבת עבודה לארכיון או הוצאה שלה מהארכיון
workspaces.listMembers(), addMember(), updateMember(), removeMember()ניהול החברים בסביבת עבודה
workspaces.getJoinCode(), actOnJoinCode()ניהול קוד ההצטרפות
workspaces.join(code)הצטרפות לסביבת עבודה עם קוד
workspaces.usage(), usageRows(), usageCsv()קריאת השימוש של סביבת עבודה בקרדיטים

client.organizations

organizations.list()‎

מחזירה את רשימת הארגונים שאתם שייכים אליהם (GET /v1/orgs).

list(): Promise<{ data: OrganizationView[] }>
const { data: orgs } = await client.organizations.list()

organizations.get(id)‎

מחזירה ארגון אחד (GET /v1/orgs/:id).

get(id: string): Promise<{ data: OrganizationView }>

מאפיין

סוג

const { data: org } = await client.organizations.get(orgId)
console.log(org.status) // pending, active, suspended or deleted

organizations.create(input)‎

יוצרת ארגון, ואתם הבעלים שלו (POST /v1/orgs). ארגון חדש מתחיל בדרך כלל בסטטוס pending, ועובר ל-active אחרי ש-Nodaro מאשר אותו. כל עוד הוא ממתין לאישור, רק אתם יכולים לראות אותו ואי אפשר לשנות בו שום דבר, ולכן הודיעו למשתמש שהארגון ממתין לאישור.

create(input: { name: string; kind: "school" | "team"; slug?: string; acceptTerms?: boolean; settings?: OrgSettings }): Promise<{ data: OrganizationView }>

מאפיין

סוג

const { data: school } = await client.organizations.create({
  name: "Sunrise School",
  kind: "school",
  acceptTerms: true,
})

יצירה של בית ספר בלי acceptTerms: true נכשלת עם 400 terms_required.

organizations.update(id, input)‎

משנה את השם או את ההגדרות של ארגון (PATCH /v1/orgs/:id).

update(id: string, input: { name?: string; settings?: OrgSettings }): Promise<{ data: OrganizationView }>

מאפיין

סוג

await client.organizations.update(orgId, {
  settings: { default_workflow_visibility: "workspace", allowed_email_domains: ["school.example"] },
})

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

מפתחסוגמשמעות
admin_accessview או editמה מנהלים רשאים לעשות עם תהליך של חבר
default_workflow_visibilityprivate או workspaceהנראות של תהליך חדש
member_access_to_sharedview או editמה חברים רשאים לעשות עם תהליך ששותף לסביבת העבודה
members_can_create_projectsbooleanאם חברים רשאים ליצור פרויקטים בסביבת העבודה
member_caps_enabledbooleanאם חלות תקרות קרדיטים לכל חבר
personal_space_enabledbooleanאם לחברים נשאר מרחב אישי
workspace_admins_can_invitebooleanאם מנהלי סביבות עבודה רשאים להזמין אנשים חדשים
collaborators_can_invitebooleanאם שותף עם הרשאת עריכה רשאי להזמין שותפים נוספים
allowed_email_domainsרשימת מחרוזותלארגון בלבד: דומייני האימייל שמורשים להצטרף
vocabulary_overridesobjectלארגון בלבד: תוויות חדשות במקום המילים של הסוג, כגון { "workspace": "Cohort" }. הוסיפו "workspace_gender": "m" כשהמילה החדשה לסביבת עבודה היא בלשון זכר, כדי שמשפטים בעברית ובפורטוגזית (ברזיל) יתאימו את עצמם למין הדקדוקי שלה

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

organizations.delete(id)‎

מוחקת ארגון (DELETE /v1/orgs/:id). הארגון מוסתר מהחברים שהיו בו, אבל שום נתון לא נמחק לצמיתות. קודם העבירו לארכיון את כל סביבות העבודה שלו: אחרת הקריאה נכשלת עם 409 has_active_workspaces.

delete(id: string): Promise<{ data: { id: string; status: string } }>

מאפיין

סוג

await client.organizations.delete(orgId)

organizations.transferOwnership(id, userId)‎

הופכת חבר אחר לבעלים (POST /v1/orgs/:id/transfer-ownership). אתם הופכים למנהלים.

transferOwnership(id: string, userId: string): Promise<{ data: { orgId: string; ownerUserId: string } }>

מאפיין

סוג

await client.organizations.transferOwnership(orgId, newOwnerId)

organizations.leave(id)‎

מוציאה אתכם מארגון (POST /v1/orgs/:id/leave). הבעלים לא יכול לעזוב: העבירו קודם את הבעלות, אחרת הקריאה נכשלת עם 409 owner_cannot_leave.

leave(id: string): Promise<{ data: { orgId: string; left: boolean } }>

מאפיין

סוג

await client.organizations.leave(orgId)

חברי הארגון

המתודות האלה מחזירות את רשימת החברים בארגון, משנות חברים ומסירות אותם (/v1/orgs/:id/members). הסטטוס של חבר הוא active או suspended; חבר מושעה שומר על המקום שלו בארגון, אבל לא יכול לפעול. אי אפשר להשעות את הבעלים, להסיר אותו או להוריד את התפקיד שלו.

listMembers(orgId: string, opts?: { cursor?: string; limit?: number }): Promise<OrgPage<OrgMemberView>>
updateMember(orgId: string, userId: string, input: { role?: "admin" | "member"; status?: "active" | "suspended" }): Promise<{ data: OrgMemberView }>
removeMember(orgId: string, userId: string): Promise<{ data: { removed: boolean } }>

מאפיין

סוג

const { data: members, nextCursor } = await client.organizations.listMembers(orgId)
await client.organizations.updateMember(orgId, userId, { role: "admin" })

organizations.invite(orgId, input)‎

מזמינה אנשים באימייל (POST /v1/orgs/:id/invitations). המתודה מחזירה שורה אחת לכל כתובת.

invite(orgId: string, input: {
  emails: string[]
  orgRole?: "admin" | "member"
  workspaceId?: string
  workspaceRole?: "admin" | "member"
}): Promise<{ data: InvitationDelivery[] }>

מאפיין

סוג

const { data: rows } = await client.organizations.invite(orgId, {
  emails: ["teacher@school.example"],
  workspaceId,
  workspaceRole: "admin",
})
for (const row of rows) {
  if (row.status !== "sent") showInviteLink(row.email, row.link) // not emailed: share the link yourself
}

הציגו את הקישור. בשורה שה-status שלה שונה מ-sent יש במקום זאת link: בהתקנה אין שירות אימייל, או ששליחת האימייל נכשלה. ההזמנה קיימת בכל מקרה, ובלי הקישור אף אחד לא יכול להגיע אליה. תוקף ההזמנה פג אחרי 14 ימים. כשהארגון מגיע למגבלת ההזמנות היומית שלו, הקריאה נכשלת עם RateLimitedError.

ניהול הזמנות

המתודות האלה מחזירות את רשימת ההזמנות, מבטלות הזמנות ושולחות אותן שוב.

listInvitations(orgId: string, opts?: { status?: "open" | "accepted" | "revoked" | "expired"; workspaceId?: string; cursor?: string; limit?: number }): Promise<OrgPage<InvitationView>>
revokeInvitation(id: string): Promise<{ data: { id: string; revoked: boolean } }>
resendInvitation(id: string): Promise<{ data: InvitationDelivery & { id: string } }>

מאפיין

סוג

const { data: open } = await client.organizations.listInvitations(orgId, { status: "open" })
await client.organizations.resendInvitation(open[0].id)

תצוגה מקדימה וקבלה של הזמנה

המתודה previewInvitation() היא ציבורית: היא עובדת גם כשהמוזמן עדיין לא מחובר, ומחזירה את כתובת האימייל כשחלק ממנה מוסתר. המתודה acceptInvitation() דורשת שמי שקורא לה יהיה מחובר, עם אימייל שתואם להזמנה.

previewInvitation(token: string): Promise<{ data: InvitationPreview }>
acceptInvitation(token: string): Promise<{ data: { orgId: string; workspaceId: string | null } }>

מאפיין

סוג

const { data: preview } = await client.organizations.previewInvitation(token)
const { data: joined } = await signedInClient.organizations.acceptInvitation(token)

קבלת ההזמנה נכשלת עם 400 invitation_expired, invitation_revoked, invitation_accepted או email_mismatch, ועם ForbiddenError כשהארגון מקבל רק כתובות אימייל מהדומיינים שברשימה שלו.

organizations.audit(orgId, opts?)‎

מחזירה את יומן הביקורת של הארגון, מהחדש לישן (GET /v1/orgs/:id/audit). אפשר לקרוא את היומן גם כשהארגון מושעה.

audit(orgId: string, opts?: { cursor?: string; limit?: number }): Promise<OrgPage<OrgAuditEntry>>

מאפיין

סוג

const { data: entries } = await client.organizations.audit(orgId, { limit: 50 })
for (const e of entries) console.log(e.createdAt, e.action, e.actor?.displayName ?? "system")

בכל רשומה יש id, workspaceId, action, targetType, targetId, details, createdAt ו-actor, שהוא null בפעולות שהמערכת ביצעה. השדה action הוא רשימה פתוחה: הציגו את הפעולות שאתם מכירים, ואת המחרוזת הגולמית בשאר המקרים. קוד שמטפל רק ברשימה קבועה נשבר בפעולה החדשה הראשונה.

נתוני השימוש של הארגון

דוחות על השימוש בקרדיטים בטווח תאריכים, לבעלים ולמנהלי הארגון (GET /v1/orgs/:id/usage). המתודה usage() מחזירה דוח מקובץ, המתודה usageRows() מחזירה את ההרצות שמאחוריו, מהחדש לישן, עמוד אחד בכל פעם, והמתודה usageCsv() מחזירה את הדוח או את השורות כטקסט CSV.

usage(orgId: string, opts?: { from?: string; to?: string; tz?: string; groupBy?: "workspace" | "member" | "model" | "day"; workspaceId?: string; userId?: string }): Promise<{ data: UsageReport }>
usageRows(orgId: string, opts?: { from?: string; to?: string; tz?: string; workspaceId?: string; userId?: string; cursor?: string; limit?: number }): Promise<OrgPage<UsageLogEntry>>
usageCsv(orgId: string, opts?: { from?: string; to?: string; tz?: string; groupBy?: string; workspaceId?: string; userId?: string }): Promise<string>

מאפיין

סוג

const { data: report } = await client.organizations.usage(orgId, {
  from: "2026-09-01",
  to: "2026-09-30",
  tz: "Europe/Rome",
  groupBy: "workspace",
})
const csv = await client.organizations.usageCsv(orgId, { from: "2026-09-01", to: "2026-09-30" })

כל שורה מדווחת על שלושה נתוני קרדיטים. השדה credits הוא מה שההרצות עלו עד עכשיו: הסכום אחרי החיוב הסופי בהרצות שהסתיימו, והשריון בשאר ההרצות. השדות settledCredits ו-inFlightCredits מפצלים את הסכום הזה לשני חלקיו. הסיכומים מכסים את כל הטווח, גם כשקיבוץ מסוים הוא truncated.

  • השדה platformAbsorbedCredits הוא החריגה של הרצה שמחויבת לפי שימוש ועלתה יותר ממה שנשאר בתקציב של סביבת העבודה. את החריגה הזו הפלטפורמה סופגת.
  • השדה chargedToBudget שווה ל-settledCredits פחות platformAbsorbedCredits: הקרדיטים שנגבו בחיוב הסופי וירדו מהתקציב.
  • השדה appMarkupAbsorbedCredits מסכם את תוספות המחיר של אפליקציות מאושרות שהפלטפורמה ספגה, בתקופה שבה תוספת המחיר של אפליקציה עוד לא נגבתה רק עד גובה היתרה הפנויה בתקציב. הרצות חדשות כבר לא מוסיפות לו: היוצר מקבל רק את מה שהתקציב שילם. אין לו הרצה בדוח, ולכן הוא לא חלק מ-chargedToBudget. מכאן שהשדה chargedToBudget לבדו הוא לא הסכום שסביבת העבודה הוציאה.

ייצוא לקובץ CSV מוגבל ל-10 ייצואים בדקה לכל משתמש.

client.workspaces

workspaces.list()‎

מחזירה את רשימת סביבות העבודה שאתם שייכים אליהן, ואת ה-lastWorkspaceId שלכם (GET /v1/workspaces). המתודה מחזירה סיכומים: אותה רשימה שהמתודה client.me() מחזירה.

list(): Promise<{ data: WorkspaceSummary[]; lastWorkspaceId: string | null }>
const { data: workspaces, lastWorkspaceId } = await client.workspaces.list()

workspaces.listForOrg(orgId, opts?)‎

מחזירה את רשימת סביבות העבודה של ארגון אחד (GET /v1/orgs/:id/workspaces).

listForOrg(orgId: string, opts?: { includeArchived?: boolean }): Promise<{ data: WorkspaceView[] }>

מאפיין

סוג

const { data: classes } = await client.workspaces.listForOrg(orgId)

workspaces.get(id)‎

מחזירה סביבת עבודה אחת במלואה (GET /v1/workspaces/:id).

get(id: string): Promise<{ data: WorkspaceView }>

מאפיין

סוג

const { data: workspace } = await client.workspaces.get(workspaceId)

workspaces.create(orgId, input)‎

יוצרת סביבת עבודה בארגון (POST /v1/orgs/:id/workspaces). הארגון חייב להיות פעיל.

create(orgId: string, input: { name: string; slug?: string; description?: string; settings?: WorkspaceSettings }): Promise<{ data: WorkspaceView }>

מאפיין

סוג

const { data: classOne } = await client.workspaces.create(orgId, { name: "Class 1" })

workspaces.update(id, input)‎

משנה סביבת עבודה (PATCH /v1/workspaces/:id).

update(id: string, input: { name?: string; description?: string | null; settings?: WorkspaceSettings }): Promise<{ data: WorkspaceView }>

מאפיין

סוג

await client.workspaces.update(workspaceId, { settings: { members_can_create_projects: true } })

workspaces.setArchived(id, archived)‎

מעבירה סביבת עבודה לארכיון או מוציאה אותה מהארכיון (POST /v1/workspaces/:id/archive או /unarchive). אפשר לבטל העברה לארכיון, והיא לא מוחקת כלום: סביבת העבודה מפסיקה לקבל עבודה חדשה, ונשארת זמינה לקריאה במלואה. כתיבה לסביבת עבודה שבארכיון נכשלת עם ForbiddenError.

setArchived(id: string, archived: boolean): Promise<{ data: WorkspaceView }>

מאפיין

סוג

await client.workspaces.setArchived(workspaceId, true)

חברי סביבת העבודה

המתודות האלה מחזירות את רשימת החברים בסביבת עבודה, מוסיפות חברים, משנות אותם ומסירות אותם (/v1/workspaces/:id/members). אפשר להוסיף רק אדם שכבר שייך לארגון; כדי לצרף מישהו חדש, הזמינו אותו. הבעלים והמנהלים של הארגון הם מנהלים בכל סביבת עבודה, גם בלי שהם מופיעים ברשימה.

listMembers(id: string, opts?: { cursor?: string; limit?: number }): Promise<OrgPage<WorkspaceMemberView>>
addMember(id: string, input: { userId: string; role: "admin" | "member" }): Promise<{ data: WorkspaceMemberView }>
updateMember(id: string, userId: string, input: { role?: "admin" | "member"; status?: "active" | "suspended"; creditCap?: number | null }): Promise<{ data: WorkspaceMemberView }>
removeMember(id: string, userId: string): Promise<{ data: { removed: boolean } }>

מאפיין

סוג

await client.workspaces.addMember(workspaceId, { userId, role: "member" })
await client.workspaces.updateMember(workspaceId, userId, { creditCap: 500 })

הוספה של מי שהוא לא חבר פעיל בארגון נכשלת עם 400 not_org_member, והוספה של אותו אדם פעמיים נכשלת עם 409 already_a_member.

קודי הצטרפות

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

getJoinCode(id: string): Promise<{ data: JoinCodeView | null }>
actOnJoinCode(id: string, action: "rotate" | "enable" | "disable"): Promise<{ data: JoinCodeView }>

מאפיין

סוג

const { data: code } = await client.workspaces.actOnJoinCode(workspaceId, "enable")
console.log(code.code) // for example BCDFGHJK

המתודה getJoinCode() מחזירה null כשעוד לא נוצר קוד.

workspaces.join(code)‎

מצרפת אתכם לסביבת עבודה לפי קוד ההצטרפות שלה (POST /v1/workspaces/join). המתודה עובדת בלי קשר לסביבת העבודה שבה הלקוח שלכם פועל, ולכן בחירה שכבר לא תקפה אף פעם לא חוסמת אותה.

join(code: string): Promise<{ data: { orgId: string; workspaceId: string } }>

מאפיין

סוג

const { data: joined } = await client.workspaces.join("BCDFGHJK")

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

נתוני השימוש של סביבת העבודה

אותם דוחות קרדיטים כמו של הארגון, לסביבת עבודה אחת (GET /v1/workspaces/:id/usage). חבר רואה את ההרצות שלו; מנהל רואה את ההרצות של כולם, ויכול לסנן לפי userId.

usage(id: string, opts?: { from?: string; to?: string; tz?: string; groupBy?: "member" | "model" | "day"; userId?: string }): Promise<{ data: UsageReport }>
usageRows(id: string, opts?: { from?: string; to?: string; tz?: string; userId?: string; cursor?: string; limit?: number }): Promise<OrgPage<UsageLogEntry>>
usageCsv(id: string, opts?: { from?: string; to?: string; tz?: string; groupBy?: string; userId?: string }): Promise<string>

מאפיין

סוג

const { data: byModel } = await client.workspaces.usage(workspaceId, { groupBy: "model" })

שגיאות

השרת מחליט על כל הרשאה, ועונה בשגיאה. ב-SDK, שגיאת 403 הופכת ל-ForbiddenError, שגיאת 404 ל-NotFoundError ושגיאת 429 ל-RateLimitedError; הסיבה מופיעה ב-message שלהן. סטטוסים אחרים מגיעים כ-NodaroError, עם ה-code של השרת.

סטטוסקודמתי
400validation_errorשדה לא תקין, cursor פגום או דוח שימוש שהתאריך, אזור הזמן או הטווח שלו לא תקינים
400terms_requiredבית ספר נוצר בלי acceptTerms: true
400not_org_memberהאדם שנוסף לסביבת עבודה הוא לא חבר פעיל בארגון שלה
400token_workspace_mismatchאסימון ששויך לסביבת עבודה אחת נשלח עם סביבת עבודה אחרת
400join_code_invalidקוד ההצטרפות לא קיים, מושבת או שייך לסביבת עבודה שבארכיון
400invitation_expired, invitation_revoked, invitation_accepted, email_mismatchאי אפשר לקבל את ההזמנה
403התפקיד נמוך מדי, החבר מושעה, הארגון לא פעיל, סביבת העבודה בארכיון או שהדומיין של האימייל לא מורשה
404הארגון, סביבת העבודה, החבר או ההזמנה לא קיימים, או שאתם לא חברים בהם
409name_takenה-slug כבר בשימוש
409already_a_memberהאדם כבר נמצא בסביבת העבודה
409owner_cannot_leaveהבעלים ניסה לעזוב
409has_active_workspacesבארגון עדיין יש סביבות עבודה שלא הועברו לארכיון
429יותר מדי ארגונים חדשים, ניסיונות הצטרפות, ייצואים לקובץ CSV או הזמנות
503billing_unavailableדוחות השימוש עדיין לא זמינים במופע הזה
503audit_unavailableאי אפשר היה לרשום ביומן הביקורת ייצוא לקובץ CSV. נסו שוב.

שאלות נפוצות

מה ההבדל בין ארגון לסביבת עבודה?

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

איך מריצים תהליך בתוך סביבת עבודה?

צרו לקוח לסביבת העבודה הזו עם client.withWorkspace(workspaceId)‎, וקראו דרכו למתודה run. הלקוח המקורי ממשיך לעבוד במרחב האישי שלכם.

למה הארגון החדש שלי ממתין לאישור?

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

מה עושים כשהזמנה חוזרת עם קישור?

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

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

בדף הזה