All skills
wix avatar

/wix-manage

@4895cc9 official
by Wix.comwix/skills33 stars
33

REST recipes to configure and manage a Wix site's business solutions — stores, bookings, payments, CMS, and more. Open the matching recipe for the exact endpoint, method, and payload before calling — never guess a Wix API, never write Wix dashboard URL from memory. Routes to: stores, bookings, get-paid, CMS, contacts, forms, media, app-installation, pricing-plans, restaurants, ricos rich-content, sites, blog, calendar, domains, events, site-properties, ecommerce, marketing, google-ads, google-business-profile, analytics, accessibility, seo, dashboard-navigation.

Use this Skill: https://skilld.dev/gh/wix/skills/wix-manage

This session only. Nothing lands on disk.

referencesrich-contentauthor-ricos-rich-content.md

≈6.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Author Ricos Rich Content

Routing rule (READ FIRST). When hand-authoring or returning Ricos / richContent JSON, use this recipe — the shapes, nesting rules, spacer paragraphs, and plugin nodes below. Do not rely on API schema search alone; it misses those details. After this recipe loads, do not perform additional schema or documentation searches for node types covered here; compose and self-audit the JSON from this file. When the user only wants JSON output, do not call Ricos convert/validate APIs.

Ricos is Wix's rich-content format — a tree of typed nodes serialized as JSON. The same structure is embedded by many products: a Blog post's draftPost.richContent, a Store product's rich description, an Events description, and CMS rich-text fields all expect a Ricos document. This recipe is the authoring reference for that node tree: the valid shape of each node, how nodes nest, and how to format text. It is intentionally product-agnostic — the consuming API decides where the document goes; this recipe governs what a valid document looks like.

A Ricos document is an object with a nodes array: { "nodes": [ /* block nodes */ ] }. Whatever field the consuming API exposes (e.g. richContent), it holds this object. For validating or converting an existing document to/from HTML/Markdown, see Ricos Converter Service.

Universal rules for every node

  • type is always a bare string — "type": "PARAGRAPH", never an object like "type": { "type": "PARAGRAPH" }. An object-valued type may pass a shallow validation but renders as a broken/uneditable block.
  • Every node carries a type, an optional id, and (for container nodes) a nodes array of children. Node ids are optional when authoring for a create request — the API generates them; the examples below omit id for brevity.
  • TEXT is a leaf. A TEXT node only ever lives inside a PARAGRAPH, HEADING, or CODE_BLOCK. It must never sit directly in the root nodes array or inside a LIST_ITEM, BLOCKQUOTE, or TABLE_CELL — those must contain a PARAGRAPH (or HEADING) that then contains the TEXT. See Nesting rules.
  • Failing to wrap TEXT correctly produces the parse error "Expected a paragraph node but found TEXT".
  • Block nodes do not get automatic vertical gap when rendered — insert empty PARAGRAPH spacer nodes between sibling blocks when you need breathing room. See Vertical spacing between blocks.

Required plugin shape checklist

Use this checklist while composing and again before returning JSON. Treat every path below as required for the described request:

  • Button CTA: emit a root-level BUTTON, never a PARAGRAPH with an inline LINK. Include buttonData.type: "LINK", buttonData.text, buttonData.link.url, buttonData.link.target, and buttonData.containerData.
  • Hosted audio: emit { "type": "AUDIO", "nodes": [], "audioData": { ... } }. The empty nodes array is on the AUDIO node beside audioData — never inside audioData. Include audioData.containerData.alignment, width, and textWrap, plus audioData.audio.src.id.
  • Video with thumbnail: place videoData.video.src and videoData.video.duration inside video; place videoData.thumbnail beside video, with src.id, width, and height.
  • Gallery: emit one root-level GALLERY. Put images in galleryData.items, not as child IMAGE nodes. Every item uses image.media with src, width, and height; include galleryData.options.layout.type and numberOfColumns.
  • Collapsible FAQ: use COLLAPSIBLE_LIST → COLLAPSIBLE_ITEM → COLLAPSIBLE_ITEM_TITLE | COLLAPSIBLE_ITEM_BODY → PARAGRAPH → TEXT. Every PARAGRAPH includes paragraphData, and every item includes both title and body.
  • HTML embed: emit a root-level HTML with htmlData.source, either url or html, and htmlData.containerData.width, height, and alignment.

Vertical spacing between blocks

