@fusebase/fusebase-gate-sdk 2.5.1-sdk.3 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,7 +43,7 @@ class PortalsApi {
43
43
  }
44
44
  /**
45
45
  * Add a published app as a portal page (embed)
46
- * Creates a new sidebar page in the portal that embeds a published Fusebase app (a flexible block with an app-feature brick). Pass productId (the product that owns the app) and appId (the app to embed) — typically the app you just built and published via the CLI. For a managed product (Customizer "Managed Products") also pass productType='managed' and productOrgId from findPublishedApps. The app's URL is resolved by the portal at render time from these ids; nothing is hard-coded. Pass parentId to nest the page under an existing folder. The page is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Returns the page/menu-item/block ids, the page url, and the draft branch/seqs. Requires portals.write access.
46
+ * Creates a new sidebar page in the portal that embeds a published Fusebase app (a flexible block with an app-feature brick). Pass productId (the product that owns the app) and appId (the app to embed) — typically the app you just built and published via the CLI. For a managed product (Customizer "Managed Products") also pass productType='managed' and productOrgId from findPublishedApps. The app's URL is resolved by the portal at render time from these ids; nothing is hard-coded. Pass parentId to nest the page under an existing folder, or positionType ('sidebar' default, 'top', 'footer') to place a root page in a specific menu bar. The page is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Returns the page/menu-item/block ids, the page url, and the draft branch/seqs. Requires portals.write access.
47
47
  */
48
48
  async addPortalAppPage(params) {
49
49
  return this.client.request({
@@ -72,17 +72,17 @@ class PortalsApi {
72
72
  });
73
73
  }
74
74
  /**
75
- * Add a block of any palette type to a portal page
76
- * Stages a single block of any supported type onto an existing portal page — the universal building block behind the customizer's 'Add new block' palette (no new page or sidebar item is created). Pass pageId (the target page node id from listPortalContent) and type. Supported types: note, content, docs, help, request, meetings, links, files-dashboard, tasks-dashboard, chats-dashboard, files-recent, flexible. Type-specific fields: note/content require noteId; flexible requires template (e.g. {type:'text'|'image'|'title'|'dashboard'|'app-feature'|...}) and may carry bricks; the link cards (docs/help/request/meetings/links) and others take their fields via the free-form `properties` object (e.g. image/link). It does NOT accept type='projection' — use addPortalLinkedBlock for a Linked block. This op does NOT accept type='embed', a flexible block with template.type='timeline' or a timeline brick (use addPortalTimelineBlock), a flexible block with template.type='dashboard' or a dashboard brick (use addPortalDatabaseBlock) or type='chat' — use addPortalEmbedBlock for Embed blocks and addPortalChatBlock for Chat blocks. It also does NOT accept type='files-bucket': use addPortalFileUploaderBlock for File uploader blocks. It does NOT accept a flexible ai-agent template or an ai-agent brick: use addPortalAiAgentBlock, which binds the agent to the caller. It does NOT accept a flexible `form` template or a `form` brick either: use addPortalFormBlock, which owns the canonical Form block and its fields. It does NOT accept type='info': use addPortalInfoBlock, which owns the canonical Info block, its icon catalog and its destination resolution. It does NOT accept type='task-list' or a note/content block with properties.templateKey='task-list': use addPortalTaskListBlock, which creates the note and its task list. Use addPortalNoteBlock for the common note case or addPortalAppPage for an app on its own page. Note: a `content` block renames the page to its title, so leave title empty for content blocks. The block is staged in the portal's customizer draft (not published immediately); the owner reviews and publishes it. Returns the block id and the draft branch/seqs. Requires portals.write access.
75
+ * Add a BPMN Diagram block to a portal page
76
+ * Stages one Customizer-compatible BPMN Diagram block on an EXISTING portal page — the programmatic equivalent of the customizer's Experimental "BPMN Diagram" tile. It creates exactly one flexible block with a single BPMN diagram brick; no page, sidebar item or menu icon change comes with it. The diagram is created EMPTY, exactly as the Customizer creates it: the process itself is drawn or imported from a `.bpmn` file in Portal Customizer. BPMN XML, `.bpmn` file uploads, task ids, persisted data/details and links for BPMN Task elements are rejected. This is not a Mermaid diagram, a generic flowchart, a Timeline or an image. The body may be empty, which reproduces the Customizer default: the title "BPMN Diagram", a 500px canvas, a blank backdrop with the title shown, width 6 and automatic height. `title` is the block title (plain text, only the `{{ClientName}}` and `{{ClientLastName}}` variables). `content.diagramHeight` is the BPMN canvas height in pixels (integer 150-5000, default 500) and is distinct from the block Layout height. `appearance` sets Customizer Backdrop `none`, `blank` or `custom`; a custom backdrop takes a background, padding (default `s`) and `showTitle` (default true). `layout` sets Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
77
77
  */
78
- async addPortalBlock(params) {
78
+ async addPortalBpmnDiagramBlock(params) {
79
79
  return this.client.request({
80
80
  method: "POST",
81
- path: "/:orgId/portals/:portalId/blocks",
81
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/bpmn-diagram",
82
82
  pathParams: params.path,
83
83
  headers: params.headers,
84
84
  body: params.body,
85
- opId: "addPortalBlock",
85
+ opId: "addPortalBpmnDiagramBlock",
86
86
  expectedContentType: "application/json",
87
87
  });
88
88
  }
@@ -146,6 +146,21 @@ class PortalsApi {
146
146
  expectedContentType: "application/json",
147
147
  });
148
148
  }
