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.

referencesbloghow-to-create-blog-posts.md

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

Article: Create and Publish Blog Posts with Rich Content and Images

Standard call shape (every curl below). The <AUTH> placeholder is shorthand for Authorization: Bearer <TOKEN> only. Body-bearing requests also need Content-Type: application/json.


Description

This article demonstrates how to create and immediately publish blog posts using Wix Blog REST API, including handling external images, rich content formatting, and proper media management workflow.

Part 0: Get an Author/Member ID (Required for 3rd-Party Apps)

IMPORTANT: When calling the Blog API as a 3rd-party app (not as the site owner), draftPost.memberId is required. The API will reject requests with "Missing post owner information" if omitted.

A memberId is the id of a site member (Wix Members). Only the Members API produces one. Run the two steps below in order and stop as soon as you have an id — do not go looking for an author id anywhere else (see What is not a memberId).

  1. Query site members using List Members:

    curl -X GET "https://www.wixapis.com/members/v1/members?fieldsets=PUBLIC&paging.limit=1" \
      -H "Authorization: <AUTH>"

    If the response contains a member, use members[0].id as draftPost.memberId and skip step 2. That member becomes the post author.

  2. If the site has no members yet — the response is {"members": [], "metadata": {"count": 0, "total": 0, ...}} — create the author member yourself with Create Member. This is the normal case on a new site or a site that only has Blog installed: nobody has signed up, so there is no member to reuse. Creating the author is a prerequisite of the post the user asked for, not a separate decision — create it, then say so in your summary.

    curl -X POST "https://www.wixapis.com/members/v1/members" \
      -H "Authorization: <AUTH>" \
      -H "Content-Type: application/json" \
      -d '{
        "member": {
          "loginEmail": "blogauthor@example.com",
          "contact": { "firstName": "Blog", "lastName": "Author" }
        }
      }'

    Use member.id from the response as draftPost.memberId. The new member comes back with status: "APPROVED", and its profile.nickname is derived from the contact name. That nickname is the author name the blog displays, so pass the name the user wants shown (or set member.profile.nickname explicitly). If the user named an author, use their name; otherwise a generic author like the example above is fine.

What is not a memberId

These are the wrong places to look, and probing them costs a round trip each:

  • Site collaborators / contributors are Wix users, not site members. The Contributors API returns account and user ids, which the Blog API will not accept as a memberId.
  • A contact is not a member. Querying Contacts returns contact ids; only members have a memberId. On a site with no members the contacts query is usually empty too.
  • GET https://www.wixapis.com/identity/v1/users returns 404. There is no site-scoped identity endpoint to read the site owner from. Do not try it.

Part 1: Import External Images to Wix Media Manager

  1. Identify external image URLs from user input for cover images and embedded content images.

  2. Import each external image using Import File. This converts external URLs to Wix Media IDs required for blog posts.

    curl -X POST "https://www.wixapis.com/site-media/v1/files/import" \
      -H "Authorization: <AUTH>" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://example.com/image.jpg",
        "mediaType": "IMAGE",
        "displayName": "Cover Image.jpg"
      }'

    The response will include a file.id field. Use this ID in blog post creation. Images with operationStatus: "PENDING" can be used immediately.

  3. Store the returned file IDs for use in blog post creation.

Part 2: Create Blog Post with Rich Content

You have two endpoints:

  • Single post: Create Draft Post — POST https://www.wixapis.com/blog/v3/draft-posts
  • Multiple posts (preferred for any N ≥ 2): Bulk Create Draft Posts — POST https://www.wixapis.com/blog/v3/bulk/draft-posts/create

Use the bulk endpoint when seeding multiple posts — one call replaces N single-post calls and avoids the per-call latency of ~25–30 s each.

