npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lacneu/wix-openclaw

v0.2.2

Published

Wix REST API plugin for OpenClaw — manage blog, CMS data, forms, bookings, contacts, events, FAQ on a single Wix site with site_id whitelist and approval gating on destructive ops

Readme

wix-openclaw-plugin

Wix REST API plugin for OpenClaw Manage blog, CMS data, forms, bookings, contacts, events, FAQ on a single Wix site — with site_id whitelist and approval gating on every destructive operation.

License: MIT OpenClaw npm version Plugin version


Overview

wix-openclaw is an OpenClaw plugin that lets your agent operate a Wix site through the official Wix REST API. It registers ~50 tools split across a dozen Wix products (Blog, CMS Data, Forms, Bookings, Contacts, Events, Reviews, FAQ, Multilingual, Sites, Site Media), plus a wix_design_brief helper that turns loose textual briefs into structured markdown artefacts.

Every tool funnels through a single authenticated HTTP client that:

  1. Injects the correct headers (Authorization, wix-account-id, wix-site-id)
  2. Refuses any call to a site UUID not in allowedSiteIdsbefore the network round trip
  3. Retries on 429/5xx with exponential backoff
  4. Maps non-retryable errors to clean tool failures (WixApiError)

Destructive operations (publish, delete, cancel, moderate) trigger a before_tool_call approval prompt that the operator must accept in the Control UI / Telegram before the call goes through.


Why a whitelist?

Wix accounts can host many sites. The wix-site-id header is the only thing between an agent and "we just published a draft on the wrong site".

allowedSiteIds is enforced in the client itself, before any HTTP request is built. If the LLM hallucinates a site UUID, the call fails locally — no traffic is generated and no Wix logs are polluted. This is the same reason google_workspace enforces a domain allowlist: prompt injection should never reach the wrong tenant.


Installation

Requirements

  • OpenClaw >= v2026.4.0
  • A Wix REST API key with the minimum required permissions (see Wix API Key permissions below)
  • The Wix account UUID and at least one site UUID

Install via OpenClaw CLI

openclaw plugins install @lacneu/wix-openclaw
openclaw plugins inspect @lacneu/wix-openclaw

Configuration

Add the entry to your openclaw.json:

{
  "plugins": {
    "allow": ["wix-openclaw", "openclaw-knowledge", "telegram"],
    "entries": {
      "wix-openclaw": {
        "enabled": true,
        "config": {
          "apiKey": "${WIX_API_KEY}",
          "accountId": "${WIX_ACCOUNT_ID}",
          "allowedSiteIds": ["${WIX_SITE_ID_ATARAXIS}"],
          "defaultSiteId": "${WIX_SITE_ID_ATARAXIS}",
          "logLevel": "info"
        }
      }
    }
  }
}

Add the secrets to your .env:

WIX_API_KEY=<your-wix-api-key>
WIX_ACCOUNT_ID=<your-wix-account-uuid>
WIX_SITE_ID_ATARAXIS=<your-target-site-uuid>

Restart the gateway:

openclaw gateway restart

Configuration reference

| Field | Type | Default | Description | |---|---|---|---| | enabled | boolean | true | Master switch — disables all wix_* tools when false | | apiKey | string | — | Wix REST API key. Sent raw in Authorization (no Bearer prefix). Supports ${ENV_VAR} | | accountId | string | — | Wix account UUID. Sent as wix-account-id. Supports ${ENV_VAR} | | allowedSiteIds | string[] | [] | Whitelist of Wix site UUIDs. Calls to other sites are rejected before the network round trip | | defaultSiteId | string | first of allowedSiteIds | Site UUID injected when a tool does not explicitly specify one | | approvalRequired | string[] | (every destructive tool) | Tool names that trigger a before_tool_call approval prompt | | logLevel | enum | info | debug / info / warn / error. debug logs request bodies (mind PII) |


Authentication header convention

Wix REST APIs use a slightly non-standard auth pattern: the API key goes raw in the Authorization header — without the Bearer prefix.

Authorization: <wix-api-key>
wix-account-id: <wix-account-uuid>
wix-site-id: <wix-site-uuid>

This plugin handles that for you; you only need to provide the three values.


Wix API Key permissions