The renderer does not add margin between stacked block nodes. Adjacent paragraphs, headings, images, videos, tables, collapsible lists, buttons, galleries, and other blocks will sit flush against each other unless you separate them explicitly.

Use an empty PARAGRAPH as a spacer — a paragraph with no nodes (no TEXT children):

{ "type": "PARAGRAPH" }

Place spacer paragraphs at the root nodes level (or inside a CARD page) wherever layout needs vertical rhythm:

  • After headings — before the following body copy or media block.
  • Between paragraphs — when two text blocks should not run together visually.
  • After block plugins — images, videos, audio, galleries, tables, collapsible lists, HTML embeds, buttons, dividers, and lists often need a spacer before the next distinct section (not between every adjacent block in a minimal snippet the user enumerated).
  • After blockquotes — only when the following block is a separate section; skip the spacer when the user asked for a blockquote immediately followed by a specific paragraph in one compact output.
  • Before major sections — optional extra spacer when transitioning from one content group to another.

When the user requests only specific nodes in one JSON output (e.g. "a blockquote and then a paragraph"), include exactly those nodes — do not add spacer paragraphs they did not ask for.

Do not rely on \n inside textData.text for spacing — that does not create a real line break between blocks. Do not expect paragraphData margins or containerData alone to separate unrelated sibling nodes; the empty paragraph is the supported spacing mechanism.

Example — spacer after an image and before a table:

{
  "nodes": [
    { "type": "IMAGE", "imageData": { /* … */ } },
    { "type": "PARAGRAPH" },
    { "type": "TABLE", "nodes": [ /* … */ ], "tableData": { /* … */ } },
    { "type": "PARAGRAPH" },
    { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Next section.", "decorations": [] } } ], "paragraphData": {} }
  ]
}

Block node shapes

PARAGRAPH — the base text container. An empty paragraph — { "type": "PARAGRAPH" } — is the vertical spacer between block nodes (the renderer adds no gap on its own). See Vertical spacing between blocks. paragraphData.textStyle.textAlignment accepts AUTO·LEFT·CENTER·RIGHT·JUSTIFY:

{
  "type": "PARAGRAPH",
  "nodes": [
    { "type": "TEXT", "textData": { "text": "Body copy.", "decorations": [] } }
  ],
  "paragraphData": { "textStyle": { "textAlignment": "AUTO" } }
}

HEADING — same TEXT-in-container shape as PARAGRAPH, with the level (1–6) in headingData:

{
  "type": "HEADING",
  "nodes": [
    { "type": "TEXT", "textData": { "text": "Section Title", "decorations": [] } }
  ],
  "headingData": { "level": 2, "textStyle": { "textAlignment": "AUTO" } }
}

BULLETED_LIST / ORDERED_LIST — nesting is LIST → LIST_ITEM → PARAGRAPH → TEXT. Ordered lists use orderedListData in place of bulletedListData:

{
  "type": "BULLETED_LIST",
  "nodes": [
    {
      "type": "LIST_ITEM",
      "nodes": [
        {
          "type": "PARAGRAPH",
          "nodes": [
            { "type": "TEXT", "textData": { "text": "First item", "decorations": [] } }
          ]
        }
      ]
    }
  ],
  "bulletedListData": { "indentation": 0 }
}

BLOCKQUOTE — wraps a PARAGRAPH (never a bare TEXT):

{
  "type": "BLOCKQUOTE",
  "nodes": [
    {
      "type": "PARAGRAPH",
      "nodes": [
        { "type": "TEXT", "textData": { "text": "A quoted line.", "decorations": [] } }
      ]
    }
  ],
  "blockquoteData": { "indentation": 1 }
}

DIVIDER — a standalone horizontal rule (no children). lineStyle: SINGLE·DOUBLE·DASHED·DOTTED; width: LARGE·MEDIUM·SMALL:

{
  "type": "DIVIDER",
  "dividerData": { "lineStyle": "SINGLE", "width": "LARGE", "alignment": "CENTER" }
}

TABLE — nesting is TABLE → TABLE_ROW → TABLE_CELL → PARAGRAPH → TEXT. tableData.dimensions.colsWidthRatio sets relative column widths. Fill a header row or zebra-stripe body rows with tableCellData.cellStyle.backgroundColor (a hex string):

{
  "type": "TABLE",
  "nodes": [
    {
      "type": "TABLE_ROW",
      "nodes": [
        {
          "type": "TABLE_CELL",
          "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE", "backgroundColor": "#116DFF" }, "borderColors": {} },
          "nodes": [
            { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Header A", "decorations": [] } } ] }
          ]
        },
        {
          "type": "TABLE_CELL",
          "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE", "backgroundColor": "#116DFF" }, "borderColors": {} },
          "nodes": [
            { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Header B", "decorations": [] } } ] }
          ]
        }
      ]
    }
  ],
  "tableData": { "dimensions": { "colsWidthRatio": [50, 50], "colsMinWidth": [120, 120], "rowsHeight": [47] } }
}