Single-post endpoint
curl -X POST "https://www.wixapis.com/blog/v3/draft-posts" \
  -H "Authorization: <AUTH>" \
  -H "Content-Type: application/json" \
  -d '{
    "draftPost": {
      "title": "My Blog Post",
      "memberId": "author-member-id",
      "richContent": {
        "nodes": [
          {
            "type": "PARAGRAPH",
            "nodes": [{
              "type": "TEXT",
              "textData": {
                "text": "This is a paragraph with some content.",
                "decorations": []
              }
            }],
            "paragraphData": {}
          }
        ]
      },
      "media": {
        "wixMedia": {
          "image": { "id": "mediaId" }
        },
        "displayed": true,
        "custom": true
      }
    },
    "publish": true
  }'
Bulk-create endpoint (preferred for multiple posts)

⚠️ Body shape — read this carefully. Each item in draftPosts is a FLAT post object: {title, memberId, richContent, media?, ...}. Do NOT wrap each item in a draftPost field. Unlike the single-post endpoint (which uses {draftPost: {...}} because the request is one post), the bulk endpoint puts each post DIRECTLY inside the draftPosts array.

✅ CORRECT body shape (verified against the live API — returns 200 with results[].itemMetadata.success: true):

{
  "draftPosts": [
    { "title": "First Post",  "memberId": "...", "richContent": { /* … */ } },
    { "title": "Second Post", "memberId": "...", "richContent": { /* … */ } }
  ],
  "publish": true
}

❌ WRONG body shape (returns 400 Bad Request with draftPosts[i].title must not be empty because the API is looking for draftPosts[i].title directly and finds it nested under a draftPost field):

{
  "draftPosts": [
    { "draftPost": { "title": "First Post",  "memberId": "...", "richContent": { /* … */ } } },
    { "draftPost": { "title": "Second Post", "memberId": "...", "richContent": { /* … */ } } }
  ],
  "publish": true
}

The natural intuition is "the bulk endpoint reuses the single-post {draftPost: {...}} envelope, just inside an array" — that's wrong. The bulk endpoint flattens the envelope away because the array IS the envelope. Use the FLAT shape: draftPosts[i] IS the post.

Full bulk-create curl example
curl -X POST "https://www.wixapis.com/blog/v3/bulk/draft-posts/create" \
  -H "Authorization: <AUTH>" \
  -H "Content-Type: application/json" \
  -d '{
    "draftPosts": [
      {
        "title": "First Post",
        "memberId": "author-member-id",
        "richContent": { /* Ricos JSON — see below */ },
        "media": { "wixMedia": { "image": { "id": "mediaId" } }, "displayed": true, "custom": true }
      },
      {
        "title": "Second Post",
        "memberId": "author-member-id",
        "richContent": { /* Ricos JSON */ }
      }
    ],
    "publish": true
  }'

The response body is {results: [{itemMetadata: {id, originalIndex, success}}, ...]}. Each result's itemMetadata carries the created post id and a success: boolean flag — the bulk call returns 200 even if some posts fail; check each results[i].itemMetadata.success individually.