A Wix REST API key has account-wide reach by design — it can target any of the sites under the Wix account it belongs to. Wix does not let you scope a key to a single site at creation time. The plugin compensates with its allowedSiteIds whitelist (cf. Why a whitelist?), but the API key permission set itself remains your most important defense against accidental — or malicious — over-reach. Treat it as a least-privilege configuration exercise.

Where to configure them Wix Dashboard → SettingsHeadless SettingsAPI Keys → click your key → Edit API KeyPermissions.

Minimum required (for the V1 toolset shipped here)

Tick only the following permissions on your API key. Everything else should stay unticked.

Basic permissions

  • [x] Get Sites List — required to discover and validate site UUIDs

Site permissions

  • [x] Wix Blog — drafts, posts, categories, tags
  • [x] Manage Site Media — upload images for blog cover & rich content
  • [x] Business Info — name, address, hours, timezone
  • [x] Wix Data — custom CMS collections (read & write)
  • [x] Wix Forms — read submitted forms
  • [x] Manage Form Submissions — read leads / contact requests
  • [x] Wix Contacts & Members — CRM contacts + members
  • [x] Wix Bookings — services, sessions, bookings
  • [x] Wix Events — events, RSVPs, guests
  • [x] Wix Reviews — list & moderate reviews
  • [x] Manage FAQ — FAQ categories and questions
  • [x] Multilingual Translation Schema Read — read site translations
  • [x] List Marketing Tags — read-only marketing/analytics tags

Optional, depending on the business model

Tick these only if the corresponding Wix product is actually in use on the target site:

  • [ ] Pricing Plans — if you sell subscription packages
  • [ ] Wix Stores + Wix eCommerce — if you sell physical/digital products. Without these, the wix_* tools that touch e-commerce resources (none in V1) cannot run.

Permissions to never tick (defense in depth)

The plugin does not need any of the following, and granting them needlessly amplifies the blast radius if the key ever leaks. Audit your key periodically and keep these unticked:

| Permission | Why it's dangerous | |---|---| | Manage Sites | Allows site deletion | | Manage Domains | Allows transferring your domain away | | Publish Metasite | Allows un-publishing the entire site | | Manage Embedded Scripts | Allows arbitrary JavaScript injection on every page | | OAuth Apps | Allows creating persistent OAuth apps that survive key revocation | | Manage Functions / Manage Your App | Arbitrary server-side code | | Connect Wix Payments Account / Wix Payments / Wix Cashier | Reroutes customer payments | | Manage Email Marketing / Manage Email Subscriptions | Mass-email spam & subscription tampering | | Server Sign On for Members | Lets the holder impersonate any member | | Manage Roles / Manage Site Members | Account take-over | | Wix CLI - Git Integration | Modify deployed code | | Multilingual Translation Schema Write | Tamper with on-site copy across languages | | Manage Notifications | Push spam to members | | Invoke AI Models | Bills your account for arbitrary LLM usage | | Manage Wixel Projects / Manage Site Branches | Layout/structure mutation | | Any All account permissions master toggle | Unties every account-wide capability above |

Mapping: tool group → required permission

Use this table to figure out which permission a given group of tools relies on. If you want a slimmer key (e.g. blog-only first), drop entire columns and remove the matching tools from your agent's allow-list.

| Tool group | Wix permission | Required if you use… | |---|---|---| | wix_sites_list, wix_site_url_get | Get Sites List | Always (used internally — wix_site_url_get reads viewUrl from the Site object, no separate "Read Site URLs" permission needed) | | wix_business_info_get | Business Info | wix_business_info_get | | wix_blog_* | Wix Blog | Any blog tool | | wix_media_* | Manage Site Media | Any media tool, and rich-content blog drafts | | wix_data_* | Wix Data | Any CMS collection tool | | wix_forms_* | Wix Forms + Manage Form Submissions | Lead reading | | wix_contacts_* | Wix Contacts & Members | CRM tooling | | wix_bookings_* | Wix Bookings | Booking tooling | | wix_events_* | Wix Events | Event tooling | | wix_reviews_* | Wix Reviews | Reviews moderation | | wix_faq_* | Manage FAQ | FAQ tooling | | wix_multilingual_* | Multilingual Translation Schema Read | Translation reads | | wix_design_brief | (none — no API call) | Always |

Wix app installation requirements