CODE_BLOCK — children are TEXT nodes (one per line, or \n-joined):

{ "type": "CODE_BLOCK", "nodes": [ { "type": "TEXT", "textData": { "text": "const x = 1;", "decorations": [] } } ], "codeBlockData": { "textStyle": { "textAlignment": "AUTO" } } }

IMAGE — references a Wix Media id (upload/import the image first via Media Manager; a raw external URL will not render). Requires width and height. An optional CAPTION child holds a TEXT node:

{
  "type": "IMAGE",
  "nodes": [
    { "type": "CAPTION", "nodes": [ { "type": "TEXT", "textData": { "text": "Figure 1", "decorations": [] } } ] }
  ],
  "imageData": {
    "containerData": { "width": { "size": "CONTENT" }, "alignment": "CENTER" },
    "image": { "src": { "id": "mediaId" }, "width": 900, "height": 600 },
    "altText": "Descriptive alt text"
  }
}

BUTTON — a standalone call-to-action block. Not the same as an inline LINK decoration on TEXT (that is hyperlinked body copy; this is a labeled button control). buttonData.type is required on every BUTTON node — use "LINK" for URL navigation or "ACTION" for viewer click handlers (never omit type even when link is present). Two buttonData.type values:

  • LINK — navigates to a URL when clicked (link.url, link.target: BLANK·SELF, optional link.rel).
  • ACTION — triggers a viewer onClick handler (store the node in JSON; behavior is configured in the Ricos viewer, not in the document body).
{
  "type": "BUTTON",
  "buttonData": {
    "type": "LINK",
    "text": "Get Started",
    "link": { "url": "https://example.com", "target": "BLANK", "rel": { "nofollow": true } },
    "containerData": { "alignment": "CENTER", "width": { "size": "ORIGINAL" }, "textWrap": true },
    "styles": { "borderRadius": 4, "borderWidth": 0, "backgroundColor": "#116DFF", "textColor": "#FFFFFF" }
  }
}

AUDIO — uploaded audio via Wix Media src.id, or an embed variant whose audioData.html holds an iframe (SoundCloud, Spotify). Include audioData.containerData with alignment and width settings, and use an empty nodes: [] array because AUDIO has no child nodes. Optional fields include coverImage (src.id, width, height), name, authorName, and disableDownload:

{
  "type": "AUDIO",
  "nodes": [],
  "audioData": {
    "containerData": { "alignment": "CENTER", "width": { "size": "CONTENT" }, "textWrap": true },
    "audio": { "src": { "id": "mp3/f0f74f_48772df0375c41cd88e8e29370ccf899" } },
    "disableDownload": true,
    "coverImage": { "src": { "id": "f0f74f_2973832f552e4002b58ec6abbe7fce71~mv2.png" }, "width": 436, "height": 524 },
    "name": "Track title",
    "authorName": "Artist name"
  }
}

VIDEO — Wix Media video.src.id, duration (seconds), and a thumbnail (src.id, width, height). YouTube and other embeds use the same VIDEO node shape with the appropriate media id:

{
  "type": "VIDEO",
  "videoData": {
    "containerData": { "width": { "size": "CONTENT" }, "alignment": "CENTER" },
    "video": { "src": { "id": "video/11062b_a552731f40854d16a91627687fb8d1a6/1080p/mp4/file.mp4" }, "duration": 14.08 },
    "thumbnail": { "src": { "id": "media/11062b_a552731f40854d16a91627687fb8d1a6f000.jpg" }, "width": 1920, "height": 1080 }
  }
}

GALLERY — multiple images in one block. Each items[] entry wraps image.media with src (id or url), width, and height. galleryData.options controls layout (layout.type: GRID, numberOfColumns, orientation; item.ratio, item.crop; thumbnails.placement):

