Execute JavaScript code against the Wix REST API.
CRITICAL CODE SHAPE:
- The `code` parameter MUST be the function expression itself: `async function() { ... }` or `async () => { ... }`.
- Do NOT send a script body like `const result = await ...; return result;`.
- Do NOT call the function yourself. The tool calls it for you.
- Put all `const`, `await`, and `return` statements inside the function body.
Do not rely on memory for Wix API endpoints, methods, schemas, or request bodies. Before writing code, use SearchWixAPISpec or the search, browse, read-docs, and schema tools to confirm the exact API URL, HTTP method, request body structure, schema field names, required fields, enum values, and auth context. Before accessing fields on a response object, know the exact shape — don't guess paths like `result.id` when the actual path might be `result.results[0].item.id`. When you fetch the method schema for the request body, include `responses: method.responses` at the same time — it costs nothing and tells you exactly what fields come back. When SearchWixAPISpec returns a method schema, use `method.publicUrl` for ExecuteWixAPI when available; do not use `method.servers[0]`, which may be an internal Wix host. Pass the docs article, recipe, or schema URLs you used in the `sourceDocUrls` parameter. Then write code using wix.request(). Auth is handled automatically — do NOT set Authorization, wix-site-id, or wix-account-id headers.
This tool overlaps with `CallWixSiteAPI` and `ManageWixSite`: all can call Wix REST APIs. Use `ExecuteWixAPI` when code helps express the task: repeating one API call in a loop, paginating through results, transforming data between calls, branching on API responses, or chaining several related API calls in one operation.
Probing is useful when it is read-only: use GET/query/list/search calls to inspect existing state, resolve real IDs, confirm response shapes, or verify a previous write. For create/update/delete calls, search docs, read docs, and inspect schemas first; call the mutation only with real resolved inputs, and avoid using placeholder IDs or speculative mutation calls just to discover validation behavior or response shape. If a mutation succeeds but you need more details, use the returned data or follow up with a read-only GET/query; do not repeat the mutation only to get a different response shape.
Use `wix.request({ method, url, body })` for API calls. Scope defaults to `"site"` when the ExecuteWixAPI `siteId` parameter is passed, otherwise `"account"`. Set `scope: "site"` explicitly for site-level APIs, which is the common case for business domains such as Stores, Bookings, CRM, Forms, CMS, Events, and Blog. Set `scope: "account"` explicitly for account-level APIs such as Sites, Site Folders, Domains, and User Management, or when the docs/schema indicate account-level auth.
A single `ExecuteWixAPI` invocation can target at most one site. For site-level API calls, pass the site ID in the tool-level `siteId` parameter, not inside `wix.request()`. Do not use `wix.request({ siteId: "..." })`; per-request site switching is not supported.
Error handling: `wix.request()` throws when the Wix API returns an error. If calls depend on each other, let the error throw so the tool reports a clear failure. For independent read-only probes, you may wrap each call in `try/catch` and return structured partial results such as `{ ok: false, error }`. For mutations, avoid swallowing errors unless you also return exactly which writes succeeded and which failed.
Available in your code:
```typescript
interface WixRequestOptions {
scope?: "site" | "account"; // Defaults to "site" with ExecuteWixAPI siteId, otherwise "account"
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
url: string; // Prefer method.publicUrl from SearchWixAPISpec, e.g. "https://www.wixapis.com/stores/v1/products/query"; paths like "/stores/v1/products/query" are resolved against https://www.wixapis.com
body?: unknown;
headers?: Record<string, string>; // Do NOT set Authorization, wix-site-id, or wix-account-id
}
interface WixResponse<T = unknown> {
status: number;
data: T;
json(): Promise<T>; // Fetch-compatible alias for data
}
declare const wix: {
request<T = unknown>(options: WixRequestOptions): Promise<WixResponse<T>>;
};
declare const siteId: string | undefined; // Tool-level siteId passed to ExecuteWixAPI, if any.
```
Your code MUST be an async function expression that returns the result:
```javascript
async () => {
const response = await wix.request({
method: "GET",
url: "https://www.wixapis.com/<account-level-endpoint>"
});
return response.data;
}
```
The response is available as `response.data`. For compatibility with fetch-style code, `await response.json()` returns the same data. Return compact, task-focused data instead of raw API responses. For list/query/search endpoints, especially "list all" tasks or APIs that may return many items, paginate in code and map each item to the fields needed for the task. Include IDs, metadata, nested fields, or raw response fragments when they are needed to complete the task, disambiguate entities, verify mutations, or answer the user. If the user asks for names and types, return only names and types. For hundreds of items, avoid verbose JSON objects because repeated keys waste tokens; return compact strings such as `"Name - TYPE"` joined with newlines, or small tuples such as `["Name", "TYPE"]`. If the user asks for a specific output value, include that value explicitly in the returned object so the final answer can report it. If you need to filter by a field, verify the endpoint supports that filter in the method docs/schema or related "Supported Filters and Sorting" docs; otherwise retrieve a bounded page and filter in JavaScript. When looking up an item by user-provided name, paginate/search until you find an exact name match; never update or delete the first result unless it exactly matches.
Example — site-level request with compact output:
```javascript
async function() {
const response = await wix.request({
method: "POST",
url: "https://www.wixapis.com/<site-level-endpoint>",
body: {
query: {
cursorPaging: { limit: 100 }
}
}
});
const items = response.data.items ?? response.data.results ?? [];
return {
count: items.length,
items: items.map(item => item.name + " - " + item.type).join("\
")
};
}
```
Example — account-level request:
```javascript
async function() {
const response = await wix.request({
scope: "account",
method: "POST",
url: "https://www.wixapis.com/<account-level-endpoint>",
body: {
query: {
cursorPaging: { limit: 50 }
}
}
});
return response.data;
}
```
Example — independent read-only probes with partial results:
```javascript
async function() {
const checks = {};
try {
const products = await wix.request({
scope: "site",
method: "POST",
url: "https://www.wixapis.com/<products-query-endpoint>",
body: { query: { cursorPaging: { limit: 10 } } }
});
checks.products = {
ok: true,
count: (products.data.items ?? products.data.products ?? []).length
};
} catch (error) {
checks.products = { ok: false, error: String(error) };
}
try {
const collections = await wix.request({
scope: "site",
method: "POST",
url: "https://www.wixapis.com/<collections-query-endpoint>",
body: { query: { cursorPaging: { limit: 10 } } }
});
checks.collections = {
ok: true,
count: (collections.data.items ?? collections.data.collections ?? []).length
};
} catch (error) {
checks.collections = { ok: false, error: String(error) };
}
return checks;
}
```
Example — chain related mutation calls and fail fast on API errors:
```javascript
async function() {
const list = await wix.request({
scope: "site",
method: "POST",
url: "https://www.wixapis.com/<query-endpoint>",
body: { query: { cursorPaging: { limit: 20 } } }
});
const items = list.data.items ?? [];
const match = items.find(item => item.name === "Target name");
if (!match) {
return { error: "NOT_FOUND", available: items.map(item => ({ id: item.id, name: item.name })) };
}
const updated = await wix.request({
scope: "site",
method: "PATCH",
url: `https://www.wixapis.com/<update-endpoint>/${match.id}`,
body: {
item: {
id: match.id,
revision: match.revision,
name: "Updated name"
}
}
});
return {
id: updated.data.item?.id,
name: updated.data.item?.name,
revision: updated.data.item?.revision
};
}
```