Some Wix REST endpoints only exist when the corresponding Wix app is installed on the target site. The plugin ships them all generically — they will simply return a clean error when the app is missing, and start working as soon as the app is installed (no plugin upgrade needed).

| Tool group | Wix app required | Error returned when missing | |---|---|---| | wix_blog_* | Wix Blog | 404 | | wix_data_* | Velo / Wix Code (enable in Editor) | 400 WDE0110: Wix Code not enabled | | wix_forms_* | Wix Forms | 404 | | wix_bookings_* | Wix Bookings | 404 | | wix_events_* | Wix Events | 428 WIX_EVENTS_APP_NOT_INSTALLED | | wix_reviews_* | Wix Reviews | 428 APP_NOT_INSTALLED | | wix_faq_* | Wix FAQ | 400 App is not installed | | wix_multilingual_* | Wix Multilingual | 403 | | wix_contacts_*, wix_media_*, wix_sites_list, wix_site_url_get, wix_business_info_get | (always available) | — |

To install a Wix app on your site: Wix Dashboard → App Market → search for the app → Add to Site. It is free in most cases and takes effect immediately for API calls.

Rotating the key

Wix keys can be revoked at any time from the same API Keys page. If a key leaks, or if you need to ship a temporary smoke-test key with narrower scope:

  1. Generate a new key with the desired scope.
  2. Update WIX_API_KEY in your environment.
  3. Restart the OpenClaw gateway.
  4. Revoke the old key.

The plugin reads the key on each request through the resolved config — no in-memory caching beyond the gateway lifecycle, so a restart fully flushes the previous credential.


Wix query envelope

Every POST /query tool (wix_contacts_query, wix_bookings_*_list, wix_forms_list_submissions, wix_events_*, wix_reviews_list, wix_multilingual_list_languages, wix_sites_list, wix_data_query_items) accepts the standard Wix Query Language envelope as plain optional parameters:

{
  // Optional — MongoDB-style filter, e.g.
  //   { "status": { "$in": ["ACTIVE", "PENDING"] } }
  //   { "$and": [{ "createdDate": { "$gt": "2026-01-01T00:00:00Z" } },
  //              { "info.emails.email": { "$contains": "acme" } }] }
  "filter": { /* ... */ },

  // Optional — sort entries applied in order
  "sort": [{ "fieldName": "createdDate", "order": "DESC" }],

  // Optional — offset paging (most endpoints)
  "paging": { "limit": 50, "offset": 0 },

  // Optional — cursor paging (Site Media, some Bookings, ...)
  "cursorPaging": { "limit": 50, "cursor": "<opaque>" },

  // Optional — projection
  "fields": ["id", "info.name"]
}

Supported operators (per the Wix Query Language docs): $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists, $startsWith, $contains, $hasSome, $hasAll, $matches, $and, $or, $not.

Live verification scope The plugin's smoke test currently exercises $eq, $in, $exists, field equality, sort entries, offset paging, and free-text search against the Ataraxis site. Other operators ($ne, $gt, $gte, $lt, $lte, $nin, $startsWith, $contains, $hasSome, $hasAll, $matches, $or, $not) and cursorPaging / fields projection are exposed structurally and routed to the body by the mapper, but per-operator live coverage on every endpoint is not in v0.2.0's scope. Each Wix endpoint individually decides which fields are filterable and which operators are accepted — Wix returns a clean 400 UNSUPPORTED_QUERY_FILTER when it disagrees, surfaced as a tool failure to the model.

Tools that have ergonomic shortcuts (e.g. wix_blog_list_drafts.status, wix_forms_list_submissions.namespace) always merge the shortcut into the filter via $and, so the agent can never silently override the shortcut by passing a competing filter.

Flat GET endpoints (wix_blog_list_drafts, wix_blog_list_published, wix_blog_list_categories, wix_blog_list_tags, wix_data_list_collections, wix_faq_list_*, wix_media_list, wix_multilingual_list_schemas) accept named query string params plus paging.{limit,offset,cursor} — they do NOT support the operator passthrough above. Each tool's parameters are documented in its description.


Tools

The Validated column reflects v0.2.0 verification on the Ataraxis Coaching site: live means hit by the smoke-test against a real Wix site; app-not-installed and velo-not-enabled mean the tool's endpoint exists but its backing Wix product is not active on the smoke-test site (the request still reaches Wix and the path/headers are correct); docs means write/destructive endpoints that we do not exercise live.