{
  "type": "GALLERY",
  "galleryData": {
    "containerData": { "width": { "size": "CONTENT" }, "alignment": "CENTER", "textWrap": true },
    "items": [
      { "image": { "media": { "src": { "id": "8bb438_36726a2d14ec44ee9edc5693bade1092.jpg" }, "width": 3648, "height": 5472 } } },
      { "image": { "media": { "src": { "id": "8bb438_6bbf8e82fe8f4b79b6e03ee79b66fd6a.jpg" }, "width": 1920, "height": 1280 } } }
    ],
    "options": {
      "layout": { "type": "GRID", "horizontalScroll": false, "orientation": "COLUMNS", "numberOfColumns": 3 },
      "item": { "ratio": 1, "crop": "FILL" },
      "thumbnails": { "placement": "NONE" }
    }
  }
}

COLLAPSIBLE_LIST — FAQ-style expandable items. Nesting is COLLAPSIBLE_LIST → COLLAPSIBLE_ITEM → COLLAPSIBLE_ITEM_TITLE | COLLAPSIBLE_ITEM_BODY → PARAGRAPH → TEXT (body cells may also contain other supported block plugins such as IMAGE or VIDEO). The item wrapper type is COLLAPSIBLE_ITEM — not COLLAPSIBLE_LIST_ITEM or other variants:

