Searchwixapispec
Inspect the Wix REST API spec by writing JavaScript code that runs in a sandboxed read-only environment.
**Precondition:** you already have a method `docsUrl` — from `SearchWixRESTDocumentation`, `BrowseWixRESTDocsMenu`, `ReadFullDocsArticle`, a `WixREADME` recipe, or a prior tool result / the user's message in this conversation. If you don't have one yet, call `SearchWixRESTDocumentation` FIRST to discover it; do not use this tool to search for or choose an endpoint.
**Never pass a `docsUrl` you produced from memory.** If the exact URL you are about to pass to `getResourceSchemaByUrl` did not appear verbatim in an earlier tool result (or the user's message), it is a guess — call `SearchWixRESTDocumentation` first and use a URL from its ranked results. A guessed URL that merely looks plausible routinely resolves to the WRONG sibling method (e.g. `.../products-v3/create-product` when the task needs `.../products-v3/create-product-with-inventory`), sending the whole turn down a dead end. When in doubt, discover — don't guess.
**This tool's job is to INSPECT the exact schema of a method you have ALREADY located — its request/response shape, nested types, and enums. It is NOT a discovery tool for choosing which method to use.**
With a method `docsUrl` in hand, call `getResourceSchemaByUrl(methodDocsUrl)` to get the resource schema, then read the target method from `schema.methods` and resolve any nested `{ $circular: name }` types via `schema.components.schemas[name]`.
**If you don't already have a `docsUrl` in context, your FIRST action MUST be `SearchWixRESTDocumentation` (ranked semantic search) — not this tool.** Then pass the resulting `docsUrl` to `getResourceSchemaByUrl` here. Do NOT discover endpoints by hand-filtering or scanning `lightIndex` (e.g. `lightIndex.filter(...)` / `lightIndex.flatMap(...)` on a substring): it has no relevance ranking, matches only at resource-name granularity, and misses composite or method-level operations whose parent resource is named after a different noun than your intent. `lightIndex` is for resolving a `docsUrl` you already have, not for finding one.
Prefer `SearchWixAPISpec` over `ReadFullDocsMethodSchema` for REST method schemas when it is available, especially once you already have a docs URL from semantic search, menu browsing, or conversation context.
Prefer URL-first results:
- If you have a docs URL or partial docs URL, search `resource.docsUrl` and `method.docsUrl` first.
- If you have a method docs URL and need the request/response shape, call `getResourceSchemaByUrl(methodDocsUrl)` in this tool and return the selected method schema directly.
- For API execution, return and use `method.publicUrl` when available. It is the preferred executable `https://www.wixapis.com/...` URL.
- Return `docsUrl` for relevant resources/methods when the next step needs an article or API call source URL; do not hand off to `ReadFullDocsMethodSchema` just to inspect a REST method schema.
- Use `resourceId` only as the internal handle for low-level loaders; prefer URL helpers when you have a docs URL.
- `getResourceSchemaByUrl` resolves only **API resource/method** docs (e.g. `.../bookings/services/services-v2/create-service`). It does NOT work on **skill** pages (`.../skills/...`) or **article** pages — those have no schema. For an article, use `getArticleContentByUrl(docsUrl)`. Never pass a `.../skills/...` URL (skill recipes often cross-link sibling skill pages) — use `SearchWixRESTDocumentation` to find the real API method instead. If a lookup misses, don't retry the same URL; rediscover it with `SearchWixRESTDocumentation`.
Your code has access to these globals:
**lightIndex** — Current lightweight REST API resource array:
```typescript
interface LightIndex extends Array<LightResource> {
updatedAt?: string; // ISO timestamp for when spec sync generated this index
}
interface LightResource {
name: string; // resource display name, e.g. "<Resource> V3"
resourceId: string; // internal handle for getResourceSchema()
docsUrl: string; // e.g. "https://dev.wix.com/docs/api-reference/.../<resource>"
menuPath: string[]; // e.g. ["business-solutions", "<vertical>", "<resource>"]
methods: Array<{
operationId: string; // e.g. "wix.<vertical>.v3.<Api>.<Operation>"
summary: string; // human-readable method name
httpMethod: string; // "get" | "post" | "patch" | "delete"
path: string; // partial relative path, e.g. "/v3/<resources>"
docsUrl?: string; // e.g. "https://dev.wix.com/docs/api-reference/.../query-products"
publicUrl?: string; // preferred executable URL for ExecuteWixAPI, when available after spec sync
publicBaseUrl?: string;
description: string; // truncated to 200 chars
}>;
}
```
**getResourceSchemaByUrl(docsUrl)** and **getResourceSchema(resourceId)** return the full schema for a resource:
```typescript
interface FullSchema {
title: string;
description: string;
fqdn: string;
docsUrl?: string;
methods: Array<{
summary: string;
description: string;
operationId: string;
httpMethod: string;
path: string;
docsUrl?: string;
publicUrl?: string; // Preferred executable URL for ExecuteWixAPI, e.g. "https://www.wixapis.com/..."
publicBaseUrl?: string; // Public Wix APIs base URL used to derive publicUrl
servers: Array<{ url: string }>; // Base URLs (e.g. "https://www.wixapis.com/...")
requestBody: object | null;
responses: object;
parameters: Array<object>;
permissions: string[];
legacyExamples: Array<{ // Curl examples
content: { title: string; request: string; response: string };
}>;
}>;
components: { schemas: object };
}
```
**articles** — Array of all Wix documentation articles (~1000 guides, tutorials, concepts):
```typescript
interface LightArticle {
name: string; // e.g. "About the Wix API Query Language"
resourceId: string;
docsUrl: string; // e.g. "https://dev.wix.com/docs/api-reference/articles/..."
menuPath: string[]; // e.g. ["work-with-wix-apis", "data-retrieval", "about-the-wix-api-query-language"]
description: string; // first ~200 chars of the article content
}
```
**getResourceSchemaByUrl(docsUrl)** — Async function returning the full schema for the resource or method docs URL. Nested types appear as `{ $circular: name }` pointers into `components.schemas`; resolve them via `schema.components.schemas[name]`.
**getResourceSchema(resourceId)** — Lower-level async function returning the full schema for a resource ID. Prefer `getResourceSchemaByUrl(docsUrl)` when you have a docs URL.
**getArticleContentByUrl(docsUrl)** — Async function returning the full markdown content of an article docs URL (string).
**getArticleContent(resourceId)** — Lower-level async function returning the full markdown content of an article resource ID. Prefer `getArticleContentByUrl(docsUrl)` when you have a docs URL.
Articles and API resources share the same menuPath hierarchy. Use menuPath to find related articles and APIs within the same domain.
Your code MUST be an `async function()` expression that returns a value.
Top-level verticals and their subcategories. This is a shallow orientation snapshot, NOT the full tree: every subcategory below contains many more resources, and each resource its methods — none of them listed here. Filter lightIndex by menuPath for the complete live tree:
wix-apis
├── account-level
│ └── accounts, ai-credits, b2b-site-management, domains, enterprise, resellers, sites, studio-workspace, user-management
├── app-management
│ └── app-billing, app-extensions, app-installations, app-instance, app-permissions, app-tools, bi-event, companion-apps, embedded-scripts, market-listing, oauth-2, site-plugins
├── assets
│ └── media, pro-gallery, rich-content
├── business-management
│ └── ai-site-chat, analytics, app-installation, async-job, automations, branches, calendar, captcha, cookie-consent-policy, custom-embeds, dashboard, data-extension-schema, faq-app, functions, get-paid, google-business-profile, headless, locations, marketing, multilingual, notifications, online-programs, payments, secrets, seo, site-properties, site-search, site-urls, tags
├── business-solutions
│ └── benefit-programs, blog, bookings, cms, coupons, donations, e-commerce, events, forum, gift-cards, meetings, portfolio, pricing-plans, restaurants, stores, suppliers-hub
├── crm
│ └── communication, community, crm, forms, loyalty-program, members-contacts
├── mobile
│ └── containers-app
├── site
│ └── accessibility, viewer
└── tools
└── dynamic-site-context, semantic-search
(each leaf above expands into resources → methods; explore via lightIndex, e.g. lightIndex.filter(r => r.menuPath[1] === "e-commerce"))
Important schema guidance:
- For ExecuteWixAPI, ALWAYS use `method.publicUrl`. It is the complete, executable `https://www.wixapis.com/...` URL for that method. When `publicUrl` is present, never build the execution URL by hand and never expose any other field as "the endpoint".
- Do not use `method.servers[0]` to build execution URLs. `method.servers` includes internal Wix hosts such as `www.wix.com`, `manage.wix.com`, and editor hosts.
- `method.path` is a PARTIAL, relative path (e.g. `/v2/coupons/query`). It OMITS the gateway prefix that the real URL requires: many APIs are served under a prefix such as `/stores` or `/ecom` (for example, `path` `/v2/coupons/query` is actually served at `https://www.wixapis.com/stores/v2/coupons/query`). Prepending `https://www.wixapis.com` to `method.path` will 404 for these APIs. Treat `method.path` as a matching/debugging key only — never as an execution URL, and never surface it as the endpoint of a method.
- If — and only if — `publicUrl` is absent and you must construct the URL: recover the gateway prefix from `method.publicBaseUrl` (it is the segment(s) before the API version, e.g. `https://www.wixapis.com/stores/v2/coupons` → prefix `/stores`) and build `https://www.wixapis.com` + prefix + `method.path`. Do NOT simply concatenate `publicBaseUrl` + `path`; they overlap on the version/resource segments and would duplicate them.
- Do not exact-match full Wix API URLs against `method.path`.
- If you already have a docs URL, match it against `resource.docsUrl`/`method.docsUrl` first. Only as a fallback — when `SearchWixRESTDocumentation` is unavailable — filter `lightIndex` at method granularity across `method.summary`, `method.operationId`, `method.description`, and `method.docsUrl`, not just `resource.name`.
- Schemas use `{ "$circular": "TypeName" }` to reference a type defined in `schema.components.schemas`. The marker appears both in method bodies and *inside dictionary entries themselves*, so a looked-up type's nested fields may contain further `$circular` refs. **The `schema.components.schemas` dictionary returned in THIS call is complete — every `$circular` name resolves against it right here. Resolve every ref your task needs in this one call; do NOT make another `SearchWixAPISpec` call just to read a type you already have.** Expand **as much or as little as you need**, not the whole schema:
- Partial / targeted: from the `schema.components.schemas` you already have, look up only the specific types on the path you care about, e.g. `["…SeoSchema"]` then its `settings` type `["…SeoSchema.Settings"]` (see the "Expand selected nested schema refs" example) — all in the same call.
- Recursive: expand an entire subtree when you really need it (see the `expandRefs` example), but keep depth small and avoid dumping huge fully-expanded schemas.
- When inspecting a specific method schema (i.e. you have found a single method and are returning its details), always include `responses: method.responses` alongside `requestBody`. Knowing the response shape up front prevents speculative re-runs of mutations just to see what the API returned.
- Query/search methods: the declared map is `method.queryMethodData.queryFieldsCapabilitiesMap`, or `method.searchMethodData.searchFieldsCapabilitiesMap` on search methods. Each entry declares one field's allowed `operators` and `sort` directions — a closed list, valid for that method alone, so another endpoint's map or a field's presence in the response proves nothing here. Each listed operator is valid on its own — a field takes one — so combine conditions with the logical operators instead: `$and` and `$or` take an array of expressions, `$not` takes one, and they can nest. They are WQL syntax rather than a field capability, so they never appear in the map, and its silence about them is no restriction. An undeclared field or unlisted operator are rejected; some endpoints instead ignore the filter or sort and return the wrong rows. `sort: []` means not sortable; no map means nothing is declared, so try what you need and filter in code if it isn't supported.
Examples:
Inspect one method schema by exact docs URL:
```javascript
async function() {
const methodUrl = "https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products";
const schema = await getResourceSchemaByUrl(methodUrl);
const method = schema.methods.find(method => method.docsUrl === methodUrl);
if (!method) {
return {
message: "Found the resource, but no exact method URL match. Returning available methods.",
resourceDocsUrl: schema.docsUrl,
methods: schema.methods.map(method => ({
title: method.summary,
docsUrl: method.docsUrl,
httpMethod: method.httpMethod.toUpperCase(),
publicUrl: method.publicUrl
}))
};
}
return {
title: method.summary,
docsUrl: method.docsUrl,
resourceDocsUrl: schema.docsUrl,
publicUrl: method.publicUrl,
publicBaseUrl: method.publicBaseUrl,
httpMethod: method.httpMethod.toUpperCase(),
operationId: method.operationId,
permissions: method.permissions,
parameters: method.parameters,
requestBody: method.requestBody,
responses: method.responses,
// Query methods: which fields are filterable (allowed operators) and sortable.
queryFieldsCapabilities: method.queryMethodData?.queryFieldsCapabilitiesMap,
// Search methods carry the same thing under their own key — read both, they never overlap.
searchFieldsCapabilities: method.searchMethodData?.searchFieldsCapabilitiesMap,
curlExamples: method.legacyExamples?.map(example => example.content)
};
}
```
Inspect one resource by resource docs URL:
```javascript
async function() {
const resourceUrl = "https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3";
const schema = await getResourceSchemaByUrl(resourceUrl);
return {
resource: schema.title,
docsUrl: schema.docsUrl,
description: schema.description,
methods: schema.methods.map(method => ({
title: method.summary,
docsUrl: method.docsUrl,
httpMethod: method.httpMethod.toUpperCase(),
publicUrl: method.publicUrl,
operationId: method.operationId
}))
};
}
```
Inspect one method from a partial docs URL:
```javascript
async function() {
const partialUrl = "stores/catalog-v3/products-v3/query-products";
const resource = lightIndex.find(resource =>
resource.docsUrl.includes(partialUrl) ||
resource.methods.some(method => method.docsUrl?.includes(partialUrl))
);
if (!resource) return "No API resource found for this partial docs URL";
const schema = await getResourceSchemaByUrl(
resource.methods.find(method => method.docsUrl?.includes(partialUrl))?.docsUrl ??
resource.docsUrl
);
const method = schema.methods.find(method =>
method.docsUrl?.includes(partialUrl)
);
if (!method) {
return {
message: "Found the resource, but no exact method match.",
resource: resource.name,
resourceDocsUrl: resource.docsUrl,
methods: schema.methods.map(method => ({
title: method.summary,
docsUrl: method.docsUrl,
httpMethod: method.httpMethod.toUpperCase(),
publicUrl: method.publicUrl
}))
};
}
return {
title: method.summary,
docsUrl: method.docsUrl,
resource: resource.name,
resourceDocsUrl: resource.docsUrl,
httpMethod: method.httpMethod.toUpperCase(),
publicUrl: method.publicUrl,
publicBaseUrl: method.publicBaseUrl,
requestBody: method.requestBody,
responses: method.responses,
curlExamples: method.legacyExamples?.map(example => example.content)
};
}
```
Expand selected nested schema refs:
```javascript
async function() {
const methodUrl = "https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products";
const schema = await getResourceSchemaByUrl(methodUrl);
const method = schema.methods.find(method => method.docsUrl === methodUrl);
return {
title: method.summary,
docsUrl: method.docsUrl,
requestBody: method.requestBody,
selectedNestedTypes: {
product: schema.components.schemas["com.wix.stores.catalog.product.api.v3.Product"],
cursorPaging: schema.components.schemas["wix.stores.catalog.v3.upstream.wix.common.CursorPaging"],
sorting: schema.components.schemas["wix.stores.catalog.v3.upstream.wix.common.Sorting"]
}
};
}
```
Advanced: bounded recursive expansion for one method. Use only when top-level schema and selected nested refs are not enough; keep depth small because schemas can become very large.
```javascript
async function() {
const methodUrl = "https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products";
const schema = await getResourceSchemaByUrl(methodUrl);
const method = schema.methods.find(method => method.docsUrl === methodUrl);
function expandRefs(value, depth = 0, seen = []) {
if (depth > 3) return value;
if (Array.isArray(value)) return value.map(item => expandRefs(item, depth, seen));
if (!value || typeof value !== "object") return value;
if (value.$circular) {
const refName = value.$circular;
if (seen.includes(refName)) return { $ref: refName, circular: true };
const target = schema.components?.schemas?.[refName];
if (!target) return { $ref: refName, missing: true };
return {
$ref: refName,
schema: expandRefs(target, depth + 1, seen.concat(refName))
};
}
return Object.fromEntries(
Object.entries(value).map(([key, nested]) => [
key,
expandRefs(nested, depth, seen)
])
);
}
return {
title: method.summary,
docsUrl: method.docsUrl,
httpMethod: method.httpMethod.toUpperCase(),
publicUrl: method.publicUrl,
requestBody: expandRefs(method.requestBody),
responses: expandRefs(method.responses)
};
}
```
You do NOT discover endpoints in this tool. When you don't have a `docsUrl`, call `SearchWixRESTDocumentation` first, then inspect the method it points you to — pass its `docsUrl` to `getResourceSchemaByUrl` and read the method from `schema.methods`:
```javascript
// docsUrl came from SearchWixRESTDocumentation (or conversation context) — NOT from scanning lightIndex.
async function() {
const docsUrl = "https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products";
const schema = await getResourceSchemaByUrl(docsUrl);
const method = schema.methods.find(m => m.docsUrl === docsUrl);
return {
publicUrl: method.publicUrl,
httpMethod: method.httpMethod.toUpperCase(),
requestBody: method.requestBody,
responses: method.responses
};
}
```