Blog

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_blog_list_drafts | List drafts; supports status (UNPUBLISHED \| PUBLISHED \| SCHEDULED \| IN_REVIEW \| ALL), sort, fieldsets, paging | — | live | | wix_blog_get_draft | Fetch a draft by id; supports fieldsets | — | live | | wix_blog_create_draft | Create a new draft | — | docs | | wix_blog_update_draft | Patch a draft | — | docs | | wix_blog_publish_draft | Publish a draft | required | docs | | wix_blog_list_published | List published posts; supports sort, featured, language, tagIds, categoryIds, fieldsets, paging | — | live | | wix_blog_get_post | Fetch a published post; supports fieldsets | — | live | | wix_blog_unpublish | Move post to trash (reversible) | required | docs | | wix_blog_delete_draft | Permanently delete a draft | required | docs | | wix_blog_list_categories | List blog categories; supports language, paging | — | live | | wix_blog_list_tags | List blog tags; supports language, paging | — | live |

Media

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_media_upload | Import image into Site Media by URL | — | docs | | wix_media_list | List files; supports parentFolderId, mediaTypes (IMAGE/VIDEO/AUDIO/DOCUMENT/ARCHIVE), cursor paging via paging.cursor | — | live |

The wix_media_upload tool returns the Wix file metadata, including the id. Pass that id back into wix_blog_create_draft as coverMedia.imageId or embed it into a Ricos rich-content node — see the tool description for the contract the LLM should follow.

Site

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_sites_list | List sites under the account (account-scoped); accepts the standard Wix query envelope | — | live | | wix_site_url_get | Get published URL of a site | — | live | | wix_business_info_get | Read business info (name, address, hours) | — | live |

CMS Data

Requires Velo / Wix Code to be enabled on the target site (Wix Editor → Velo → Enable Code). Without it, calls return HTTP 400 WDE0110: Wix Code not enabled.

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_data_list_collections | List CMS collections + schemas | — | velo-not-enabled | | wix_data_query_items | Full Wix query envelope on a collection | — | velo-not-enabled | | wix_data_get_item | Fetch one item by id | — | velo-not-enabled | | wix_data_insert_item | Insert a new item | — | docs | | wix_data_update_item | Update an item | — | docs | | wix_data_remove_item | Delete an item | required | docs |

Forms

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_forms_list_submissions | Full Wix query envelope; namespace defaults to wix.form_app.form and is always $and-merged with passthrough filter | — | live | | wix_forms_get_submission | Fetch a single submission | — | docs |

Contacts

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_contacts_query | Full Wix query envelope + free-text search | — | live | | wix_contacts_get | Get one contact | — | docs | | wix_contacts_create | Create a contact | — | docs | | wix_contacts_update | Update a contact | — | docs | | wix_contacts_label_add | Add labels to a contact | — | docs | | wix_contacts_delete | Delete a contact | required | docs |

Bookings

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_bookings_services_list | List bookable services; standard query envelope | — | live | | wix_bookings_query_bookings | Query bookings with operators (e.g. status: { $in: [...] }); standard query envelope | — | live | | wix_bookings_get_booking | Fetch one booking | — | docs | | wix_bookings_create | Create a booking | — | docs | | wix_bookings_reschedule | Move to a different slot | required | docs | | wix_bookings_cancel | Cancel a booking | required | docs |

Events

Requires the Wix Events app (returns 428 WIX_EVENTS_APP_NOT_INSTALLED otherwise).

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_events_list | List events; standard query envelope | — | app-not-installed | | wix_events_get | Fetch one event | — | app-not-installed | | wix_events_list_guests | List guests / RSVPs; eventId is $and-merged with passthrough filter | — | app-not-installed |

Reviews

Requires the Wix Reviews app (returns 428 APP_NOT_INSTALLED otherwise).

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_reviews_list | List reviews; standard query envelope | — | app-not-installed | | wix_reviews_get | Fetch one review | — | docs | | wix_reviews_moderate | Approve / reject a pending review | required | docs |

FAQ