{
  "type": "COLLAPSIBLE_LIST",
  "nodes": [
    {
      "type": "COLLAPSIBLE_ITEM",
      "nodes": [
        {
          "type": "COLLAPSIBLE_ITEM_TITLE",
          "nodes": [
            { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Question?", "decorations": [] } } ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } }
          ]
        },
        {
          "type": "COLLAPSIBLE_ITEM_BODY",
          "nodes": [
            { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Answer text.", "decorations": [] } } ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } }
          ]
        }
      ]
    }
  ],
  "collapsibleListData": {
    "containerData": { "alignment": "CENTER", "textWrap": true },
    "expandOnlyOne": false,
    "initialExpandedItems": "FIRST",
    "direction": "LTR"
  }
}

initialExpandedItems: NONE·FIRST·ALL. Set isQapageData: true in list metadata when the list should render as FAQ structured data in search results.

HTML — embeds external content in an iframe. Provide either url (page URL) or inline html markup; source is typically "HTML". Size via containerData.width / height (custom pixel strings or size):

{
  "type": "HTML",
  "htmlData": {
    "containerData": { "width": { "custom": "550" }, "height": { "custom": "550" }, "alignment": "CENTER" },
    "url": "https://example.com/embed",
    "source": "HTML"
  }
}

Inline text formatting (decorations)

Apply formatting with the decorations array on a TEXT node. Each decoration is an object with a type and (for some types) a data field:

{
  "type": "TEXT",
  "textData": {
    "text": "Bold, colored, and linked",
    "decorations": [
      { "type": "BOLD", "fontWeightValue": 700 },
      { "type": "COLOR", "colorData": { "foreground": "#116DFF" } },
      { "type": "LINK", "linkData": { "link": { "url": "https://example.com", "target": "BLANK" } } }
    ]
  }
}
Decoration Data field
BOLD fontWeightValue: 700
ITALIC italicData: true
UNDERLINE (none)
STRIKETHROUGH strikethroughData: true
COLOR colorData: { foreground: "#hex" } (add background for highlight)
LINK linkData: { link: { url, target: "BLANK" } }
FONT_SIZE fontSizeData: { unit: "PX", value: 24 }
SPOILER (none — { "type": "SPOILER" } hides text behind a reveal control)
  • Mixed formatting in one paragraph → split into multiple TEXT nodes (one per style run) inside the same PARAGRAPH. A single TEXT node carries one consistent set of decorations.
  • Use a plain hex string in foreground for colors.
  • No \n inside textData.text — one visual line is one node. Emit separate sibling PARAGRAPH/HEADING nodes for separate lines.

A complete worked example

Assemble the shapes above into one valid richContent document. This example exercises every common node type — heading, bulleted list, ordered list, blockquote, filled-header table, divider, code block, and a paragraph with mixed bold + link runs — all correctly nested. Copy its structure; replace the placeholder text with real content.

{
  "nodes": [
    { "type": "HEADING", "nodes": [ { "type": "TEXT", "textData": { "text": "What's New in v2.1", "decorations": [] } } ], "headingData": { "level": 2, "textStyle": { "textAlignment": "AUTO" } } },
    { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "This release focuses on speed and clarity.", "decorations": [] } } ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } },

    { "type": "HEADING", "nodes": [ { "type": "TEXT", "textData": { "text": "Highlights", "decorations": [] } } ], "headingData": { "level": 3 } },
    { "type": "BULLETED_LIST", "nodes": [
      { "type": "LIST_ITEM", "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Faster page loads", "decorations": [] } } ] } ] },
      { "type": "LIST_ITEM", "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Redesigned dashboard", "decorations": [] } } ] } ] }
    ], "bulletedListData": { "indentation": 0 } },

    { "type": "HEADING", "nodes": [ { "type": "TEXT", "textData": { "text": "How to upgrade", "decorations": [] } } ], "headingData": { "level": 3 } },
    { "type": "ORDERED_LIST", "nodes": [
      { "type": "LIST_ITEM", "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Back up your data", "decorations": [] } } ] } ] },
      { "type": "LIST_ITEM", "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Run the migration", "decorations": [] } } ] } ] }
    ], "orderedListData": { "indentation": 0 } },

    { "type": "BLOCKQUOTE", "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "The new dashboard cut our reporting time in half.", "decorations": [] } } ] } ], "blockquoteData": { "indentation": 1 } },

    { "type": "DIVIDER", "dividerData": { "lineStyle": "SINGLE", "width": "LARGE", "alignment": "CENTER" } },

    { "type": "HEADING", "nodes": [ { "type": "TEXT", "textData": { "text": "Plan comparison", "decorations": [] } } ], "headingData": { "level": 3 } },
    { "type": "TABLE", "nodes": [
      { "type": "TABLE_ROW", "nodes": [
        { "type": "TABLE_CELL", "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE", "backgroundColor": "#116DFF" }, "borderColors": {} }, "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Plan", "decorations": [ { "type": "BOLD", "fontWeightValue": 700 }, { "type": "COLOR", "colorData": { "foreground": "#FFFFFF" } } ] } } ] } ] },
        { "type": "TABLE_CELL", "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE", "backgroundColor": "#116DFF" }, "borderColors": {} }, "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Price", "decorations": [ { "type": "BOLD", "fontWeightValue": 700 }, { "type": "COLOR", "colorData": { "foreground": "#FFFFFF" } } ] } } ] } ] }
      ] },
      { "type": "TABLE_ROW", "nodes": [
        { "type": "TABLE_CELL", "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE" }, "borderColors": {} }, "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Starter", "decorations": [] } } ] } ] },
        { "type": "TABLE_CELL", "tableCellData": { "cellStyle": { "verticalAlignment": "MIDDLE" }, "borderColors": {} }, "nodes": [ { "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "$0", "decorations": [] } } ] } ] }
      ] }
    ], "tableData": { "dimensions": { "colsWidthRatio": [50, 50], "colsMinWidth": [120, 120], "rowsHeight": [47, 47] } } },

    { "type": "CODE_BLOCK", "nodes": [ { "type": "TEXT", "textData": { "text": "npm install @wix/sdk@latest", "decorations": [] } } ], "codeBlockData": { "textStyle": { "textAlignment": "AUTO" } } },

    { "type": "PARAGRAPH", "nodes": [
      { "type": "TEXT", "textData": { "text": "Read the ", "decorations": [] } },
      { "type": "TEXT", "textData": { "text": "full release notes", "decorations": [ { "type": "BOLD", "fontWeightValue": 700 }, { "type": "LINK", "linkData": { "link": { "url": "https://example.com/release-notes", "target": "BLANK" } } } ] } },
      { "type": "TEXT", "textData": { "text": " for details.", "decorations": [] } }
    ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } }
  ]
}

Note the mixed-run paragraph at the end: the linked words are their own TEXT node carrying BOLD + LINK, while the surrounding words are separate plain TEXT runs — that is how you apply formatting to part of a sentence.

Nesting rules

Parent Valid children
Root nodes PARAGRAPH, HEADING, BULLETED_LIST, ORDERED_LIST, BLOCKQUOTE, DIVIDER, IMAGE, TABLE, CODE_BLOCK, BUTTON, AUDIO, VIDEO, GALLERY, COLLAPSIBLE_LIST, HTML
PARAGRAPH / HEADING / CODE_BLOCK TEXT
BULLETED_LIST / ORDERED_LIST LIST_ITEM
LIST_ITEM / BLOCKQUOTE PARAGRAPH (which then contains TEXT)
TABLE → TABLE_ROW → TABLE_CELL cell contains PARAGRAPH / HEADING / IMAGE
IMAGE / VIDEO CAPTION (optional)
COLLAPSIBLE_LIST COLLAPSIBLE_ITEM
COLLAPSIBLE_ITEM COLLAPSIBLE_ITEM_TITLE, COLLAPSIBLE_ITEM_BODY
COLLAPSIBLE_ITEM_TITLE / _BODY PARAGRAPH (and other plugins supported inside collapsible cells — see COLLAPSIBLE_LIST above)
BUTTON / AUDIO / GALLERY / HTML (leaf — nodes: [] or omit)