149
+ /**
150
+ * Add a Chat dashboard navigation item
151
+ * Adds a root navigation item pointing at the portal's system Chat dashboard page (`/chats-dashboard`), staged in the customizer draft. The page and its canonical `chats-dashboard` block are created with the portal, so this operation never creates them: if the portal has no such page the request returns 409 and stages nothing. This is the Customizer's Dashboards > Chat dashboard action, not an ordinary block — the item is always a ROOT item, so the operation takes no `pageId` and no `parentId`. Use addPortalChatBlock instead for a channel or direct-message widget on an existing page. Duplicates are allowed, as in the Customizer: any bar may carry several items, and every one of them points at the same dashboard. The body may be empty, which uses the default title "Chat Dashboard"; `title` is plain text of at most 100 characters and names the navigation item only — the page title, icon and route are managed by the service. `positionType` ('sidebar' default, 'top' or 'footer') picks the root menu bar. Requires portals.write access.
152
+ */
153
+ async addPortalChatsDashboardMenuItem(params) {
154
+ return this.client.request({
155
+ method: "POST",
156
+ path: "/:orgId/portals/:portalId/chats-dashboard",
157
+ pathParams: params.path,
158
+ headers: params.headers,
159
+ body: params.body,
160
+ opId: "addPortalChatsDashboardMenuItem",
161
+ expectedContentType: "application/json",
162
+ });
163
+ }
149
164
  /**
150
165
  * Add a Countdown block to a portal page
151
166
  * Stages one Customizer-compatible Countdown on an EXISTING portal page — the programmatic equivalent of the customizer's Content display "Countdown" tile. It creates exactly one flexible block with a single Countdown item that ticks down days, hours, minutes and seconds to a future moment; no page, sidebar item or external entity is created. The body may be empty, which reproduces the Customizer default: the title "Countdown" and a target 30 days after creation. `content.targetAt` is an absolute RFC 3339 date-time with `Z` or an explicit UTC offset — epoch seconds/milliseconds, a timezone-less local date and a duration are rejected, as are a raw timestamp, brick, renderer style, the item's internal title and its fixed days/hours/min/sec labels. The target must not be in the past or more than 99 days after creation. `title` is the block title (plain text, only the `{{ClientName}}` and `{{ClientLastName}}` variables). `appearance` sets Customizer Backdrop `none`, `blank` or `custom`; omitting it keeps the canonical blank backdrop with the title shown, and a custom backdrop takes a background, padding (default `s`) and `showTitle` (default true). `layout` sets Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -191,6 +206,21 @@ class PortalsApi {
191
206
  expectedContentType: "application/json",
192
207
  });
193
208
  }
209
+ /**
210
+ * Add a Dynamic Table block to a portal page
211
+ * Stages one Customizer-compatible Dynamic Table block on an EXISTING portal page — the programmatic equivalent of the customizer's Dynamic "Table" tile. It creates exactly one flexible block with a single integration brick; no page, sidebar item or OAuth connection is created. This is NOT addPortalDatabaseBlock: Database shows a Fusebase Database table/view, while Dynamic Table reads records from a HubSpot, Asana or monday.com connection. The block is created UNCONFIGURED, exactly as the Customizer creates it before a Data source is picked: the response carries `configured: false` and the Data source, table fields, filters, sorting and pagination are still chosen in Portal Customizer. `tokenId`, provider source ids, mappings, filters, order, pagination, template and bricks are rejected. The body may be empty, which reproduces the Customizer default: the title "Dynamic Table", a blank backdrop with the title shown, width 6 and automatic height. `title` is the block title (plain text, only the `{{ClientName}}` and `{{ClientLastName}}` variables). `appearance` sets Customizer Backdrop `none`, `blank` or `custom`; a custom backdrop takes a background, padding (default `s`) and `showTitle` (default true). `layout` sets Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px). The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
212
+ */
213
+ async addPortalDynamicTableBlock(params) {
214
+ return this.client.request({
215
+ method: "POST",
216
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/dynamic-table",
217
+ pathParams: params.path,
218
+ headers: params.headers,
219
+ body: params.body,
220
+ opId: "addPortalDynamicTableBlock",
221
+ expectedContentType: "application/json",
222
+ });
223
+ }
194
224
  /**
195
225
  * Add an Embeds & Integrations block to a portal page
196
226
  * Stages one Customizer-compatible Embed block on an EXISTING portal page — the programmatic equivalent of the customizer's "Embeds & Integrations" action. No new page and no sidebar menu item is created. embedType is one of the 11 chooser variants (custom, youtube, google-drive, ms-doc, calendly, hubspot, airtable, loom, data-studio, figma, miro). For `custom` pass `content` (URL or embed code) and NOT `url`; for every named variant pass `url` and NOT `content` — the service builds the canonical iframe. hubspot here is an iframe Embed block, not a Flexible Block integration brick. For a published page resolve pageId from listPortalContent; for a page created earlier in the active draft use the pageId that operation returned. The block is staged in the portal's customizer draft (not published immediately). Returns the block id and the draft branch/seqs. Requires portals.write access.
@@ -206,6 +236,21 @@ class PortalsApi {
206
236
  expectedContentType: "application/json",
207
237
  });
208
238
  }
239
+ /**
240
+ * Add a Files dashboard navigation item
241
+ * Adds a root navigation item pointing at the portal's system Files dashboard, staged in the customizer draft. If the portal has no `/files-dashboard` page yet, the page and its canonical `files-dashboard` block are created in the same batch; if it already has one, only the item is added, so several bars can link to the same dashboard. The dashboard renders the portal's full File Manager, so it cannot be placed on a page of your choice — the operation takes no `pageId` and no `parentId`. Use addPortalRecentFilesBlock or addPortalFileUploaderBlock instead for a file list or an upload area on an existing page. Pass `positionType` to choose the bar: 'sidebar' (default), 'top' (topbar) or 'footer'. The body may be empty, which uses the default title "Files"; `title` is plain text of at most 100 characters and names the navigation item (and the dashboard block when it is created) — the page title, route and icon are managed by the service. Requires portals.write access.
242
+ */
243
+ async addPortalFilesDashboardMenuItem(params) {
244
+ return this.client.request({
245
+ method: "POST",
246
+ path: "/:orgId/portals/:portalId/files-dashboard",
247
+ pathParams: params.path,
248
+ headers: params.headers,
249
+ body: params.body,
250
+ opId: "addPortalFilesDashboardMenuItem",
251
+ expectedContentType: "application/json",
252
+ });
253
+ }
209
254
  /**
210
255
  * Add a File uploader block to a portal page
211
256
  * Stages one Customizer-compatible File uploader on an EXISTING portal page — the programmatic equivalent of the customizer's File management "File uploader" tile. It creates an EMPTY upload area (internally a `files-bucket` block) that non-visitor portal users can upload files to and manage; no page, sidebar item, bucket or file is created and nothing is uploaded. The body may be empty, which reproduces the Customizer default: the title "File uploader", no description and both file columns hidden. `title` is plain text and `description` is a plain-text hint of at most 50 characters. `showAuthor` and `showUploadDate` add the matching file-list columns; neither changes who may upload — that stays a function of the viewer's portal role. `layout` sets Width (3, 4 or 6, default 3) and Height (Auto by default, a manual value is at least 50px). The screen has no Appearance section, so `appearance`, `rowspan`, upload permissions, bucket/file ids and query/sort/limit are not accepted. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -296,6 +341,21 @@ class PortalsApi {
296
341
  expectedContentType: "application/json",
297
342
  });
298
343
  }
344
+ /**
345
+ * Add an existing Internal Space page to a portal
346
+ * Adds an EXISTING Internal Space page (Fusebase note) to the portal as its own page — the 'Internal Space Content' tile of the customizer. Identify the note with either noteId (its global id) or noteUrl (the browser URL, e.g. https://acme.nimbusweb.me/space/<workspaceId>/page/<noteId>); exactly one is required. The note must already exist in the portal's workspace — use createPortalPageWithNote to create a NEW note instead, or addPortalNoteBlock to embed a note as one more block on an existing page. The page (page node + note menu item + content block) is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it — the note is shared into the portal at publish time. `title` names the page and its menu item; the block header always shows the note's own title, because publishing backfills it from the note's share. Everything defaults to the note's title when `title` is omitted. Pass parentId to nest the page under an existing folder, or positionType ('sidebar' default, 'top', 'footer') to place a root page in a specific menu bar. Returns the note/page/menu-item/block ids, the page url, and the draft branch/seqs. Requires portals.write access.
347
+ */
348
+ async addPortalInternalSpacePage(params) {
349
+ return this.client.request({
350
+ method: "POST",
351
+ path: "/:orgId/portals/:portalId/pages/internal-space",
352
+ pathParams: params.path,
353
+ headers: params.headers,
354
+ body: params.body,
355
+ opId: "addPortalInternalSpacePage",
356
+ expectedContentType: "application/json",
357
+ });
358
+ }
299
359
  /**
300
360
  * Add a Kanban board as a block to a portal page
301
361
  * Creates a new Fusebase note, shares it into the portal, initialises a Kanban board inside it and adds the note as a block to an existing portal page — the programmatic equivalent of the customizer's Project management "Kanban" tile. No new page and no sidebar menu item is created. For a published page resolve pageId from listPortalContent; for a page created earlier in the active draft use the pageId that operation returned. Optional body: title (block, note and board title, non-empty and at most 100 characters, default "Kanban") and columns (1-10 column titles in order, each at most 100 characters, default "To do", "In progress", "Done"). The board starts empty — tasks are added by portal users, not by this operation. Use addPortalBlankNoteBlock when an empty note is wanted instead. The block is appended after the last block of the page body and is staged in the portal's customizer draft (not published immediately). Returns the note/board/block ids and the draft branch/seqs. Requires portals.write access.
@@ -341,6 +401,21 @@ class PortalsApi {
341
401
  expectedContentType: "application/json",
342
402
  });
343
403
  }
404
+ /**
405
+ * Add a Recent files block to a portal page
406
+ * Stages one Customizer-compatible Recent files block on an EXISTING portal page — the programmatic equivalent of the customizer's File management "Recent files" tile. The block lists the five most recently created files of the whole portal or of exactly one portal page; no page, sidebar item, file or bucket is created and no file access is widened (the File Manager applies the viewer's own access at render time). The body may be empty, which reproduces the Customizer default: the title "Recent files" scoped to the entire portal. `title` is at most 100 characters. `source` is either `{type:'entirePortal'}` or `{type:'portalPage', pageId}` with an exact page id of THIS portal — a page title, path, URL, file or bucket id is rejected. `layout` sets Width (3-6, default 3) and Height (Auto by default, a manual value is at least 50px). Sort order (createdAt descending), the item count of 5, the offset, raw query/link data, Appearance and Rows are fixed and not configurable. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
407
+ */
408
+ async addPortalRecentFilesBlock(params) {
409
+ return this.client.request({
410
+ method: "POST",
411
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/recent-files",
412
+ pathParams: params.path,
413
+ headers: params.headers,
414
+ body: params.body,
415
+ opId: "addPortalRecentFilesBlock",
416
+ expectedContentType: "application/json",
417
+ });
418
+ }
344
419
  /**
345
420
  * Add a task list as a block to a portal page
346
421
  * Creates a new Fusebase note, shares it into the portal, initialises a task list inside it and adds the note as a block to an existing portal page — the programmatic equivalent of the customizer's Project management "Task list" tile. No new page and no sidebar menu item is created. For a published page resolve pageId from listPortalContent; for a page created earlier in the active draft use the pageId that operation returned. Optional body: title (block and task list title, at most 100 characters, default "Task list") and layout (colspan 3-6, default 6; height in pixels or null for Auto, default null). The list starts empty — tasks are added by portal users, not by this operation, and an existing task list cannot be attached. Use addPortalBlankNoteBlock when an empty note is wanted instead. The block is appended after the last block of the page body and is staged in the portal's customizer draft (not published immediately). Returns the note/task list/block ids and the draft branch/seqs. Requires portals.write access.
@@ -356,6 +431,21 @@ class PortalsApi {
356
431
  expectedContentType: "application/json",
357
432
  });
358
433
  }
434
+ /**
435
+ * Add a Tasks dashboard navigation item
436
+ * Adds a root navigation item pointing at the portal's system Tasks dashboard, staged in the customizer draft. If the portal has no `/tasks-dashboard` page yet, the page and its canonical `tasks-dashboard` block are created in the same batch; if it already has one, only the item is added, so several bars can link to the same dashboard. The dashboard shows each viewer the portal tasks they are allowed to see, so it cannot be placed on a page of your choice — the operation takes no `pageId` and no `parentId`. Use addPortalTaskListBlock or addPortalKanbanBlock instead for a task list or board on an existing page. Pass `positionType` to choose the bar: 'sidebar' (default), 'top' (topbar) or 'footer'. The body may be empty, which uses the default title "Task Dashboard"; `title` is plain text of at most 100 characters and names the navigation item (and the dashboard block when it is created) — the page title, route and icon are managed by the service. Requires portals.write access.
437
+ */
438
+ async addPortalTasksDashboardMenuItem(params) {
439
+ return this.client.request({
440
+ method: "POST",
441
+ path: "/:orgId/portals/:portalId/tasks-dashboard",
442
+ pathParams: params.path,
443
+ headers: params.headers,
444
+ body: params.body,
445
+ opId: "addPortalTasksDashboardMenuItem",
446
+ expectedContentType: "application/json",
447
+ });
448
+ }
359
449
  /**
360
450
  * Add a Text & Media Simple text block to a portal page
361
451
  * Stages one Customizer-compatible Simple text block on an existing portal page — the programmatic equivalent of the customizer's Text & Media "Simple text" tile. `content` carries the text settings (plain text, one palette colour token such as `cyan-700` — never HEX or CSS —, size `s`/`m`/`l`/`xl`, a unique set of `bold`, `italic`, `underline`, `lineThrough` styles and alignment). `appearance` is the Customizer Appearance section; a `custom` backdrop takes a colour, gradient or one of the five preset background images (`azure`, `mira`, `solis`, `serenity`, `glow`) — an image URL, asset id or upload is rejected. HTML, Markdown, CSS, Tailwind classes, a wrapper title and raw bricks are not accepted. Defaults: text "Your journey starts here! Add your unique message to engage your audience.", size `m`, no styles, left alignment and a blank backdrop. It creates exactly one flexible block on an EXISTING page; no page, sidebar item or media asset is created. `layout` sets Customizer Width (2-6, default 6) and Height (Auto by default, a manual value is at least 50px); `rowspan`, row placement and responsive values are not part of this contract. The block is staged in the portal's customizer draft (not published immediately). Requires portals.write access.
@@ -418,7 +508,7 @@ class PortalsApi {
418
508
  }
419
509
  /**
420
510
  * Create a root folder in a portal
421
- * Creates a new empty root folder (a portalSection) in the portal's sidebar navigation. The folder is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending folder, and publishes it. Returns the created folder/page ids, its url, and the draft branch/seqs. Requires portals.write access.
511
+ * Creates a new empty root folder (a portalSection) in a portal menu bar. Pass positionType to choose the bar: 'sidebar' (default), 'top' (topbar), or 'footer'. The folder is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending folder, and publishes it. Returns the created folder/page ids, its url, and the draft branch/seqs. Requires portals.write access.
422
512
  */