Requires the Wix FAQ app (returns 400 App is not installed otherwise).

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_faq_list_categories | List FAQ categories | — | app-not-installed | | wix_faq_list_questions | List questions (filterable by category) | — | app-not-installed | | wix_faq_create_question | Create a question | — | docs | | wix_faq_update_question | Update a question | — | docs | | wix_faq_delete_question | Delete a question | required | docs |

Multilingual (read-only in V1)

Returns 403 on the Ataraxis smoke-test site — likely missing the Multilingual Translation Schema Read permission on the API key rather than an app-not-installed condition.

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_multilingual_list_languages | List configured languages; standard query envelope | — | 403-permission | | wix_multilingual_list_schemas | List translation schemas | — | 403-permission |

Design

| Tool | What it does | Approval | Validated | |---|---|---|---| | wix_design_brief | Turn a loose textual brief into a structured markdown artefact (palette, typography, sections, image-gen prompts). Does NOT call the Wix API. | — | n/a |


Approval flow

When the LLM calls a destructive tool, the plugin's before_tool_call hook fires and returns a requireApproval directive:

{
  "requireApproval": {
    "title": "Wix: confirm wix_blog_publish_draft",
    "description": "Tool `wix_blog_publish_draft` is about to run with the following parameters:\n\n```json\n{ \"draftPostId\": \"abc-123\" }\n```\n...",
    "severity": "critical",
    "timeoutMs": 600000,
    "timeoutBehavior": "deny"
  }
}

OpenClaw surfaces this to whichever channel/UI the operator is using (Telegram inline buttons, Control UI badge, etc.). If no decision is made within 10 minutes, the call is denied automatically.

You can override the gated set via approvalRequired in the plugin config — use an empty array to disable gating entirely (not recommended in production).


Recommended companion skill

OpenClaw plugins ship code (tools, hooks); they do not ship skills. Skills live in agent workspaces and carry the business context that makes the LLM use the tools correctly (audience, tone, recipes, guardrails).

To get an agent up and running with this plugin, copy examples/recommended-skill.md into the target workspace at ~/.openclaw/workspace-<agent>/skills/wix/SKILL.md, then replace the <PLACEHOLDER> values with your own (organisation name, domain, contributors, tone). Duplicate the file for each agent that should benefit from the skill.

The template covers:

  • Conversational triggers (encoded in the description frontmatter as per OpenClaw skill convention)
  • 5 usage recipes (publish article, list real drafts, read leads, manage bookings, design request)
  • Behavioural guardrails (approval recap before publish, app-not-installed handling, PII rules)
  • Tool mapping (short reference; the README is the source of truth)

Development

Project layout

wix-openclaw-plugin/
├── src/
│   ├── index.ts             # Entry point + tool collection
│   ├── config.ts            # resolveEnv + default resolution
│   ├── wix-client.ts        # Authenticated HTTP client + whitelist
│   ├── types.ts             # Shared interfaces
│   ├── hooks/
│   │   └── approval.ts      # before_tool_call approval gating
│   └── tools/
│       ├── _factory.ts      # defineWixTool helper
│       ├── blog.ts
│       ├── media.ts
│       ├── site.ts
│       ├── data.ts
│       ├── forms.ts
│       ├── contacts.ts
│       ├── bookings.ts
│       ├── events.ts
│       ├── reviews.ts
│       ├── faq.ts
│       ├── multilingual.ts
│       └── design.ts
├── test/
│   ├── wix-client.test.ts
│   ├── manifest.test.ts
│   ├── hooks/approval.test.ts
│   └── tools/blog.test.ts
├── tsconfig.json
├── tsconfig.test.json
├── tsconfig.test-build.json
├── openclaw.plugin.json
└── package.json

Build and test

npm install
npm run typecheck     # strict TS check (src + test)
npm test              # compile tests + run node:test
npm run build         # compile src/ → dist/
npm run clean         # remove dist + dist-test

Release process

  1. Update CHANGELOG.md with a new ## [x.y.z] - YYYY-MM-DD section
  2. Commit
  3. Tag and push:
    git tag v0.1.0
    git push origin v0.1.0
  4. GitHub Actions will:
    • Run typecheck, tests, build on Node.js 24
    • Stamp the version into package.json and openclaw.plugin.json
    • Publish to npm via Trusted Publishing (OIDC) — no NPM_TOKEN secret needed
    • Create a GitHub Release with the changelog excerpt

License

MIT — see LICENSE