Self-audit before returning the document

All decidable from the JSON itself — check before handing the document to a consuming API:

  1. Every type is a bare string — search for "type": {; there should be zero hits.
  2. TEXT wrapping — no TEXT node sits directly in the root array, a LIST_ITEM, a BLOCKQUOTE, or a TABLE_CELL.
  3. Container nesting is complete — LIST → LIST_ITEM → PARAGRAPH → TEXT and TABLE → TABLE_ROW → TABLE_CELL → PARAGRAPH → TEXT, no level skipped.
  4. Headings carry a level (1–6) and nest logically (don't jump H2 → H4).
  5. No \n inside textData.text — split into sibling nodes; mixed inline formatting → split into multiple TEXT runs.
  6. Images use a Wix Media id (not a raw URL), with width, height, and meaningful altText.
  7. Links — every LINK decoration has a valid url and target. Use a BUTTON block with buttonData.type: "LINK" for CTAs — not an inline LINK decoration styled to look like a button.
  8. Buttons — every BUTTON includes buttonData.type (LINK requires link.url; ACTION has no URL). Omitting type is invalid even when link is set. LINK buttons and inline LINK decorations serve different purposes.
  9. Media blocks — AUDIO has root-level nodes: [] and audioData.containerData; VIDEO keeps thumbnail beside video under videoData; every GALLERY item is under galleryData.items and carries image.media.src, width, and height.
  10. Collapsible lists — every item has both _TITLE and _BODY, each wrapping content through PARAGRAPH → TEXT, and every PARAGRAPH has paragraphData.
  11. HTML embeds — htmlData includes source, containerData.width, containerData.height, and either url or html (not both empty).
  12. Spoiler — SPOILER is a decoration on TEXT (or containerData.spoiler on some block plugins in editor output); preserve it verbatim on edit.
  13. Vertical spacing — stacked block nodes that should not appear cramped are separated by empty { "type": "PARAGRAPH" } spacers — especially after images, videos, tables, collapsible lists, galleries, buttons, and between consecutive paragraphs. Missing spacers produce a wall-of-blocks layout with no renderer-added margin.

Source: SKILL.md on GitHub

1 warning1d4 checks · Risk SAFE
  • Gen Agent Trust Hub1d

    The wix-manage skill is an extensive collection of management recipes for Wix sites, covering business solutions such as eCommerce, Bookings, SEO, and site provisioning. It utilizes official Wix REST endpoints and incorporates robust safety patterns, including mandatory user confirmation for sensitive operations and careful validation of site data before mutation.

  • Socket1d

    No alerts

  • Snyk1d

    Risk: MEDIUM · 1 issue

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 4895cc9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated yesterday
compatibility
Requires Wix REST API access (API key or OAuth).
  • wix
  • rest-api
  • ecommerce
  • bookings
  • cms
  • contacts
  • blog
  • domains
  • restaurants
  • site-configuration
  • api-integration

README badge

README badge for wix/skills/wix-manage

REST API operations for configuring Wix business solutions including stores, bookings, CMS, contacts, domains, and ecommerce. Routes to site setup, entity management (products, services, staff), bulk administrative operations, and server-to-server integrations across Wix's business app ecosystem.

Generated from the current SKILL.md.

Do I need API credentials to use these recipes?
Yes. The skill requires Wix REST API access via either an API key or OAuth token to execute any management operations.
Can I use these recipes to display data on my site frontend?
No. These recipes are for backend REST API operations only — site configuration, entity management, and administrative tasks. They do not cover frontend development or displaying data to users.
What business domains do these recipes cover?
The skill covers stores, bookings, payments, CMS, contacts, forms, media, apps, pricing plans, restaurants, rich content, sites, blogs, calendars, domains, and site properties.
Do these recipes handle OAuth authentication with external services like Google Calendar?
Yes. The external calendar integration recipe covers OAuth-based setup with Google Calendar, Microsoft Outlook, and Apple Calendar for bidirectional event sync.

Generated from the current SKILL.md. These answers refresh after source changes.