Common URL-shape mistakes (do not use these — both return 404):

  • /blog/v3/draft-posts/bulk ✗
  • /blog/v3/draft-posts/bulk-create ✗
  • The correct path is /blog/v3/bulk/draft-posts/create (note: bulk is a path segment between v3 and draft-posts, not a suffix on draft-posts).
  1. Structure rich content using Ricos JSON format. Reference Ricos documentation for complete node structure. Common node types:

    • PARAGRAPH for text content
    • HEADING for section headers
    • IMAGE for embedded images (requires Wix Media ID)
    • ORDERED_LIST and BULLETED_LIST for lists
    • BLOCKQUOTE for quoted text
    • LIST_ITEM for individual list items

    CRITICAL: All TEXT nodes MUST be wrapped in PARAGRAPH nodes within their parent containers.

    Correct Ricos structure example:

    {
      "nodes": [
        {
          "type": "PARAGRAPH",
          "nodes": [
            {
              "type": "TEXT",
              "textData": {
                "text": "This is a paragraph with some content.",
                "decorations": []
              }
            }
          ],
          "paragraphData": {}
        }
      ]
    }

    Correct BLOCKQUOTE structure:

    {
      "type": "BLOCKQUOTE",
      "nodes": [
        {
          "type": "PARAGRAPH",
          "nodes": [
            {
              "type": "TEXT",
              "textData": { "text": "Quote text here", "decorations": [] }
            }
          ],
          "paragraphData": {}
        }
      ],
      "blockquoteData": { "indentation": 1 }
    }

    Correct LIST_ITEM structure:

    {
      "type": "LIST_ITEM",
      "nodes": [
        {
          "type": "PARAGRAPH",
          "nodes": [
            {
              "type": "TEXT",
              "textData": { "text": "List item text", "decorations": [] }
            }
          ],
          "paragraphData": {}
        }
      ]
    }
  2. For embedded images in rich content, use IMAGE nodes with Wix Media IDs:

    {
      "type": "IMAGE",
      "nodes": [],
      "imageData": {
        "containerData": {
          "width": { "size": "CONTENT" },
          "alignment": "CENTER"
        },
        "image": {
          "src": { "id": "mediaId" },
          "width": 900,
          "height": 600
        },
        "altText": "Descriptive alt text"
      }
    }
  3. Set publish: true to immediately publish the post rather than saving as draft.

Part 3: Handle Categories and Tags (Optional)

  1. Resolve category IDs using List Categories if user provides category names.

  2. Resolve tag IDs using Query Tags if user provides tag labels.

  3. Include resolved IDs in categoryIds and tagIds arrays in the draft post object.

IMPORTANT NOTES:

  • Never mock blog posts or media IDs - always use the APIs to import images and create posts
  • Always read the full documentation of methods before implementation
  • External images MUST be imported via Import File API before use in blog posts - direct external URLs will not work
  • For 3rd-party app integrations, memberId is mandatory - get it from List Members, and if the site has no members yet, create one with Create Member (see Part 0). Never substitute a contact id, a collaborator/contributor id, or a Wix user id for a memberId
  • Use ONLY the file ID (without wix:image://v1/ prefix) for both cover images and embedded images
  • Rich content IMAGE nodes require both width and height properties in the image object
  • Images with "operationStatus": "PENDING" from import can be used immediately in blog posts
  • Set publish: true in the request to publish immediately rather than save as draft
  • For multiple posts, use Bulk Create Draft Posts API with draftPosts array
  • Include fieldsets: ['URL'] to get post URLs in the response
  • Handle image import failures gracefully - continue without images if import fails
  • Provide meaningful displayName values during image import for better organization
  • Use appropriate Ricos node types (PARAGRAPH, HEADING, LIST, etc.) for semantic content structure
  • Consider batching image imports when creating multiple posts with many images

CRITICAL RICOS JSON STRUCTURE RULES:

  • NEVER place TEXT nodes directly in BLOCKQUOTE, LIST_ITEM, or other container nodes
  • ALL TEXT nodes MUST be wrapped in PARAGRAPH nodes within their parent containers
  • BLOCKQUOTE nodes must contain PARAGRAPH nodes, which contain TEXT nodes
  • LIST_ITEM nodes must contain PARAGRAPH nodes, which contain TEXT nodes
  • Failure to follow proper nesting will result in parsing errors: "Expected a paragraph node but found TEXT"
  • Always validate Ricos structure before sending to ensure TEXT nodes are properly nested

Troubleshooting

Error Cause Solution
"Missing post owner information" memberId not provided Add draftPost.memberId - see Part 0 for how to get one
"memberIds ... do not exist" Invalid member ID The id is not a site member's id (e.g. a contact, contributor, or Wix user id). Re-resolve it with Part 0
List Members returns "total": 0 Site has no members yet Create the author member with Create Member - Part 0, step 2. Do not query contacts, contributors, or identity endpoints instead
"Expected a paragraph node but found TEXT" Invalid Ricos structure Wrap TEXT nodes in PARAGRAPH nodes (see structure rules above)
Image not displaying Using external URL directly Import image via Media Manager first, then use the returned file ID

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.