423
513
  async createPortalFolder(params) {
424
514
  return this.client.request({
@@ -431,9 +521,24 @@ class PortalsApi {
431
521
  expectedContentType: "application/json",
432
522
  });
433
523
  }
524
+ /**
525
+ * Create an external link menu item in a portal
526
+ * Creates a menu item that opens an external URL (no page is created). Use it to build a topbar or footer nav of external links (e.g. Chat / Case Studies / Contact). Pass name and url; positionType chooses the bar: 'sidebar' (default), 'top' (topbar), or 'footer'. Optionally pass icon, openInNewTab (default true), and parentId to nest under a folder. The link is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending link, and publishes it. Returns the created menu-item id and the draft branch/seqs. Requires portals.write access.
527
+ */
528
+ async createPortalLink(params) {
529
+ return this.client.request({
530
+ method: "POST",
531
+ path: "/:orgId/portals/:portalId/links",
532
+ pathParams: params.path,
533
+ headers: params.headers,
534
+ body: params.body,
535
+ opId: "createPortalLink",
536
+ expectedContentType: "application/json",
537
+ });
538
+ }
434
539
  /**
435
540
  * Create an empty portal page
436
- * Creates a new EMPTY sidebar page in the portal — a page node plus its sidebar menu item, with no Fusebase note and no block. The page is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Pass parentId to nest the page under an existing published or active-draft folder. The returned pageId can immediately be passed to semantic block operations to add content before publishing. Use createPortalPageWithNote instead when a page backed by a new Fusebase note is wanted. Returns the page/menu-item ids, the page url, and the draft branch/seqs. Requires portals.write access.
541
+ * Creates a new EMPTY page in the portal — a page node plus its menu item, with no Fusebase note and no block. The page is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Pass positionType ('sidebar' default, 'top' or 'footer') to choose the menu bar. Pass parentId to nest the page under an existing published or active-draft folder. The returned pageId can immediately be passed to semantic block operations to add content before publishing. Use createPortalPageWithNote instead when a page backed by a new Fusebase note is wanted. Returns the page/menu-item ids, the page url, and the draft branch/seqs. Requires portals.write access.
437
542
  */
438
543
  async createPortalPage(params) {
439
544
  return this.client.request({
@@ -448,7 +553,7 @@ class PortalsApi {
448
553
  }
449
554
  /**
450
555
  * Create a portal page backed by a Fusebase note
451
- * Creates a new sidebar page in the portal backed by a freshly created Fusebase note. The note is created in the portal's workspace and shared into the portal; optional initial text or html can be appended to it. The page (page node + note menu item + note content block) is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Pass parentId to nest the page under an existing folder. Returns the note/page/menu-item ids, the page url, and the draft branch/seqs. Requires portals.write access.
556
+ * Creates a new sidebar page in the portal backed by a freshly created Fusebase note. The note is created in the portal's workspace and shared into the portal; optional initial text or html can be appended to it. The page (page node + note menu item + note content block) is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending page, and publishes it. Pass parentId to nest the page under an existing folder, or positionType ('sidebar' default, 'top', 'footer') to place a root page in a specific menu bar. Returns the note/page/menu-item ids, the page url, and the draft branch/seqs. Requires portals.write access.
452
557
  */
453
558
  async createPortalPageWithNote(params) {
454
559
  return this.client.request({
@@ -461,6 +566,34 @@ class PortalsApi {
461
566
  expectedContentType: "application/json",
462
567
  });
463
568
  }
569
+ /**
570
+ * Remove a block from a portal page
571
+ * Removes ONE existing removable block from a portal page and STAGES the deletion in the active customizer draft; the live portal only changes when the draft is published. Takes no body. It deletes the portal block ONLY — the backing Fusebase note, Kanban board, task list, app, agent, database/dashboard source and files are kept. Resolve the exact pageId and blockId with listPortalPageBlocks first and let the user choose when several blocks may match. Requires portals.write access.
572
+ */
573
+ async deletePortalBlock(params) {
574
+ return this.client.request({
575
+ method: "DELETE",
576
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId",
577
+ pathParams: params.path,
578
+ headers: params.headers,
579
+ opId: "deletePortalBlock",
580
+ expectedContentType: "application/json",
581
+ });
582
+ }
583
+ /**
584
+ * Delete a portal menu item
585
+ * Deletes a portal menu item (folder, page, or link) identified by itemId. Deleting a folder removes its whole subtree, including items created in the same draft. The portal's home item cannot be deleted. The item may be a published one (from listPortalContent) or one that exists only in the active draft, by the exact id its create operation returned. The deletion is staged in the portal's customizer draft (not published immediately): the owner reviews and publishes it, and a concurrent customizer edit returns 409 — retry the request. Requires portals.write access.
586
+ */
587
+ async deletePortalItem(params) {
588
+ return this.client.request({
589
+ method: "DELETE",
590
+ path: "/:orgId/portals/:portalId/items/:itemId",
591
+ pathParams: params.path,
592
+ headers: params.headers,
593
+ opId: "deletePortalItem",
594
+ expectedContentType: "application/json",
595
+ });
596
+ }
464
597
  /**
465
598
  * Duplicate an existing portal
466
599
  * Creates a new portal as a full copy of an existing portal: settings, theme, menu structure, pages, and content blocks are all copied. Returns portal details. Status is 'ready' immediately for P_SUB domains; 'pending' for custom/CNAME domains or if content copy is still in progress. Requires org.write access.
@@ -505,6 +638,20 @@ class PortalsApi {
505
638
  expectedContentType: "application/json",
506
639
  });
507
640
  }
641
+ /**
642
+ * Read one portal block's current settings
643
+ * Read-only step between listPortalPageBlocks and a typed updatePortal*Block operation: shows what the block is set to TODAY so the change can be confirmed with the user before it is staged. Reads the published portal AND its active customizer draft. Returns the block's semantic `kind` — the vocabulary the typed updates use, which neither `type` nor `templateType` gives on its own — plus `title`, `place`, `layout`, `editOperation` and the kind-specific `settings`. `settings` and `editOperation` are null for a kind whose typed update operation does not exist yet; call listPortalPageBlocks first to resolve the blockId. Internal customizer state (bricks, wrappers, share keys, draft events) is never returned. Requires portals.write access.
644
+ */
645
+ async getPortalBlock(params) {
646
+ return this.client.request({
647
+ method: "GET",
648
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId",
649
+ pathParams: params.path,
650
+ headers: params.headers,
651
+ opId: "getPortalBlock",
652
+ expectedContentType: "application/json",
653
+ });
654
+ }
508
655
  /**
509
656
  * Count matching blocks on a portal page (published + draft)
510
657
  * Universal preflight: how many active blocks of a given type a page already carries, counted over the published portal AND its active customizer draft — so a block staged earlier in this session is included. `type` is a canonical portal block type; `templateType` is allowed only with type='flexible' and narrows by the flexible template (e.g. type='flexible' + templateType='ai-agent' for AI Agent blocks). Returns only the count — never blocks, bricks, ids or draft events. Requires portals.write access.
@@ -637,6 +784,20 @@ class PortalsApi {
637
784
  expectedContentType: "application/json",
638
785
  });
639
786
  }
787
+ /**
788
+ * List the blocks of a portal page
789
+ * Read-only discovery step before movePortalBlock, deletePortalBlock and the typed block updates. Lists EVERY block of ONE page over the published portal AND its active customizer draft, in display order, as `blocks` of `blockId`, `type`, `templateType`, `title`, `editOperation`, `place` and `draftOnly`. The order is the page order — area (`place`) first, then position inside it — and is what a move anchor refers to; a move anchor must share the block's `place`. `editOperation` names the typed update operation for the block, or is null when its kind has none yet. Unlike listPortalLinkableBlocks this includes Linked blocks, because they can be moved and deleted. The response carries identity only: never bricks, wrappers, content, data or draft events. Requires portals.write access.
790
+ */
791
+ async listPortalPageBlocks(params) {
792
+ return this.client.request({
793
+ method: "GET",
794
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks",
795
+ pathParams: params.path,
796
+ headers: params.headers,
797
+ opId: "listPortalPageBlocks",
798
+ expectedContentType: "application/json",
799
+ });
800
+ }
640
801
  /**
641
802
  * List organization portals
642
803
  * Returns portals visible for the caller in the organization. Requires portals.read and org access.
@@ -651,6 +812,21 @@ class PortalsApi {
651
812
  expectedContentType: "application/json",
652
813
  });
653
814
  }
815
+ /**
816
+ * Move a block within its portal page
817
+ * Reorders ONE existing block on its own portal page and STAGES the change in the active customizer draft; nothing is published. Send exactly one position: `{position:"first"}`, `{position:"last"}`, `{beforeBlockId}` or `{afterBlockId}`. An anchor block must be on the same page, in the same area, and cannot be the block being moved. A raw index and the internal append sentinel 999 are rejected — the index is resolved server-side against the effective state, so a concurrent draft change cannot land the block in the wrong slot. Resolve ids with listPortalPageBlocks first. Moving to another page or changing the block's area is not supported. Requires portals.write access.
818
+ */
819
+ async movePortalBlock(params) {
820
+ return this.client.request({
821
+ method: "PATCH",
822
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/position",
823
+ pathParams: params.path,
824
+ headers: params.headers,
825
+ body: params.body,
826
+ opId: "movePortalBlock",
827
+ expectedContentType: "application/json",
828
+ });
829
+ }
654
830
  /**
655
831
  * Publish an entire portal draft after user confirmation
656
832
  * Publishes every staged change in the portal's customizer draft to the live portal, including changes the owner or another user staged manually. Never call this operation automatically after staging content or settings. Before every call, tell the user that the entire pending draft will go live, ask one clear yes/no question, and wait for explicit confirmation. Do not infer publish permission from a content-edit request or successful staging. Confirmation is single-use and applies only to the current draft and one attempt. Returns 400 if the draft is empty and 409 if the portal was published elsewhere since the draft was based; obtain new confirmation before retrying. Requires portals.write access.
@@ -709,6 +885,141 @@ class PortalsApi {
709
885
  expectedContentType: "application/json",
710
886
  });
711
887
  }
888
+ /**
889
+ * Update a portal AI Agent block
890
+ * Changes the exact agent used by one AI Agent block and synchronizes its title. Use listPortalAiAgents first.
891
+ */
892
+ async updatePortalAiAgentBlock(params) {
893
+ return this.client.request({
894
+ method: "PATCH",
895
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/ai-agent",
896
+ pathParams: params.path,
897
+ headers: params.headers,
898
+ body: params.body,
899
+ opId: "updatePortalAiAgentBlock",
900
+ expectedContentType: "application/json",
901
+ });
902
+ }
903
+ /**
904
+ * Update a portal App block
905
+ * Updates the title or complete published-app identity of one existing App block. Binding changes require productId, appId, productType and productOrgId together.
906
+ */
907
+ async updatePortalAppBlock(params) {
908
+ return this.client.request({
909
+ method: "PATCH",
910
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/app",
911
+ pathParams: params.path,
912
+ headers: params.headers,
913
+ body: params.body,
914
+ opId: "updatePortalAppBlock",
915
+ expectedContentType: "application/json",
916
+ });
917
+ }
918
+ /**
919
+ * Update a portal BPMN Diagram block
920
+ * Edits ONE existing BPMN Diagram block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one of `title`, `content.diagramHeight`, `appearance` or `layout` must be sent. `diagramHeight` is the BPMN canvas height inside the block, from 150 to 5000 pixels; `layout.height` is the separate outer block height. This operation cannot accept BPMN XML, import a `.bpmn` file, or edit process elements and links. Title is plain text and supports only {{ClientName}} and {{ClientLastName}}. Appearance is a complete variant. Layout width is 2 to 6 and manual height is at least 50; null restores automatic height. Call getPortalBlock first for current settings. Rejected with 400: an empty patch, invalid canvas/layout/appearance, unsupported variables, a block of another kind, and a patch the block already satisfies. Requires portals.write access.
921
+ */
922
+ async updatePortalBpmnDiagramBlock(params) {
923
+ return this.client.request({
924
+ method: "PATCH",
925
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/bpmn-diagram",
926
+ pathParams: params.path,
927
+ headers: params.headers,
928
+ body: params.body,
929
+ opId: "updatePortalBpmnDiagramBlock",
930
+ expectedContentType: "application/json",
931
+ });
932
+ }
933
+ /**
934
+ * Update a portal Card block
935
+ * Edits ONE existing Card block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. Editable: `view` (Card Type), `content` (image, heading, description, button and the shared destination), `appearance` and `layout` (`colspan` 2 to 6, `height` at least 50 or null for the automatic height). Each `content` item is a complete variant: a heading sent with only `size` keeps its stored text, styles and alignment, and `{ visible: false }` may carry nothing else — but re-showing an item with `{ visible: true }` keeps everything it had. `destination` is the Card's single link, shared with its Button; `null` removes it. Changing `view` repaints the text colours the way the Customizer does, unless an explicit `color` is sent with it. Call getPortalBlock first to see the current values — it reports no `appearance` for a Card still on its original wrapper, which is not a backdrop the update can ask for. Rejected with 400: an empty patch, text or styles next to a hidden item, a destination page outside this portal, a colour outside the Tailwind palette, background, padding or showTitle outside backdrop `custom`, a value outside the supported range, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
936
+ */
937
+ async updatePortalCardBlock(params) {
938
+ return this.client.request({
939
+ method: "PATCH",
940
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/card",
941
+ pathParams: params.path,
942
+ headers: params.headers,
943
+ body: params.body,
944
+ opId: "updatePortalCardBlock",
945
+ expectedContentType: "application/json",
946
+ });
947
+ }
948
+ /**
949
+ * Update a portal Card group block
950
+ * Updates title, description, the full desired list of 1 to 6 cards, appearance or layout. Each card accepts plain title text, one built-in image and a same-portal page, absolute HTTPS URL, email or null destination. Image URLs, uploads, raw links, bricks and item indexes are never accepted.
951
+ */
952
+ async updatePortalCardGroupBlock(params) {
953
+ return this.client.request({
954
+ method: "PATCH",
955
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/card-group",
956
+ pathParams: params.path,
957
+ headers: params.headers,
958
+ body: params.body,
959
+ opId: "updatePortalCardGroupBlock",
960
+ expectedContentType: "application/json",
961
+ });
962
+ }
963
+ /**
964
+ * Update a portal Carousel block
965
+ * Edits ONE existing Carousel block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: `layout` is a field-level patch, while `content.items`, when sent, is the FULL desired list of 1 to 6 slides in visual order. Each slide may contain `caption`, `description`, `button: { text }` or null, and `destination` or null. The slide surface and Button share one destination. Description supports only {{ClientName}} and {{ClientLastName}}; caption and Button text support no variables. Images remain the block's built-in images. Do not send media, autoplay, duration, controls, indicators, appearance or item ids. Layout width is 2 to 6 and manual height is at least 50; null restores automatic height. Call getPortalBlock first for the current full list. Rejected with 400: an empty patch, an invalid list or destination, unsupported variables, a block of another kind, and a patch the block already satisfies. Requires portals.write access.
966
+ */
967
+ async updatePortalCarouselBlock(params) {
968
+ return this.client.request({
969
+ method: "PATCH",
970
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/carousel",
971
+ pathParams: params.path,
972
+ headers: params.headers,
973
+ body: params.body,
974
+ opId: "updatePortalCarouselBlock",
975
+ expectedContentType: "application/json",
976
+ });
977
+ }
978
+ /**
979
+ * Update a portal Chat block
980
+ * Updates title, exact channel/DM target, channel membership restriction or layout of one Chat widget. Use listPortalChatChannels or listPortalChatUsers before changing its target.
981
+ */
982
+ async updatePortalChatBlock(params) {
983
+ return this.client.request({
984
+ method: "PATCH",
985
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/chat",
986
+ pathParams: params.path,
987
+ headers: params.headers,
988
+ body: params.body,
989
+ opId: "updatePortalChatBlock",
990
+ expectedContentType: "application/json",
991
+ });
992
+ }
993
+ /**
994
+ * Set who may open one portal page or folder
995
+ * Replaces or extends the client-facing access list of one published portal page or folder selected by its exact full path. mode='replace' removes the previous item ACL and leaves access to the supplied emails; mode='add' preserves existing access and adds the supplied emails. Missing portal members receive a targeted client/editor portal invitation without being granted access to other private items. Folder permissions cascade to all descendants. mode='add' on an item that is open to everyone is a successful no-op — the users already have access and the item is not made private. The change is applied immediately and must not be followed by publishPortalDraft. Requires portals.manage access.
996
+ */
997
+ async updatePortalContentPermissions(params) {
998
+ return this.client.request({
999
+ method: "POST",
1000
+ path: "/:orgId/portals/:portalId/content/permissions",
1001
+ pathParams: params.path,
1002
+ headers: params.headers,
1003
+ body: params.body,
1004
+ opId: "updatePortalContentPermissions",
1005
+ expectedContentType: "application/json",
1006
+ });
1007
+ }
1008
+ /**
1009
+ * Update a portal Countdown block
1010
+ * Edits ONE existing Countdown block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one of `title`, `content.targetAt`, `appearance` or `layout` must be sent. `targetAt` is an absolute RFC 3339 date-time with Z or an explicit UTC offset; it must not be in the past or more than 99 days from the update. Never send epoch time, a timezone-less date, duration or internal countdown items. Title is plain text and supports only {{ClientName}} and {{ClientLastName}}. Appearance is a complete variant. Layout width is 2 to 6 and manual height is at least 50; null restores automatic height. Call getPortalBlock first for the current settings. Rejected with 400: an empty patch, invalid target, unsupported variables, invalid appearance/layout, a block of another kind, and a patch the block already satisfies. Requires portals.write access.
1011
+ */
1012
+ async updatePortalCountdownBlock(params) {
1013
+ return this.client.request({
1014
+ method: "PATCH",
1015
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/countdown",
1016
+ pathParams: params.path,
1017
+ headers: params.headers,
1018
+ body: params.body,
1019
+ opId: "updatePortalCountdownBlock",
1020
+ expectedContentType: "application/json",
1021
+ });
1022
+ }
712
1023
  /**
713
1024
  * Update portal custom CSS/JS code
714
1025
  * Sets custom code for the portal: css (custom styles), headCode (HTML/JS at the start of <head>), and bodyCode (HTML/JS at the end of <body>). css is auto-scoped under the portal root container #main-scrolling-container so it cannot leak into the customizer UI; scope selectors accordingly and avoid body/html/:root. Only the provided fields change; omitted fields keep their current value, and an empty string clears a field. At least one field is required. Custom code only renders on portals served from a custom CNAME domain. The change is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending change, and publishes it. Returns the draft branch/seq. Requires portals.write access.
@@ -724,5 +1035,275 @@ class PortalsApi {
724
1035
  expectedContentType: "application/json",
725
1036
  });
726
1037
  }
1038
+ /**
1039
+ * Update a portal Custom widget block
1040
+ * Updates title, the full desired semantic brick list, appearance or layout of one existing Custom widget. Supported bricks are heading, text, built-in image, avatar, rating, link and button. Raw brick ids, indexes, image sources, classes and links are never accepted.
1041
+ */
1042
+ async updatePortalCustomWidgetBlock(params) {
1043
+ return this.client.request({
1044
+ method: "PATCH",
1045
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/custom-widget",
1046
+ pathParams: params.path,
1047
+ headers: params.headers,
1048
+ body: params.body,
1049
+ opId: "updatePortalCustomWidgetBlock",
1050
+ expectedContentType: "application/json",
1051
+ });
1052
+ }
1053
+ /**
1054
+ * Update a portal Database block
1055
+ * Edits ONE existing Database block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. Editable: `target`, `title`, `itemsPerPage` (10, 20, 50, 100, 200 or 500), `appearance` and `layout` (`colspan` 2 to 6, `height` at least 50 or null for the automatic height). `target` and `appearance` are NOT field-level patches: each is a complete variant when sent. Call listPortalDatabaseBlockSources for a new target and use the exact `databaseId`, `dashboardId` and `viewId` chain it returns; the whole chain is re-validated as the calling user. Call getPortalBlock first to see the current values — it reports no `databaseId`, because the block does not store one. Rejected with 400: an empty patch, an incomplete target variant, a dashboard or view the caller cannot read, a colour outside the Tailwind palette, background, padding or showTitle outside backdrop `custom`, a value outside the supported range, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
1056
+ */
1057
+ async updatePortalDatabaseBlock(params) {
1058
+ return this.client.request({
1059
+ method: "PATCH",
1060
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/database",
1061
+ pathParams: params.path,
1062
+ headers: params.headers,
1063
+ body: params.body,
1064
+ opId: "updatePortalDatabaseBlock",
1065
+ expectedContentType: "application/json",
1066
+ });
1067
+ }
1068
+ /**
1069
+ * Update a portal Dynamic Table block
1070
+ * Edits ONE existing Dynamic Table block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one of `title`, `appearance` or `layout` must be sent. This operation does not configure or replace the integration provider, OAuth connection, data source, columns or rows. Title is plain text and supports only {{ClientName}} and {{ClientLastName}}. Appearance is a complete variant. Layout width is 2 to 6 and manual height is at least 50; null restores automatic height. Call getPortalBlock first for the current settings. Rejected with 400: an empty patch, unsupported variables, invalid appearance/layout, a block of another kind, and a patch the block already satisfies. Requires portals.write access.
1071
+ */
1072
+ async updatePortalDynamicTableBlock(params) {
1073
+ return this.client.request({
1074
+ method: "PATCH",
1075
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/dynamic-table",
1076
+ pathParams: params.path,
1077
+ headers: params.headers,
1078
+ body: params.body,
1079
+ opId: "updatePortalDynamicTableBlock",
1080
+ expectedContentType: "application/json",
1081
+ });
1082
+ }
1083
+ /**
1084
+ * Update a portal Embed block
1085
+ * Edits ONE existing Embed block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. Editable: `title`, `embedType`, `url` or `content`, `showEmbedLink`, `colspan` (2 to 6), `rowspan` (1 to 4) and `height` (a positive number, or null for the automatic height). The SOURCE is not a field-level patch: `embedType` plus exactly one of `url` (named variants) or `content` (`custom`) is a complete variant, so changing the type requires sending the matching source in the same request, and `embedType` alone is rejected. Call getPortalBlock first to see the current values. Rejected with 400: an empty patch, a url on a `custom` embed or content on a named one, a non-external or malformed url, embed code with no supported construct, a value outside the supported range, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
1086
+ */
1087
+ async updatePortalEmbedBlock(params) {
1088
+ return this.client.request({
1089
+ method: "PATCH",
1090
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/embed",
1091
+ pathParams: params.path,
1092
+ headers: params.headers,
1093
+ body: params.body,
1094
+ opId: "updatePortalEmbedBlock",
1095
+ expectedContentType: "application/json",
1096
+ });
1097
+ }
1098
+ /**
1099
+ * Update a portal File uploader block
1100
+ * Updates title, short description, Author/Upload date visibility or layout of one existing File uploader block. It does not expose storage, permissions, bucket/file ids, query, sort, limit, appearance or rows.
1101
+ */
1102
+ async updatePortalFileUploaderBlock(params) {
1103
+ return this.client.request({
1104
+ method: "PATCH",
1105
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/file-uploader",
1106
+ pathParams: params.path,
1107
+ headers: params.headers,
1108
+ body: params.body,
1109
+ opId: "updatePortalFileUploaderBlock",
1110
+ expectedContentType: "application/json",
1111
+ });
1112
+ }
1113
+ /**
1114
+ * Update a portal Form block
1115
+ * Updates title, description, form fields/submit/reusable settings, appearance or layout. Fields are a full desired list: preserve existing fieldId values and omit fieldId only for new fields. A non-reusable Form with response data cannot change fields or submit controls. Response data, brick ids and indexes are never accepted.
1116
+ */
1117
+ async updatePortalFormBlock(params) {
1118
+ return this.client.request({
1119
+ method: "PATCH",
1120
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/form",
1121
+ pathParams: params.path,
1122
+ headers: params.headers,
1123
+ body: params.body,
1124
+ opId: "updatePortalFormBlock",
1125
+ expectedContentType: "application/json",
1126
+ });
1127
+ }
1128
+ /**
1129
+ * Update a portal Heading block
1130
+ * Edits ONE existing Text & Media Heading block and STAGES the change in the active customizer draft; nothing is published. Editable: `content` (text, colour, size, styles, alignment), `appearance` and `layout`. The block's wrapper title, HTML, CSS, image url and raw bricks are not accepted. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. `content` is a field-level patch — a size, style or alignment left out keeps what the block has today. `appearance` is NOT: it is a discriminated variant and must be sent complete, so read the current one with getPortalBlock first; under backdrop `custom` an omitted `background` keeps the block's current one, which is what getPortalBlock reports for a block still on the portal theme's surface colour. `layout.colspan` is 2 to 6 and `layout.height` is at least 50, or null for the automatic height. Rejected with 400: an empty patch, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
1131
+ */
1132
+ async updatePortalHeadingBlock(params) {
1133
+ return this.client.request({
1134
+ method: "PATCH",
1135
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/heading",
1136
+ pathParams: params.path,
1137
+ headers: params.headers,
1138
+ body: params.body,
1139
+ opId: "updatePortalHeadingBlock",
1140
+ expectedContentType: "application/json",
1141
+ });
1142
+ }
1143
+ /**
1144
+ * Update portal homepage settings
1145
+ * Sets the portal's Homepage settings, the same panel the customizer shows: title (renames the Home menu item and the homepage itself) and the sidebar toggles showSidebarOnOtherPages, showSidebarOnHomePage and expandSidebarByDefault. Only the provided fields change; omitted fields keep their current value. The change is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending change under Homepage settings, and publishes it. Returns the draft branch and the seqs of the staged events. Requires portals.write access.
1146
+ */
1147
+ async updatePortalHomepage(params) {
1148
+ return this.client.request({
1149
+ method: "POST",
1150
+ path: "/:orgId/portals/:portalId/homepage",
1151
+ pathParams: params.path,
1152
+ headers: params.headers,
1153
+ body: params.body,
1154
+ opId: "updatePortalHomepage",
1155
+ expectedContentType: "application/json",
1156
+ });
1157
+ }
1158
+ /**
1159
+ * Update a portal HTML/CSS block
1160
+ * Updates title, a partial raw HTML/CSS/JavaScript content patch or layout of one existing HTML/CSS block. The portal must use a verified custom CNAME domain. Omitted code fields remain unchanged and an empty string clears one field.
1161
+ */
1162
+ async updatePortalHtmlCssBlock(params) {
1163
+ return this.client.request({
1164
+ method: "PATCH",
1165
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/html-css",
1166
+ pathParams: params.path,
1167
+ headers: params.headers,
1168
+ body: params.body,
1169
+ opId: "updatePortalHtmlCssBlock",
1170
+ expectedContentType: "application/json",
1171
+ });
1172
+ }
1173
+ /**
1174
+ * Update a portal Image block layout
1175
+ * Edits the LAYOUT of one existing Text & Media Image block and STAGES the change in the active customizer draft; nothing is published. The picture stays the Customizer's built-in image — an image url, asset id, upload, base64, local path, filename, content or appearance is rejected. `layout.colspan` is 2 to 6 and `layout.height` is at least 50, or null for the automatic height. Rejected with 400: an empty patch, a block of another kind, and a patch the block already satisfies. Requires portals.write access.
1176
+ */
1177
+ async updatePortalImageBlock(params) {
1178
+ return this.client.request({
1179
+ method: "PATCH",
1180
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/image",
1181
+ pathParams: params.path,
1182
+ headers: params.headers,
1183
+ body: params.body,
1184
+ opId: "updatePortalImageBlock",
1185
+ expectedContentType: "application/json",
1186
+ });
1187
+ }
1188
+ /**
1189
+ * Update a portal Info block
1190
+ * Updates title, a complete semantic image or destination variant, new-tab behavior or layout of one existing Info block. Icon images require an exact id returned by searchPortalInfoBlockIcons. Raw persisted image/link values, wrappers and indexes are never accepted.
1191
+ */
1192
+ async updatePortalInfoBlock(params) {
1193
+ return this.client.request({
1194
+ method: "PATCH",
1195
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/info",
1196
+ pathParams: params.path,
1197
+ headers: params.headers,
1198
+ body: params.body,
1199
+ opId: "updatePortalInfoBlock",
1200
+ expectedContentType: "application/json",
1201
+ });
1202
+ }
1203
+ /**
1204
+ * Update a portal menu item
1205
+ * Updates an existing portal menu item (folder, page, or link) identified by itemId. Supports rename (name), icon, visibility (visible), reorder within a bar (index), moving between bars (positionType: sidebar/top/footer), and re-parenting (parentId, '' = root). Re-parenting is rejected (400) if parentId is the item itself, one of its descendants, or an item that cannot hold children (only a folder, note, section, process or page can — a link, dashboard, tag list or the home item is rejected), and 404s if the parent is not in the menu. A re-parented item moves to its parent's bar along with its whole subtree, so a positionType passed alongside parentId must match the parent's bar (400 otherwise). Pass only the fields to change; at least one is required. The item may be a published one (from listPortalContent) or one that exists only in the active draft — use the exact menuItemId/folderId returned by createPortalPage, createPortalPageWithNote, createPortalFolder or createPortalLink. The same holds for parentId. The change is staged in the portal's customizer draft (not published immediately): the owner reviews and publishes it, and a concurrent customizer edit returns 409 — retry the request. Requires portals.write access.
1206
+ */
1207
+ async updatePortalItem(params) {
1208
+ return this.client.request({
1209
+ method: "PATCH",
1210
+ path: "/:orgId/portals/:portalId/items/:itemId",
1211
+ pathParams: params.path,
1212
+ headers: params.headers,
1213
+ body: params.body,
1214
+ opId: "updatePortalItem",
1215
+ expectedContentType: "application/json",
1216
+ });
1217
+ }
1218
+ /**
1219
+ * Update a portal Linked block
1220
+ * Changes the exact source of ONE existing Linked block and stages the change. Resolve the source page with listPortalContent, then use the exact source from listPortalLinkableBlocks. Both portals must be in the same organization and editable by the caller. A cross-portal source must be published. Linked blocks cannot reference another Linked block or a source on their own target page. Title, content, appearance and layout are mirrored and cannot be supplied.
1221
+ */
1222
+ async updatePortalLinkedBlock(params) {
1223
+ return this.client.request({
1224
+ method: "PATCH",
1225
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/linked",
1226
+ pathParams: params.path,
1227
+ headers: params.headers,
1228
+ body: params.body,
1229
+ opId: "updatePortalLinkedBlock",
1230
+ expectedContentType: "application/json",
1231
+ });
1232
+ }
1233
+ /**
1234
+ * Update a note-backed portal block
1235
+ * Edits ONE existing note-backed block — the kind behind addPortalNoteBlock, addPortalBlankNoteBlock, addPortalKanbanBlock and addPortalTaskListBlock, which all persist as the same block kind — and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. Editable: `title`, `layout.colspan` (3, 4, 5 or 6) and `layout.height` (at least 50, or null for the automatic height). The block's CONTENT is not editable here — the note's text, the Kanban board and the task list belong to their own operations, and noteId/workspaceId are the block's identity. Call getPortalBlock first to see the current values and confirm the change. Rejected with 400: an empty patch, a colspan or height outside the supported range, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
1236
+ */
1237
+ async updatePortalNoteBlock(params) {
1238
+ return this.client.request({
1239
+ method: "PATCH",
1240
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/note",
1241
+ pathParams: params.path,
1242
+ headers: params.headers,
1243
+ body: params.body,
1244
+ opId: "updatePortalNoteBlock",
1245
+ expectedContentType: "application/json",
1246
+ });
1247
+ }
1248
+ /**
1249
+ * Update a portal Recent files block
1250
+ * Edits ONE existing Recent files block and STAGES the change in the active customizer draft; nothing is published. This is a PATCH: an omitted field keeps its current value, and at least one of `title`, `source` or `layout` must be sent. Source is either the entire portal or one exact page in the same portal; resolve that page first with listPortalContent. The operation cannot change sort order, the five-item limit, offset, file type, other query data or appearance. Width is 3, 4, 5 or 6 and manual height is at least 50; null restores automatic height. Call getPortalBlock first for the current settings. Requires portals.write access.
1251
+ */
1252
+ async updatePortalRecentFilesBlock(params) {
1253
+ return this.client.request({
1254
+ method: "PATCH",
1255
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/recent-files",
1256
+ pathParams: params.path,
1257
+ headers: params.headers,
1258
+ body: params.body,
1259
+ opId: "updatePortalRecentFilesBlock",
1260
+ expectedContentType: "application/json",
1261
+ });
1262
+ }
1263
+ /**
1264
+ * Update portal branding
1265
+ * Sets the portal's branding, the same fields the customizer's Portal style panel writes: the color theme, the header logo and the favicon. Only the provided fields change; omitted fields keep their current value. Colors come from the named themes — arbitrary hex colors and web fonts are not part of the portal theme model; use updatePortalCustomCode for those. The change is staged in the portal's customizer draft (not published immediately): the portal owner opens the customizer, reviews the pending change and publishes it. Returns the draft branch and the seq of the staged event. Requires portals.write access.
1266
+ */
1267
+ async updatePortalStyle(params) {
1268
+ return this.client.request({
1269
+ method: "POST",
1270
+ path: "/:orgId/portals/:portalId/style",
1271
+ pathParams: params.path,
1272
+ headers: params.headers,
1273
+ body: params.body,
1274
+ opId: "updatePortalStyle",
1275
+ expectedContentType: "application/json",
1276
+ });
1277
+ }
1278
+ /**
1279
+ * Update a portal Simple text block
1280
+ * Edits ONE existing Text & Media Simple text block and STAGES the change in the active customizer draft; nothing is published. Editable: `content` (text, colour, size, styles, alignment), `appearance` and `layout`. The block's wrapper title, HTML, CSS, image url and raw bricks are not accepted. This is a PATCH: an omitted field keeps its current value, and at least one field must be sent. `content` is a field-level patch — a size, style or alignment left out keeps what the block has today. `appearance` is NOT: it is a discriminated variant and must be sent complete, so read the current one with getPortalBlock first; under backdrop `custom` an omitted `background` keeps the block's current one, which is what getPortalBlock reports for a block still on the portal theme's surface colour. `layout.colspan` is 2 to 6 and `layout.height` is at least 50, or null for the automatic height. Rejected with 400: an empty patch, a block of another kind, and a patch the block already satisfies — the message names which. Requires portals.write access.
1281
+ */
1282
+ async updatePortalTextBlock(params) {
1283
+ return this.client.request({
1284
+ method: "PATCH",
1285
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/text",
1286
+ pathParams: params.path,
1287
+ headers: params.headers,
1288
+ body: params.body,
1289
+ opId: "updatePortalTextBlock",
1290
+ expectedContentType: "application/json",
1291
+ });
1292
+ }
1293
+ /**
1294
+ * Update a portal Timeline block
1295
+ * Updates view, title, content, appearance or layout of one existing Timeline. content.steps is the full desired visual-order list of 1..6 steps; completed steps must form one prefix. Internal destinations use exact same-portal page ids.
1296
+ */
1297
+ async updatePortalTimelineBlock(params) {
1298
+ return this.client.request({
1299
+ method: "PATCH",
1300
+ path: "/:orgId/portals/:portalId/pages/:pageId/blocks/:blockId/timeline",
1301
+ pathParams: params.path,
1302
+ headers: params.headers,
1303
+ body: params.body,
1304
+ opId: "updatePortalTimelineBlock",
1305
+ expectedContentType: "application/json",
1306
+ });
1307
+ }
727
1308
  }
728
1309
  exports.PortalsApi = PortalsApi;